Commit f6f5d787 authored by Yang Tse's avatar Yang Tse
Browse files

fix getinfo CURLINFO_LOCAL* for reused connections

parent 5db0a412
Loading
Loading
Loading
Loading
+23 −35
Original line number Original line Diff line number Diff line
@@ -541,6 +541,9 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
#ifdef ENABLE_IPV6
#ifdef ENABLE_IPV6
  struct sockaddr_in6* si6 = NULL;
  struct sockaddr_in6* si6 = NULL;
#endif
#endif
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
  struct sockaddr_un* su = NULL;
#endif


  switch (sa->sa_family) {
  switch (sa->sa_family) {
    case AF_INET:
    case AF_INET:
@@ -560,6 +563,13 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
      us_port = ntohs(si6->sin6_port);
      us_port = ntohs(si6->sin6_port);
      *port = us_port;
      *port = us_port;
      break;
      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
#endif
    default:
    default:
      addr[0] = '\0';
      addr[0] = '\0';
@@ -600,7 +610,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
  }
  }


  if(!getaddressinfo((struct sockaddr*)&ssrem,
  if(!getaddressinfo((struct sockaddr*)&ssrem,
                      info->ip, &info->port)) {
                      info->primary_ip, &info->primary_port)) {
    error = ERRNO;
    error = ERRNO;
    failf(data, "ssrem inet_ntop() failed with errno %d: %s",
    failf(data, "ssrem inet_ntop() failed with errno %d: %s",
          error, Curl_strerror(conn, error));
          error, Curl_strerror(conn, error));
@@ -608,7 +618,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
  }
  }


  if(!getaddressinfo((struct sockaddr*)&ssloc,
  if(!getaddressinfo((struct sockaddr*)&ssloc,
                     info->localip, &info->localport)) {
                     info->local_ip, &info->local_port)) {
    error = ERRNO;
    error = ERRNO;
    failf(data, "ssloc inet_ntop() failed with errno %d: %s",
    failf(data, "ssloc inet_ntop() failed with errno %d: %s",
          error, Curl_strerror(conn, error));
          error, Curl_strerror(conn, error));
@@ -802,11 +812,6 @@ singleipconnect(struct connectdata *conn,
  struct SessionHandle *data = conn->data;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd;
  curl_socket_t sockfd;
  CURLcode res = CURLE_OK;
  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;
  *sockp = CURL_SOCKET_BAD;


@@ -855,37 +860,20 @@ singleipconnect(struct connectdata *conn,
    sa6->sin6_scope_id = conn->scope;
    sa6->sin6_scope_id = conn->scope;
#endif
#endif


  /* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
  /* store remote address and port used in this connection attempt */
     argument? */
  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
                     data->info.primary_ip, &data->info.primary_port)) {
  if(addr.family == AF_UNIX) {
    error = ERRNO;
    infof(data, "  Trying %s... ",
    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
          ((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
          error, Curl_strerror(conn, error));
    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);
  }
  }
  else
  strcpy(conn->ip_addr_str, data->info.primary_ip);
#endif
  infof(data, "  Trying %s... ", conn->ip_addr_str);
  {

#ifdef ENABLE_IPV6
#ifdef ENABLE_IPV6
    if(addr.family == AF_INET6) {
  if(addr.family == AF_INET6)
      iptoprint = &sa6->sin6_addr;
    conn->bits.ipv6 = TRUE;
    conn->bits.ipv6 = TRUE;
    }
    else
#endif
#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)
  if(data->set.tcp_nodelay)
    tcpnodelay(conn, sockfd);
    tcpnodelay(conn, sockfd);
+4 −9
Original line number Original line Diff line number Diff line
@@ -67,11 +67,6 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
  info->request_size = 0;
  info->request_size = 0;
  info->numconnects = 0;
  info->numconnects = 0;


  info->ip[0] = 0;
  info->port = 0;
  info->localip[0] = 0;
  info->localport = 0;

  return CURLE_OK;
  return CURLE_OK;
}
}


@@ -238,20 +233,20 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
    break;
    break;
  case CURLINFO_PRIMARY_IP:
  case CURLINFO_PRIMARY_IP:
    /* Return the ip address of the most recent (primary) connection */
    /* Return the ip address of the most recent (primary) connection */
    *param_charp = data->info.ip;
    *param_charp = data->info.primary_ip;
    break;
    break;
  case CURLINFO_PRIMARY_PORT:
  case CURLINFO_PRIMARY_PORT:
    /* Return the (remote) port of the most recent (primary) connection */
    /* Return the (remote) port of the most recent (primary) connection */
    *param_longp = data->info.port;
    *param_longp = data->info.primary_port;
    break;
    break;
  case CURLINFO_LOCAL_IP:
  case CURLINFO_LOCAL_IP:
    /* Return the source/local ip address of the most recent (primary)
    /* Return the source/local ip address of the most recent (primary)
       connection */
       connection */
    *param_charp = data->info.localip;
    *param_charp = data->info.local_ip;
    break;
    break;
  case CURLINFO_LOCAL_PORT:
  case CURLINFO_LOCAL_PORT:
    /* Return the local port of the most recent (primary) connection */
    /* Return the local port of the most recent (primary) connection */
    *param_longp = data->info.localport;
    *param_longp = data->info.local_port;
    break;
    break;
  case CURLINFO_CERTINFO:
  case CURLINFO_CERTINFO:
    /* Return the a pointer to the certinfo struct. Not really an slist
    /* Return the a pointer to the certinfo struct. Not really an slist
+18 −9
Original line number Original line Diff line number Diff line
@@ -914,15 +914,24 @@ struct PureInfo {
  long numconnects; /* how many new connection did libcurl created */
  long numconnects; /* how many new connection did libcurl created */
  char *contenttype; /* the content type of the object */
  char *contenttype; /* the content type of the object */
  char *wouldredirect; /* URL this would've been redirected to if asked to */
  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
  /* 'primary_ip' and 'primary_port' get filled with peer's numerical
                             tried connect IP even on failures */
     ip address and port number whenever an outgoing connection is
  long port; /* the remote port the last connection was established to */
     *attemted* from the primary socket to a remote address. When more
  char localip[MAX_IPADR_LEN]; /* this buffer gets the numerical (local) ip
     than one address is tried for a connection these will hold data
                                  stored from where the last connection was
     for the last attempt. When the connection is actualy established
                                  established */
     these are updated with data which comes directly from the socket. */
  long localport; /* the local (src) port the last connection

                     originated from */
  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
  struct curl_certinfo certs; /* info about the certs, only populated in
                                 OpenSSL builds. Asked for with
                                 OpenSSL builds. Asked for with
                                 CURLOPT_CERTINFO / CURLINFO_CERTINFO */
                                 CURLOPT_CERTINFO / CURLINFO_CERTINFO */