From: VMware, Inc <> Date: Wed, 18 Sep 2013 03:42:05 +0000 (-0700) Subject: Update AsyncSocketResolveAddr to allow AF_UNSPEC and AF_INET6 ai_family. X-Git-Tag: 2013.09.16-1328054~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c634402c98c2eb419d111797c39e4907aa35a8eb;p=thirdparty%2Fopen-vm-tools.git Update AsyncSocketResolveAddr to allow AF_UNSPEC and AF_INET6 ai_family. AsyncSocketResolveAddr currently only accepts searches for AF_INET. Update it to search for AF_INET6 or both with AF_UNSPEC. Since we no longer need to return sockaddr_in for AsyncSocket_SendTo, only populate sockaddr. Also add a convenient IP string generation after resolve so all callers do not need to do the same operation tp log the IP string with port number. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/asyncsocket/asyncSocketInt.h b/open-vm-tools/lib/asyncsocket/asyncSocketInt.h index 0b85010c6..bcca09172 100644 --- a/open-vm-tools/lib/asyncsocket/asyncSocketInt.h +++ b/open-vm-tools/lib/asyncsocket/asyncSocketInt.h @@ -294,8 +294,12 @@ Bool AsyncSocketBind(AsyncSocket *asock, struct sockaddr *addr, int *outError); Bool AsyncSocketListen(AsyncSocket *asock, AsyncSocketConnectFn connectFn, void *clientData, int *outError); -int AsyncSocketResolveAddr(const char *hostname, unsigned short port, - int type, struct sockaddr_in *addr); +int AsyncSocketResolveAddr(const char *hostname, + unsigned short port, + int family, + int type, + struct sockaddr *addr, + char **addrString); AsyncSocket *AsyncSocketConnectWithAsock(AsyncSocket *asock, struct sockaddr *addr, socklen_t addrLen, diff --git a/open-vm-tools/lib/asyncsocket/asyncsocket.c b/open-vm-tools/lib/asyncsocket/asyncsocket.c index dda81d742..d10b527ab 100644 --- a/open-vm-tools/lib/asyncsocket/asyncsocket.c +++ b/open-vm-tools/lib/asyncsocket/asyncsocket.c @@ -1075,10 +1075,11 @@ AsyncSocket_Connect(const char *hostname, AsyncSocketPollParams *pollParams, int *outError) { - struct sockaddr_in addr; + struct sockaddr addr; int getaddrinfoError; int error; AsyncSocket *asock; + char *ipString = NULL; if (!connectFn || !hostname) { error = ASOCKERR_INVAL; @@ -1090,8 +1091,8 @@ AsyncSocket_Connect(const char *hostname, * Resolve the hostname. Handles dotted decimal strings, too. */ - getaddrinfoError = AsyncSocketResolveAddr(hostname, port, - SOCK_STREAM, &addr); + getaddrinfoError = AsyncSocketResolveAddr(hostname, port, AF_INET, + SOCK_STREAM, &addr, &ipString); if (0 != getaddrinfoError) { Log(ASOCKPREFIX "Failed to resolve address '%s' and port %u\n", hostname, port); @@ -1099,20 +1100,13 @@ AsyncSocket_Connect(const char *hostname, goto error; } - /* Only IPv4 for now. Change this when IPv6 support is added. */ - ASSERT(addr.sin_family == AF_INET); + Log(ASOCKPREFIX "creating new socket, connecting to %s (%s)\n", ipString, + hostname); + free(ipString); - { - uint32 ip; - ip = ntohl(addr.sin_addr.s_addr); - Log(ASOCKPREFIX "creating new socket, connecting to %u.%u.%u.%u:%u (%s)\n", - (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF, - port, hostname); - } - - asock = AsyncSocketConnect((struct sockaddr *)&addr, sizeof addr, - connectFn, clientData, AsyncSocketConnectCallback, - flags, pollParams, &error); + asock = AsyncSocketConnect(&addr, sizeof addr, connectFn, clientData, + AsyncSocketConnectCallback, flags, pollParams, + &error); if (!asock) { Warning(ASOCKPREFIX "connection attempt failed\n"); error = ASOCKERR_CONNECT; @@ -2498,8 +2492,10 @@ outHaveLock: int AsyncSocketResolveAddr(const char *hostname, unsigned short port, + int family, int type, - struct sockaddr_in *addr) + struct sockaddr *addr, + char **addrString) { struct addrinfo hints; struct addrinfo *aiTop = NULL; @@ -2508,15 +2504,16 @@ AsyncSocketResolveAddr(const char *hostname, char portString[6]; /* strlen("65535\0") == 6 */ ASSERT(NULL != addr); + ASSERT(NULL != addrString); + Str_Sprintf(portString, sizeof(portString), "%d", port); memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; + hints.ai_family = family; hints.ai_socktype = type; /* - * We use getaddrinfo() since it is thread-safe and IPv6 ready. - * gethostbyname() is not thread-safe, and gethostbyname_r() is not - * defined on Windows. + * We use getaddrinfo() since it is thread-safe. gethostbyname() is not + * thread-safe, and gethostbyname_r() is not defined on Windows. */ getaddrinfoError = Posix_GetAddrInfo(hostname, portString, &hints, &aiTop); @@ -2527,11 +2524,45 @@ AsyncSocketResolveAddr(const char *hostname, } for (aiIterator = aiTop; NULL != aiIterator ; aiIterator = aiIterator->ai_next) { - if (aiIterator->ai_family != AF_INET) { - continue; + if (((family == AF_UNSPEC || family == AF_INET) && + aiIterator->ai_family == AF_INET) || + ((family == AF_UNSPEC || family == AF_INET6) && + aiIterator->ai_family == AF_INET6)) { + char tempAddrString[INET6_ADDRSTRLEN]; + static char unknownAddr[] = "(Unknown)"; +#if defined(_WIN32) + DWORD len = INET6_ADDRSTRLEN; + + if (WSAAddressToString(aiIterator->ai_addr, aiIterator->ai_addrlen, + NULL, tempAddrString, &len)) { + *addrString = Util_SafeStrdup(unknownAddr); + } else { + *addrString = Util_SafeStrdup(tempAddrString); + } +#else + + if (aiIterator->ai_family == AF_INET && + !inet_ntop(aiIterator->ai_family, + &(((struct sockaddr_in *)aiIterator->ai_addr)->sin_addr), + tempAddrString, INET6_ADDRSTRLEN)) { + *addrString = Util_SafeStrdup(unknownAddr); + } else if (aiIterator->ai_family == AF_INET6 && + !inet_ntop(aiIterator->ai_family, + &(((struct sockaddr_in6 *)aiIterator->ai_addr)->sin6_addr), + tempAddrString, INET6_ADDRSTRLEN)) { + *addrString = Util_SafeStrdup(unknownAddr); + } else { + Str_Sprintf(tempAddrString, sizeof tempAddrString, "%s:%u", + tempAddrString, port); + + *addrString = Util_SafeStrdup(tempAddrString); + } +#endif + + *addr = *(aiIterator->ai_addr); + + break; } - *addr = *((struct sockaddr_in *) (aiIterator->ai_addr)); - break; } bye: