Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve DNS server address error in win32 platform #176

Closed
qi7chen opened this issue Dec 8, 2014 · 5 comments
Closed

Retrieve DNS server address error in win32 platform #176

qi7chen opened this issue Dec 8, 2014 · 5 comments

Comments

@qi7chen
Copy link

qi7chen commented Dec 8, 2014

When testing example/http_client,
type command ./http_client http://www.microsoft.com/ got right response in Linux(Ubuntu 14.04) but nothing printed in Windows platform(Windows 7 x64).

With some efforts, I found function ns_get_ip_address_of_nameserver() try to retrieve item under registry HKLM\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces\, and copy first item's NameServer field as the address of DNS server.
But when got too many interface items(as I shown below) and the NameServer field is an empty string, or the NameServer string contains more than one IP address(seperated by comma token), we cannot retrieve the right DNS server address we want.

dns_server_name

@cpq
Copy link
Member

cpq commented Dec 10, 2014

Thanks.
As far as I understand, the fix would be to trim the IP on the first comma, is that correct?

@zapline
Copy link

zapline commented Dec 14, 2014

But the first ip is not necessarily the best nameserver, 蛋疼

@cpq
Copy link
Member

cpq commented Dec 14, 2014

Thanks.
If first IP might not be the best server, what would be the best algorithm to pick one?

@mkmik
Copy link
Collaborator

mkmik commented Dec 14, 2014

On linux the default behaviour is to to try the second (and the third, see MAXNS) name after attempts number of attempts (default 2), unless the rotate option is present in resolv.conf. On windows I guess there is a similar behaviour but I didn't check.

@qi7chen
Copy link
Author

qi7chen commented Dec 17, 2014

Sorry for my poor English.

Following is code of function ns_get_ip_address_of_nameserver() started at fossa.c line 4384.

static int ns_get_ip_address_of_nameserver(char *name, size_t name_len) {
  int  ret = 0;

#ifdef _WIN32
  int  i;
  LONG  err;
  HKEY  hKey, hSub;
  char  subkey[512], dhcpns[512], ns[512], value[128], *key =
  "SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces";

  if ((err = RegOpenKey(HKEY_LOCAL_MACHINE,
      key, &hKey)) != ERROR_SUCCESS) {
    fprintf(stderr, "cannot open reg key %s: %d\n", key, err);
    ret--;
  } else {
    for (ret--, i = 0; RegEnumKey(hKey, i, subkey,
        sizeof(subkey)) == ERROR_SUCCESS; i++) {
      DWORD type, len = sizeof(value);
      if (RegOpenKey(hKey, subkey, &hSub) == ERROR_SUCCESS &&
          (RegQueryValueEx(hSub, "NameServer", 0,
          &type, value, &len) == ERROR_SUCCESS ||
          RegQueryValueEx(hSub, "DhcpNameServer", 0,
          &type, value, &len) == ERROR_SUCCESS)) {
        strncpy(name, value, name_len);
        ret++;
        RegCloseKey(hSub);
        break;
      }
    }
    RegCloseKey(hKey);
  }
#else
  /* linux version */
#endif /* _WIN32 */

  return ret;
}

looking at line strncpy(name, value, name_len),
the value can be an empty string, or IP addresses seperated by comma (e.g 8.8.8.8, 8.8.8.4).

that's the point.

cpq added a commit that referenced this issue Dec 21, 2014
@cpq cpq closed this as completed in f804e4f Dec 21, 2014
mkmik pushed a commit that referenced this issue Dec 21, 2014
imax9000 added a commit that referenced this issue Apr 15, 2015
1) If the registry value is empty - check the next interface.
2) Return proper address from ns_get_ip_address_of_nameserver, not
just the IP (confusing naming is confusing).

While I'm here, remove ret--++ madness and make it obviously return
exactly what the documentation says.
cpq added a commit that referenced this issue Apr 16, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants