mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
fix getinfo CURLINFO_LOCAL* for reused connections (take 2)
This commit is contained in:
parent
1b2b93e074
commit
11cddb68e0
@ -532,6 +532,16 @@ static CURLcode trynextip(struct connectdata *conn,
|
|||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copies connection info into the session handle to make it available
|
||||||
|
when the session handle is no longer associated with a connection. */
|
||||||
|
void Curl_persistconninfo(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
|
||||||
|
memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
|
||||||
|
conn->data->info.conn_primary_port = conn->primary_port;
|
||||||
|
conn->data->info.conn_local_port = conn->local_port;
|
||||||
|
}
|
||||||
|
|
||||||
/* retrieves ip address and port from a sockaddr structure */
|
/* retrieves ip address and port from a sockaddr structure */
|
||||||
static bool getaddressinfo(struct sockaddr* sa, char* addr,
|
static bool getaddressinfo(struct sockaddr* sa, char* addr,
|
||||||
long* port)
|
long* port)
|
||||||
@ -587,43 +597,45 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
|||||||
struct Curl_sockaddr_storage ssrem;
|
struct Curl_sockaddr_storage ssrem;
|
||||||
struct Curl_sockaddr_storage ssloc;
|
struct Curl_sockaddr_storage ssloc;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct PureInfo *info = &conn->data->info;
|
|
||||||
|
|
||||||
if(conn->bits.reuse)
|
if(!conn->bits.reuse) {
|
||||||
/* reusing same connection */
|
|
||||||
return;
|
len = sizeof(struct Curl_sockaddr_storage);
|
||||||
|
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
|
||||||
|
error = SOCKERRNO;
|
||||||
|
failf(data, "getpeername() failed with errno %d: %s",
|
||||||
|
error, Curl_strerror(conn, error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof(struct Curl_sockaddr_storage);
|
||||||
|
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
|
||||||
|
error = SOCKERRNO;
|
||||||
|
failf(data, "getsockname() failed with errno %d: %s",
|
||||||
|
error, Curl_strerror(conn, error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!getaddressinfo((struct sockaddr*)&ssrem,
|
||||||
|
conn->primary_ip, &conn->primary_port)) {
|
||||||
|
error = ERRNO;
|
||||||
|
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||||
|
error, Curl_strerror(conn, error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
||||||
|
conn->local_ip, &conn->local_port)) {
|
||||||
|
error = ERRNO;
|
||||||
|
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||||
|
error, Curl_strerror(conn, error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
len = sizeof(struct Curl_sockaddr_storage);
|
|
||||||
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
|
|
||||||
error = SOCKERRNO;
|
|
||||||
failf(data, "getpeername() failed with errno %d: %s",
|
|
||||||
error, Curl_strerror(conn, error));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = sizeof(struct Curl_sockaddr_storage);
|
/* persist connection info in session handle */
|
||||||
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
|
Curl_persistconninfo(conn);
|
||||||
error = SOCKERRNO;
|
|
||||||
failf(data, "getsockname() failed with errno %d: %s",
|
|
||||||
error, Curl_strerror(conn, error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!getaddressinfo((struct sockaddr*)&ssrem,
|
|
||||||
info->primary_ip, &info->primary_port)) {
|
|
||||||
error = ERRNO;
|
|
||||||
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
|
||||||
error, Curl_strerror(conn, error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
|
||||||
info->local_ip, &info->local_port)) {
|
|
||||||
error = ERRNO;
|
|
||||||
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
|
||||||
error, Curl_strerror(conn, error));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -865,14 +877,16 @@ singleipconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* store remote address and port used in this connection attempt */
|
/* store remote address and port used in this connection attempt */
|
||||||
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
||||||
data->info.primary_ip, &data->info.primary_port)) {
|
conn->primary_ip, &conn->primary_port)) {
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||||
error, Curl_strerror(conn, error));
|
error, Curl_strerror(conn, error));
|
||||||
}
|
}
|
||||||
strcpy(conn->ip_addr_str, data->info.primary_ip);
|
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||||
infof(data, " Trying %s... ", conn->ip_addr_str);
|
infof(data, " Trying %s... ", conn->ip_addr_str);
|
||||||
|
|
||||||
|
Curl_persistconninfo(conn);
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if(addr.family == AF_INET6)
|
if(addr.family == AF_INET6)
|
||||||
conn->bits.ipv6 = TRUE;
|
conn->bits.ipv6 = TRUE;
|
||||||
|
@ -69,4 +69,6 @@ void Curl_sndbufset(curl_socket_t sockfd);
|
|||||||
|
|
||||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||||
|
|
||||||
|
void Curl_persistconninfo(struct connectdata *conn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +67,11 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
|
|||||||
info->request_size = 0;
|
info->request_size = 0;
|
||||||
info->numconnects = 0;
|
info->numconnects = 0;
|
||||||
|
|
||||||
|
info->conn_primary_ip[0] = '\0';
|
||||||
|
info->conn_local_ip[0] = '\0';
|
||||||
|
info->conn_primary_port = 0;
|
||||||
|
info->conn_local_port = 0;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,20 +238,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.primary_ip;
|
*param_charp = data->info.conn_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.primary_port;
|
*param_longp = data->info.conn_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.local_ip;
|
*param_charp = data->info.conn_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.local_port;
|
*param_longp = data->info.conn_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
|
||||||
|
@ -4599,7 +4599,8 @@ static void reuse_conn(struct connectdata *old_conn,
|
|||||||
else
|
else
|
||||||
free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
|
free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
|
||||||
|
|
||||||
strcpy(conn->ip_addr_str, old_conn->ip_addr_str);
|
/* persist connection info in session handle */
|
||||||
|
Curl_persistconninfo(conn);
|
||||||
|
|
||||||
/* re-use init */
|
/* re-use init */
|
||||||
conn->bits.reuse = TRUE; /* yes, we're re-using here */
|
conn->bits.reuse = TRUE; /* yes, we're re-using here */
|
||||||
|
@ -757,6 +757,23 @@ struct connectdata {
|
|||||||
unsigned short remote_port; /* what remote port to connect to,
|
unsigned short remote_port; /* what remote port to connect to,
|
||||||
not the proxy port! */
|
not the proxy port! */
|
||||||
|
|
||||||
|
/* '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;
|
||||||
|
|
||||||
char *user; /* user name string, allocated */
|
char *user; /* user name string, allocated */
|
||||||
char *passwd; /* password string, allocated */
|
char *passwd; /* password string, allocated */
|
||||||
|
|
||||||
@ -915,22 +932,19 @@ struct PureInfo {
|
|||||||
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 */
|
||||||
|
|
||||||
/* 'primary_ip' and 'primary_port' get filled with peer's numerical
|
/* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
|
||||||
ip address and port number whenever an outgoing connection is
|
and, 'conn_local_port' are copied over from the connectdata struct in
|
||||||
*attemted* from the primary socket to a remote address. When more
|
order to allow curl_easy_getinfo() to return this information even when
|
||||||
than one address is tried for a connection these will hold data
|
the session handle is no longer associated with a connection, and also
|
||||||
for the last attempt. When the connection is actualy established
|
allow curl_easy_reset() to clear this information from the session handle
|
||||||
these are updated with data which comes directly from the socket. */
|
without disturbing information which is still alive, and that might be
|
||||||
|
reused, in the connection cache. */
|
||||||
|
|
||||||
char primary_ip[MAX_IPADR_LEN];
|
char conn_primary_ip[MAX_IPADR_LEN];
|
||||||
long primary_port;
|
long conn_primary_port;
|
||||||
|
|
||||||
/* 'local_ip' and 'local_port' get filled with local's numerical
|
char conn_local_ip[MAX_IPADR_LEN];
|
||||||
ip address and port number whenever an outgoing connection is
|
long conn_local_port;
|
||||||
**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
|
||||||
|
Loading…
Reference in New Issue
Block a user