fix getinfo CURLINFO_LOCAL* for reused connections
authorYang Tse <yangsita@gmail.com>
Tue, 30 Nov 2010 05:20:54 +0000 (06:20 +0100)
committerYang Tse <yangsita@gmail.com>
Tue, 30 Nov 2010 05:20:54 +0000 (06:20 +0100)
lib/connect.c
lib/getinfo.c
lib/urldata.h

index 88fb7eb..95033fa 100644 (file)
@@ -541,6 +541,9 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
 #ifdef ENABLE_IPV6
   struct sockaddr_in6* si6 = NULL;
 #endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+  struct sockaddr_un* su = NULL;
+#endif
 
   switch (sa->sa_family) {
     case AF_INET:
@@ -561,6 +564,13 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
       *port = us_port;
       break;
 #endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+    case AF_UNIX:
+      su = (struct sockaddr_un*)sa;
+      snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      *port = 0;
+      break;
+#endif
     default:
       addr[0] = '\0';
       *port = 0;
@@ -600,7 +610,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
   }
 
   if(!getaddressinfo((struct sockaddr*)&ssrem,
-                      info->ip, &info->port)) {
+                      info->primary_ip, &info->primary_port)) {
     error = ERRNO;
     failf(data, "ssrem inet_ntop() failed with errno %d: %s",
           error, Curl_strerror(conn, error));
@@ -608,7 +618,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
   }
 
   if(!getaddressinfo((struct sockaddr*)&ssloc,
-                     info->localip, &info->localport)) {
+                     info->local_ip, &info->local_port)) {
     error = ERRNO;
     failf(data, "ssloc inet_ntop() failed with errno %d: %s",
           error, Curl_strerror(conn, error));
@@ -802,11 +812,6 @@ singleipconnect(struct connectdata *conn,
   struct SessionHandle *data = conn->data;
   curl_socket_t sockfd;
   CURLcode res = CURLE_OK;
-  const void *iptoprint;
-  struct sockaddr_in * const sa4 = (void *)&addr.sa_addr;
-#ifdef ENABLE_IPV6
-  struct sockaddr_in6 * const sa6 = (void *)&addr.sa_addr;
-#endif
 
   *sockp = CURL_SOCKET_BAD;
 
@@ -855,37 +860,20 @@ singleipconnect(struct connectdata *conn,
     sa6->sin6_scope_id = conn->scope;
 #endif
 
-  /* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
-     argument? */
-#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
-  if(addr.family == AF_UNIX) {
-    infof(data, "  Trying %s... ",
-          ((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
-    snprintf(data->info.ip, MAX_IPADR_LEN, "%s",
-             ((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
-    strcpy(conn->ip_addr_str, data->info.ip);
+  /* store remote address and port used in this connection attempt */
+  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
+                     data->info.primary_ip, &data->info.primary_port)) {
+    error = ERRNO;
+    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+          error, Curl_strerror(conn, error));
   }
-  else
-#endif
-  {
+  strcpy(conn->ip_addr_str, data->info.primary_ip);
+  infof(data, "  Trying %s... ", conn->ip_addr_str);
+
 #ifdef ENABLE_IPV6
-    if(addr.family == AF_INET6) {
-      iptoprint = &sa6->sin6_addr;
-      conn->bits.ipv6 = TRUE;
-    }
-    else
+  if(addr.family == AF_INET6)
+    conn->bits.ipv6 = TRUE;
 #endif
-    {
-      iptoprint = &sa4->sin_addr;
-    }
-
-    if(Curl_inet_ntop(addr.family, iptoprint, addr_buf,
-                      sizeof(addr_buf)) != NULL) {
-      infof(data, "  Trying %s... ", addr_buf);
-      snprintf(data->info.ip, MAX_IPADR_LEN, "%s", addr_buf);
-      strcpy(conn->ip_addr_str, data->info.ip);
-    }
-  }
 
   if(data->set.tcp_nodelay)
     tcpnodelay(conn, sockfd);
index c00e675..5412c0f 100644 (file)
@@ -67,11 +67,6 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
   info->request_size = 0;
   info->numconnects = 0;
 
-  info->ip[0] = 0;
-  info->port = 0;
-  info->localip[0] = 0;
-  info->localport = 0;
-
   return CURLE_OK;
 }
 
@@ -238,20 +233,20 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
     break;
   case CURLINFO_PRIMARY_IP:
     /* Return the ip address of the most recent (primary) connection */
-    *param_charp = data->info.ip;
+    *param_charp = data->info.primary_ip;
     break;
   case CURLINFO_PRIMARY_PORT:
     /* Return the (remote) port of the most recent (primary) connection */
-    *param_longp = data->info.port;
+    *param_longp = data->info.primary_port;
     break;
   case CURLINFO_LOCAL_IP:
     /* Return the source/local ip address of the most recent (primary)
        connection */
-    *param_charp = data->info.localip;
+    *param_charp = data->info.local_ip;
     break;
   case CURLINFO_LOCAL_PORT:
     /* Return the local port of the most recent (primary) connection */
-    *param_longp = data->info.localport;
+    *param_longp = data->info.local_port;
     break;
   case CURLINFO_CERTINFO:
     /* Return the a pointer to the certinfo struct. Not really an slist
index 93c2d40..19ed4be 100644 (file)
@@ -914,15 +914,24 @@ struct PureInfo {
   long numconnects; /* how many new connection did libcurl created */
   char *contenttype; /* the content type of the object */
   char *wouldredirect; /* URL this would've been redirected to if asked to */
-  char ip[MAX_IPADR_LEN]; /* this buffer gets the numerical ip version stored
-                             at the connect *attempt* so it will get the last
-                             tried connect IP even on failures */
-  long port; /* the remote port the last connection was established to */
-  char localip[MAX_IPADR_LEN]; /* this buffer gets the numerical (local) ip
-                                  stored from where the last connection was
-                                  established */
-  long localport; /* the local (src) port the last connection
-                     originated from */
+
+  /* 'primary_ip' and 'primary_port' get filled with peer's numerical
+     ip address and port number whenever an outgoing connection is
+     *attemted* from the primary socket to a remote address. When more
+     than one address is tried for a connection these will hold data
+     for the last attempt. When the connection is actualy established
+     these are updated with data which comes directly from the socket. */
+
+  char primary_ip[MAX_IPADR_LEN];
+  long primary_port;
+
+  /* 'local_ip' and 'local_port' get filled with local's numerical
+     ip address and port number whenever an outgoing connection is
+     **established** from the primary socket to a remote address. */
+
+  char local_ip[MAX_IPADR_LEN];
+  long local_port;
+
   struct curl_certinfo certs; /* info about the certs, only populated in
                                  OpenSSL builds. Asked for with
                                  CURLOPT_CERTINFO / CURLINFO_CERTINFO */