aboutsummaryrefslogtreecommitdiff
path: root/lib/connect.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-10-03 08:45:00 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-10-03 08:45:00 +0000
commitce1cfcb7a6a0956c3101f5a6eb20961024e55d84 (patch)
tree17c181f52f1e3ff91434e31086b0dca103b4c8b0 /lib/connect.c
parentce81cd21d3865270867d68935c9700dbaf5b5fcc (diff)
Alexey Pesternikov introduced CURLOPT_OPENSOCKETFUNCTION and
CURLOPT_OPENSOCKETDATA to set a callback that allows an application to replace the socket() call used by libcurl. It basically allows the app to change address, protocol or whatever of the socket. (I also did some whitespace indent/cleanups in lib/url.c which kind of hides some of these changes, sorry for mixing those in.)
Diffstat (limited to 'lib/connect.c')
-rw-r--r--lib/connect.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/lib/connect.c b/lib/connect.c
index c8c82a1b7..b0615661f 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -677,14 +677,41 @@ singleipconnect(struct connectdata *conn,
struct SessionHandle *data = conn->data;
curl_socket_t sockfd;
CURLcode res;
-
- sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
+ /*
+ * Curl_sockaddr_storage, which is basically sockaddr_storage has a space
+ * for a largest possible struct sockaddr only. We should add some space for
+ * the other fields we are using. Hence the addr_storage size math.
+ */
+ char addr_storage[sizeof(struct Curl_sockaddr)-
+ sizeof(struct sockaddr)+
+ sizeof(struct Curl_sockaddr_storage)];
+ struct Curl_sockaddr* addr=(struct Curl_sockaddr*)&addr_storage;
+
+ addr->family=ai->ai_family;
+ addr->socktype=conn->socktype;
+ addr->protocol=ai->ai_protocol;
+ addr->addrlen=(ai->ai_addrlen<=sizeof(struct Curl_sockaddr_storage))?
+ ai->ai_addrlen:sizeof(struct Curl_sockaddr_storage);
+ memcpy(&addr->addr, ai->ai_addr, addr->addrlen);
+
+ /* optionally use callback to get the socket */
+ sockfd = (data->set.fopensocket)?
+ data->set.fopensocket(data->set.opensocket_client, CURLSOCKTYPE_IPCXN,
+ &addr):
+ socket(addr->family, addr->socktype, addr->protocol);
if (sockfd == CURL_SOCKET_BAD)
return CURL_SOCKET_BAD;
*connected = FALSE; /* default is not connected */
- Curl_printable_address(ai, addr_buf, sizeof(addr_buf));
+ /* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
+ argument? */
+ const void *iptoprint = &((const struct sockaddr_in*)(&addr->addr))->sin_addr;
+#ifdef ENABLE_IPV6
+ if(addr->family==AF_INET6)
+ iptoprint= &((const struct sockaddr_in6*)(&addr->addr))->sin6_addr;
+#endif
+ Curl_inet_ntop(addr->family, iptoprint, addr_buf, sizeof(addr_buf));
infof(data, " Trying %s... ", addr_buf);
if(data->set.tcp_nodelay)
@@ -715,7 +742,7 @@ singleipconnect(struct connectdata *conn,
/* Connect TCP sockets, bind UDP */
if(conn->socktype == SOCK_STREAM)
- rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
+ rc = connect(sockfd, &addr->addr, addr->addrlen);
else
rc = 0;
@@ -779,7 +806,7 @@ singleipconnect(struct connectdata *conn,
*/
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
- const struct Curl_dns_entry *remotehost, /* use this one */
+ const struct Curl_dns_entry *remotehost,
curl_socket_t *sockconn, /* the connected socket */
Curl_addrinfo **addr, /* the one we used */
bool *connected) /* really connected? */