aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFrank Meier <frank.meier@ergon.ch>2010-06-05 00:29:09 +0200
committerDaniel Stenberg <daniel@haxx.se>2010-06-05 00:31:36 +0200
commit8098d9417c649272b9d6d2ad76abbde7dfbfcad1 (patch)
treee1a81f1d49804a97d60c2dc78678f3a5c64925fd /lib
parent605207a3a60f515c77216922870e086dc8cc7f1b (diff)
getinfo: added *_PRIMARY_PORT, *_LOCAL_IP and *_LOCAL_PORT
Diffstat (limited to 'lib')
-rw-r--r--lib/connect.c47
-rw-r--r--lib/connect.h4
-rw-r--r--lib/getinfo.c19
-rw-r--r--lib/url.c1
-rw-r--r--lib/urldata.h6
5 files changed, 76 insertions, 1 deletions
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, <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
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 */