getinfo: added *_PRIMARY_PORT, *_LOCAL_IP and *_LOCAL_PORT
authorFrank Meier <frank.meier@ergon.ch>
Fri, 4 Jun 2010 22:29:09 +0000 (00:29 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 4 Jun 2010 22:31:36 +0000 (00:31 +0200)
CHANGES
RELEASE-NOTES
docs/libcurl/curl_easy_getinfo.3
docs/libcurl/symbols-in-versions
include/curl/curl.h
lib/connect.c
lib/connect.h
lib/getinfo.c
lib/url.c
lib/urldata.h

diff --git a/CHANGES b/CHANGES
index 4b99f09..4379303 100644 (file)
--- 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.
index da17698..63860cd 100644 (file)
@@ -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)
index 32f0ae9..b80eacf 100644 (file)
@@ -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
index b33619e..a02ead4 100644 (file)
@@ -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
index 83ba078..b19828f 100644 (file)
@@ -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
index 4adc7f3..43e17aa 100644 (file)
@@ -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)
index 36ea4f6..b365f7d 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, 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
index 7a0ed71..d5517e4 100644 (file)
@@ -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 */
index 6ec844a..8a59be2 100644 (file)
--- 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;
index 9db0640..7763278 100644 (file)
@@ -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 */