summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVMware, Inc <>2013-09-17 20:42:05 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-09-22 22:30:00 -0700
commitc634402c98c2eb419d111797c39e4907aa35a8eb (patch)
treef73a41933bf904368b4e05137b82c3f1161a70cc
parent9644250ed9110aa38d5a8f467499b3d9678f7a05 (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.h8
-rw-r--r--open-vm-tools/lib/asyncsocket/asyncsocket.c81
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: