From 8098d9417c649272b9d6d2ad76abbde7dfbfcad1 Mon Sep 17 00:00:00 2001 From: Frank Meier Date: Sat, 5 Jun 2010 00:29:09 +0200 Subject: [PATCH] getinfo: added *_PRIMARY_PORT, *_LOCAL_IP and *_LOCAL_PORT --- CHANGES | 4 +++ RELEASE-NOTES | 4 ++- docs/libcurl/curl_easy_getinfo.3 | 11 ++++++++ docs/libcurl/symbols-in-versions | 15 ++++++---- include/curl/curl.h | 5 +++- lib/connect.c | 47 ++++++++++++++++++++++++++++++++ lib/connect.h | 4 ++- lib/getinfo.c | 19 +++++++++++++ lib/url.c | 1 + lib/urldata.h | 6 ++++ 10 files changed, 107 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 4b99f099c..4379303ad 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ Changelog +Daniel Stenberg (5 June 2010) +- Frank Meier added CURLINFO_PRIMARY_PORT, CURLINFO_LOCAL_IP and + CURLINFO_LOCAL_PORT to curl_easy_getinfo(). + Yang Tse (4 June 2010) - Enabled OpenLDAP support for cygwin builds. This support was disabled back in 2008 due to incompatibilities between OpenSSL and OpenLDAP headers. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index da17698ed..63860cd19 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -17,6 +17,7 @@ This release includes the following changes: o added support for RTMP o introducing new LDAP code for new enough OpenLDAP o OpenLDAP support enabled for cygwin builds + o added CURLINFO_PRIMARY_PORT, CURLINFO_LOCAL_IP and CURLINFO_LOCAL_PORT This release includes the following bugfixes: @@ -48,6 +49,7 @@ advice from friends like these: Kamil Dudka, Alex Bligh, Ben Greear, Hoi-Ho Chan, Howard Chu, Dirk Manske, Pavel Raiskup, John-Mark Bell, Eric Mertens, Tor Arntsen, Douglas Kilpatrick, Igor Novoseltsev, Jason McDonald, Dan Fandrich, Tanguy Fautre, Guenter Knauf, - Julien Chaffraix, Kalle Vahlman + Julien Chaffraix, Kalle Vahlman, Frank Meier + Thanks! (and sorry if I forgot to mention someone) diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3 index 32f0ae996..b80eacf7d 100644 --- a/docs/libcurl/curl_easy_getinfo.3 +++ b/docs/libcurl/curl_easy_getinfo.3 @@ -173,6 +173,17 @@ string holding the IP address of the most recent connection done with this \fBcurl\fP handle. This string may be IPv6 if that's enabled. Note that you get a pointer to a memory area that will be re-used at next request so you need to copy the string if you want to keep the information. (Added in 7.19.0) +.IP CURLINFO_PRIMARY_PORT +Pass a pointer to a long to receive the destination port of the most recent +connection done with this \fBcurl\fP handle. (Added in 7.21.0) +.IP CURLINFO_LOCAL_IP +Pass a pointer to a char pointer to receive the pointer to a zero-terminated +string holding the local (source) IP address of the most recent connection done +with this \fBcurl\fP handle. This string may be IPv6 if that's enabled. The +same restrictions apply as to \fICURLINFO_PRIMARY_IP\fP. (Added in 7.21.0) +.IP CURLINFO_LOCAL_PORT +Pass a pointer to a long to receive the local (source) port of the most recent +connection done with this \fBcurl\fP handle. (Added in 7.21.0) .IP CURLINFO_COOKIELIST Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all cookies cURL knows (expired ones, too). Don't forget to diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index b33619ee0..a02ead453 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -151,11 +151,14 @@ CURLINFO_HTTPAUTH_AVAIL 7.10.8 CURLINFO_HTTP_CODE 7.4.1 7.10.8 CURLINFO_HTTP_CONNECTCODE 7.10.7 CURLINFO_LASTSOCKET 7.15.2 +CURLINFO_LOCAL_IP 7.21.0 +CURLINFO_LOCAL_PORT 7.21.0 CURLINFO_NAMELOOKUP_TIME 7.4.1 CURLINFO_NUM_CONNECTS 7.12.3 CURLINFO_OS_ERRNO 7.12.2 CURLINFO_PRETRANSFER_TIME 7.4.1 CURLINFO_PRIMARY_IP 7.19.0 +CURLINFO_PRIMARY_PORT 7.21.0 CURLINFO_PRIVATE 7.10.3 CURLINFO_PRIVATE 7.10.3 CURLINFO_PROXYAUTH_AVAIL 7.10.8 @@ -402,6 +405,12 @@ CURLPROTO_LDAP 7.19.4 CURLPROTO_LDAPS 7.19.4 CURLPROTO_POP3 7.20.0 CURLPROTO_POP3S 7.20.0 +CURLPROTO_RTMP 7.21.0 +CURLPROTO_RTMPE 7.21.0 +CURLPROTO_RTMPS 7.21.0 +CURLPROTO_RTMPT 7.21.0 +CURLPROTO_RTMPTE 7.21.0 +CURLPROTO_RTMPTS 7.21.0 CURLPROTO_RTSP 7.20.0 CURLPROTO_SCP 7.19.4 CURLPROTO_SFTP 7.19.4 @@ -415,12 +424,6 @@ CURLPROXY_SOCKS4 7.10 CURLPROXY_SOCKS4A 7.18.0 CURLPROXY_SOCKS5 7.10 CURLPROXY_SOCKS5_HOSTNAME 7.18.0 -CURLPROTO_RTMP 7.21.0 -CURLPROTO_RTMPT 7.21.0 -CURLPROTO_RTMPE 7.21.0 -CURLPROTO_RTMPTE 7.21.0 -CURLPROTO_RTMPS 7.21.0 -CURLPROTO_RTMPTS 7.21.0 CURLSSH_AUTH_DEFAULT 7.16.1 CURLSSH_AUTH_HOST 7.16.1 CURLSSH_AUTH_KEYBOARD 7.16.1 diff --git a/include/curl/curl.h b/include/curl/curl.h index 83ba078cb..b19828f58 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -1883,9 +1883,12 @@ typedef enum { CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, /* Fill in new entries below here! */ - CURLINFO_LASTONE = 39 + CURLINFO_LASTONE = 42 } CURLINFO; /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as diff --git a/lib/connect.c b/lib/connect.c index 4adc7f35a..43e17aa63 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -523,6 +523,50 @@ static bool trynextip(struct connectdata *conn, return TRUE; } +/* retrieves ip address and port from a sockaddr structure */ +static void getaddressinfo(struct sockaddr* sa, char* addr, + long* port) +{ + struct sockaddr_in* si = NULL; +#ifdef ENABLE_IPV6 + struct sockaddr_in6* si6 = NULL; +#endif + + switch (sa->sa_family) { + case AF_INET: + si = (struct sockaddr_in*) sa; + Curl_inet_ntop(sa->sa_family, &(si->sin_addr), addr, MAX_IPADR_LEN); + *port = ntohs(si->sin_port); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + si6 = (struct sockaddr_in6*)sa; + Curl_inet_ntop(sa->sa_family, &(si6->sin6_addr), addr, MAX_IPADR_LEN); + *port = ntohs(si6->sin6_port); + break; +#endif + default: + addr[0] = '\0'; + *port = 0; + } +} + +/* retrieves the start/end point information of a socket of an established + connection */ +void Curl_updateconninfo(curl_socket_t sockfd, struct PureInfo* info) +{ + struct Curl_sockaddr_storage ssrem; + struct Curl_sockaddr_storage ssloc; + + socklen_t len = sizeof(struct Curl_sockaddr_storage); + + getpeername(sockfd, (struct sockaddr*) &ssrem, &len); + getsockname(sockfd, (struct sockaddr*) &ssloc, &len); + + getaddressinfo((struct sockaddr*)&ssrem, info->ip, &info->port); + getaddressinfo((struct sockaddr*)&ssloc, info->localip, &info->localport); +} + /* * Curl_is_connected() is used from the multi interface to check if the * firstsocket has connected. @@ -577,6 +621,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, *connected = TRUE; Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ Curl_verboseconnect(conn); + Curl_updateconninfo(sockfd, &(data->info)); + return CURLE_OK; } /* nope, not connected for real */ @@ -866,6 +912,7 @@ singleipconnect(struct connectdata *conn, /* we are connected, awesome! */ *connected = TRUE; /* this is a true connect */ infof(data, "connected\n"); + Curl_updateconninfo(sockfd, &(data->info)); return sockfd; } else if(WAITCONN_TIMEOUT == rc) diff --git a/lib/connect.h b/lib/connect.h index 36ea4f639..b365f7d0c 100644 --- a/lib/connect.h +++ b/lib/connect.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -68,4 +68,6 @@ void Curl_sndbufset(curl_socket_t sockfd); #define Curl_sndbufset(y) #endif +void Curl_updateconninfo(curl_socket_t sockfd, struct PureInfo* info); + #endif diff --git a/lib/getinfo.c b/lib/getinfo.c index 7a0ed71ac..d5517e489 100644 --- a/lib/getinfo.c +++ b/lib/getinfo.c @@ -66,6 +66,12 @@ CURLcode Curl_initinfo(struct SessionHandle *data) info->header_size = 0; info->request_size = 0; info->numconnects = 0; + + info->ip[0] = 0; + info->port = 0; + info->localip[0] = 0; + info->localport = 0; + return CURLE_OK; } @@ -224,6 +230,19 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) /* Return the ip address of the most recent (primary) connection */ *param_charp = data->info.ip; break; + case CURLINFO_PRIMARY_PORT: + /* Return the (remote) port of the most recent (primary) connection */ + *param_longp = data->info.port; + break; + case CURLINFO_LOCAL_IP: + /* Return the source/local ip address of the most recent (primary) + connection */ + *param_charp = data->info.localip; + break; + case CURLINFO_LOCAL_PORT: + /* Return the local port of the most recent (primary) connection */ + *param_longp = data->info.localport; + break; case CURLINFO_CERTINFO: /* Return the a pointer to the certinfo struct. Not really an slist pointer but we can pretend it is here */ diff --git a/lib/url.c b/lib/url.c index 6ec844a65..8a59be2d4 100644 --- a/lib/url.c +++ b/lib/url.c @@ -5031,6 +5031,7 @@ static CURLcode setup_conn(struct connectdata *conn, conn->bits.tcpconnect = TRUE; *protocol_done = TRUE; Curl_verboseconnect(conn); + Curl_updateconninfo(conn->sock[FIRSTSOCKET], &data->info); } /* Stop the loop now */ break; diff --git a/lib/urldata.h b/lib/urldata.h index 9db06405e..7763278d2 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -911,6 +911,12 @@ struct PureInfo { 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 */ struct curl_certinfo certs; /* info about the certs, only populated in OpenSSL builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */