08a7e8645b4a87d94e922f0d873d733e01590b11 galt Fri Jul 29 09:07:15 2011 -0700 use thread-safe getaddrinfo() instead of gethostbyname() which was getting the dns-looked-up remote host IP clobbered on hgw0 diff --git src/lib/internet.c src/lib/internet.c index 347154f..7366c5c 100644 --- src/lib/internet.c +++ src/lib/internet.c @@ -15,46 +15,57 @@ { s = strchr(s, '.'); if (s == NULL) return FALSE; s += 1; if (!isdigit(s[0])) return FALSE; } return TRUE; } bits32 internetHostIp(char *hostName) /* Get IP v4 address (in host byte order) for hostName. * Warn and return 0 if there's a problem. */ { -struct hostent *hostent; bits32 ret; if (internetIsDottedQuad(hostName)) { internetDottedQuadToIp(hostName, &ret); } else { - hostent = gethostbyname(hostName); - if (hostent == NULL) + /* getaddrinfo is thread-safe and widely supported */ + struct addrinfo hints, *res; + struct in_addr addr; + int err; + + zeroBytes(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + + if ((err = getaddrinfo(hostName, NULL, &hints, &res)) != 0) { - warn("Couldn't find host %s.", hostName); + warn("getaddrinfo() error on hostName=%s: %s\n", hostName, gai_strerror(err)); return 0; } - memcpy(&ret, hostent->h_addr_list[0], sizeof(ret)); - ret = ntohl(ret); + + addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr; + + ret = ntohl((uint32_t)addr.s_addr); + + freeaddrinfo(res); + } return ret; } boolean internetFillInAddress(char *hostName, int port, struct sockaddr_in *address) /* Fill in address. Return FALSE if can't. */ { ZeroVar(address); address->sin_family = AF_INET; address->sin_port = htons(port); if (hostName == NULL) address->sin_addr.s_addr = INADDR_ANY; else { if ((address->sin_addr.s_addr = htonl(internetHostIp(hostName))) == 0)