diff options
author | VMware, Inc <> | 2013-09-17 20:42:05 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-09-22 22:30:00 -0700 |
commit | c634402c98c2eb419d111797c39e4907aa35a8eb (patch) | |
tree | f73a41933bf904368b4e05137b82c3f1161a70cc | |
parent | 9644250ed9110aa38d5a8f467499b3d9678f7a05 (diff) |
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 <dtor@vmware.com>
-rw-r--r-- | open-vm-tools/lib/asyncsocket/asyncSocketInt.h | 8 | ||||
-rw-r--r-- | open-vm-tools/lib/asyncsocket/asyncsocket.c | 81 |
2 files changed, 62 insertions, 27 deletions
diff --git a/open-vm-tools/lib/asyncsocket/asyncSocketInt.h b/open-vm-tools/lib/asyncsocket/asyncSocketInt.h index 0b85010c..bcca0917 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 dda81d74..d10b527a 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: |