diff options
author | Daniel Stenberg <daniel@haxx.se> | 2007-10-03 08:45:00 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2007-10-03 08:45:00 +0000 |
commit | ce1cfcb7a6a0956c3101f5a6eb20961024e55d84 (patch) | |
tree | 17c181f52f1e3ff91434e31086b0dca103b4c8b0 /lib/connect.c | |
parent | ce81cd21d3865270867d68935c9700dbaf5b5fcc (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.c | 37 |
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? */ |