fix getinfo CURLINFO_LOCAL* for reused connections

This commit is contained in:
Yang Tse 2010-11-30 06:20:54 +01:00
parent 5db0a412ff
commit f6f5d7874f
3 changed files with 46 additions and 54 deletions

View File

@ -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
if(addr.family == AF_INET6) {
iptoprint = &sa6->sin6_addr;
conn->bits.ipv6 = TRUE;
}
else
#endif
{
iptoprint = &sa4->sin_addr;
}
if(Curl_inet_ntop(addr.family, iptoprint, addr_buf, #ifdef ENABLE_IPV6
sizeof(addr_buf)) != NULL) { if(addr.family == AF_INET6)
infof(data, " Trying %s... ", addr_buf); conn->bits.ipv6 = TRUE;
snprintf(data->info.ip, MAX_IPADR_LEN, "%s", addr_buf); #endif
strcpy(conn->ip_addr_str, data->info.ip);
}
}
if(data->set.tcp_nodelay) if(data->set.tcp_nodelay)
tcpnodelay(conn, sockfd); tcpnodelay(conn, sockfd);

View File

@ -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

View File

@ -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 */