diff --git a/CHANGELOG b/CHANGELOG index 4c3ab30..404774f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -28,7 +28,7 @@ CHANGES: - Added support for CNAME/TXT/A/MX query types, fixes #75. Patch by Anne Bezemer, merge help by logix. - Merged low-latency patch from Anne Bezemer, fixes #76. - - Resolve client nameserver argument (except on win32), #82. + - Resolve client nameserver argument if given as hostname, fixes #82. 2009-06-01: 0.5.2 "WifiFree" - Fixed client segfault on OS X, #57 diff --git a/man/iodine.8 b/man/iodine.8 index 246d626..fd72067 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -221,9 +221,8 @@ in production environments. .B nameserver The nameserver to use to relay the dns traffic. This can be any relaying nameserver or the server running iodined if reachable. This field can be -given as an IP address, or as a hostname (except on Win32 currently). -This argument is optional, and if not specified a nameserver will be read -from the +given as an IP address, or as a hostname. This argument is optional, and +if not specified a nameserver will be read from the .I /etc/resolv.conf file. .TP diff --git a/src/client.c b/src/client.c index 09a81d9..98978d6 100644 --- a/src/client.c +++ b/src/client.c @@ -145,26 +145,40 @@ client_set_nameserver(const char *cp, int port) struct in_addr addr; if (inet_aton(cp, &addr) != 1) { + /* try resolving if a domain is given */ + struct hostent *host; + const char *err; + host = gethostbyname(cp); + if (host != NULL && h_errno > 0) { + int i = 0; + while (host->h_addr_list[i] != 0) { + addr = *(struct in_addr *) host->h_addr_list[i++]; + fprintf(stderr, "Resolved %s to %s\n", cp, inet_ntoa(addr)); + goto setaddr; + } + } #ifndef WINDOWS32 - /* MinGW only supports getaddrinfo on WinXP and higher.. - * so turn it off in windows for now - * - * try resolving if a domain is given */ - struct addrinfo *addrinfo; - struct addrinfo *res; - if (getaddrinfo(cp, NULL, NULL, &addrinfo) == 0) { - struct sockaddr_in *inaddr; - for (res = addrinfo; res != NULL; res = res->ai_next) { - inaddr = (struct sockaddr_in *) res->ai_addr; - addr = inaddr->sin_addr; + err = hstrerror(h_errno); +#else + { + DWORD wserr = WSAGetLastError(); + switch (wserr) { + case WSAHOST_NOT_FOUND: + err = "Host not found"; + break; + case WSANO_DATA: + err = "No data record found"; + break; + default: + err = "Unknown error"; break; } - freeaddrinfo(addrinfo); - } else -#endif - errx(1, "error parsing nameserver address: '%s'", cp); + } +#endif /* !WINDOWS32 */ + errx(1, "error resolving nameserver '%s': %s", cp, err); } +setaddr: memset(&nameserv, 0, sizeof(nameserv)); nameserv.sin_family = AF_INET; nameserv.sin_port = htons(port); diff --git a/src/iodine.c b/src/iodine.c index 14992cc..af3b9dc 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -89,8 +89,7 @@ help() { fprintf(stderr, " -I max interval between requests (default 4 sec) to prevent server timeouts\n"); fprintf(stderr, " -z context, to apply specified SELinux context after initialization\n"); fprintf(stderr, " -F pidfile to write pid to a file\n"); - fprintf(stderr, "nameserver is the IP number/hostname of the relaying nameserver\n " - "(hostname not supported on win32). if absent, /etc/resolv.conf is used\n"); + fprintf(stderr, "nameserver is the IP number/hostname of the relaying nameserver. if absent, /etc/resolv.conf is used\n"); fprintf(stderr, "topdomain is the FQDN that is delegated to the tunnel endpoint.\n"); exit(0);