diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2007-06-01 12:16:21 +0000 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2007-06-01 12:16:21 +0000 |
commit | ae7e1fde6e0e6db23e809a4a1470ae0f2fb4417c (patch) | |
tree | 8f5492d84ffa508cbda0919198587c5ad96fe8a6 /cpp | |
parent | http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=2229 (diff) | |
download | ice-ae7e1fde6e0e6db23e809a4a1470ae0f2fb4417c.tar.bz2 ice-ae7e1fde6e0e6db23e809a4a1470ae0f2fb4417c.tar.xz ice-ae7e1fde6e0e6db23e809a4a1470ae0f2fb4417c.zip |
Use getaddrinfo instead of gethostbyname on Unix
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/Ice/Network.cpp | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 0bc6ff1f114..5b515112c8e 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -1327,16 +1327,26 @@ vector<string> IceInternal::getHosts(const string& host) { vector<string> result; - struct hostent* he = 0; + +#ifdef _WIN32 + + // + // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. + // + + // + // gethostbyname() is thread safe on Windows, with a separate hostent per thread + // + struct hostent* entry = 0; int retry = 5; do { - he = gethostbyname(host.c_str()); + entry = gethostbyname(host.c_str()); } - while(he == 0 && h_errno == TRY_AGAIN && --retry >= 0); + while(entry == 0 && h_errno == TRY_AGAIN && --retry >= 0); - if(he == 0) + if(entry == 0) { DNSException ex(__FILE__, __LINE__); ex.error = h_errno; @@ -1344,14 +1354,65 @@ IceInternal::getHosts(const string& host) throw ex; } - char** ptr = he->h_addr_list; - while(*ptr) + char** p = entry->h_addr_list; + while(*p) { - struct in_addr* addr = reinterpret_cast<in_addr*>(*ptr); - result.push_back(inet_ntoa(*addr)); - ptr++; + struct in_addr* addr = reinterpret_cast<in_addr*>(*p); + result.push_back(inetAddrToString(*addr)); + p++; } +#else + + struct addrinfo* info = 0; + int retry = 5; + + struct addrinfo hints = { 0 }; + hints.ai_family = PF_INET; + + int rs = 0; + do + { + rs = getaddrinfo(host.c_str(), 0, &hints, &info); + } + while(info == 0 && rs == EAI_AGAIN && --retry >= 0); + + if(rs != 0) + { + DNSException ex(__FILE__, __LINE__); + ex.error = rs; + ex.host = host; + throw ex; + } + + struct addrinfo* p; + for(p = info; p != NULL; p = p->ai_next) + { + assert(p->ai_family == PF_INET); + struct sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(p->ai_addr); + if(sin->sin_addr.s_addr != 0) + { + string host = inetAddrToString((*sin).sin_addr); + bool found = false; + for(unsigned int i = 0; i < result.size(); ++i) + { + if(result[i] == host) + { + found = true; + break; + } + } + if(!found) + { + result.push_back(inetAddrToString((*sin).sin_addr)); + } + } + } + + freeaddrinfo(info); + +#endif + return result; } |