From 8098d9417c649272b9d6d2ad76abbde7dfbfcad1 Mon Sep 17 00:00:00 2001 From: Frank Meier Date: Sat, 5 Jun 2010 00:29:09 +0200 Subject: getinfo: added *_PRIMARY_PORT, *_LOCAL_IP and *_LOCAL_PORT --- lib/connect.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ lib/connect.h | 4 +++- lib/getinfo.c | 19 +++++++++++++++++++ lib/url.c | 1 + lib/urldata.h | 6 ++++++ 5 files changed, 76 insertions(+), 1 deletion(-) (limited to 'lib') 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 */ -- cgit v1.2.3