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.)
This commit is contained in:
parent
ce81cd21d3
commit
ce1cfcb7a6
5
CHANGES
5
CHANGES
@ -7,6 +7,11 @@
|
||||
Changelog
|
||||
|
||||
Daniel S (3 October 2007)
|
||||
- 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 renamed the CURLE_SSL_PEER_CERTIFICATE error code to
|
||||
CURLE_PEER_FAILED_VERIFICATION (standard CURL_NO_OLDIES style), and made
|
||||
this return code get used by the previous SSH MD5 fingerprint check in case
|
||||
|
@ -3,7 +3,7 @@ Curl and libcurl 7.17.1
|
||||
Public curl release number: 102
|
||||
Releases counted from the very beginning: 128
|
||||
Available command line options: 121
|
||||
Available curl_easy_setopt() options: 145
|
||||
Available curl_easy_setopt() options: 147
|
||||
Number of public functions in libcurl: 55
|
||||
Amount of public web site mirrors: 42
|
||||
Number of known libcurl bindings: 36
|
||||
@ -17,6 +17,8 @@ This release includes the following changes:
|
||||
o added --post301 and CURLOPT_POST301
|
||||
o builds with c-ares 1.5.0
|
||||
o added CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 and --hostpubmd5
|
||||
o renamed CURLE_SSL_PEER_CERTIFICATE to CURLE_PEER_FAILED_VERIFICATION
|
||||
o added CURLOPT_OPENSOCKETFUNCTION and CURLOPT_OPENSOCKETDATA
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
@ -48,6 +50,7 @@ This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Dan Fandrich, Michal Marek, Günter Knauf, Rob Crittenden, Immanuel Gregoire,
|
||||
Mark Davies, Max Katsev, Philip Langdale, Alex Fishman, Johnny Luong
|
||||
Mark Davies, Max Katsev, Philip Langdale, Alex Fishman, Johnny Luong,
|
||||
Alexey Pesternikov, Yang Tse
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@ -246,6 +246,19 @@ typedef int (*curl_sockopt_callback)(void *clientp,
|
||||
curl_socket_t curlfd,
|
||||
curlsocktype purpose);
|
||||
|
||||
struct Curl_sockaddr {
|
||||
int family;
|
||||
int socktype;
|
||||
int protocol;
|
||||
socklen_t addrlen;
|
||||
struct sockaddr addr;
|
||||
};
|
||||
|
||||
typedef curl_socket_t
|
||||
(*curl_opensocket_callback)(void* clentp,
|
||||
curlsocktype purpose,
|
||||
struct Curl_sockaddr* address);
|
||||
|
||||
#ifndef CURL_NO_OLDIES
|
||||
/* not used since 7.10.8, will be removed in a future release */
|
||||
typedef int (*curl_passwd_callback)(void *clientp,
|
||||
@ -1135,6 +1148,13 @@ typedef enum {
|
||||
/* used by scp/sftp to verify the host's public key */
|
||||
CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
|
||||
|
||||
/* Callback function for opening socket (instead of socket(2)). Optionally,
|
||||
callback is able change the address or refuse to connect returning
|
||||
CURL_SOCKET_BAD. The callback should have type
|
||||
curl_opensocket_callback */
|
||||
CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
|
||||
CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
@ -677,14 +677,41 @@ singleipconnect(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sockfd;
|
||||
CURLcode res;
|
||||
/*
|
||||
* 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;
|
||||
|
||||
sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
|
||||
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? */
|
||||
|
15
lib/url.c
15
lib/url.c
@ -1813,6 +1813,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->set.sockopt_client = va_arg(param, void *);
|
||||
break;
|
||||
|
||||
case CURLOPT_OPENSOCKETFUNCTION:
|
||||
/*
|
||||
* open/create socket callback function: called instead of socket(),
|
||||
* before connect()
|
||||
*/
|
||||
data->set.fopensocket = va_arg(param, curl_opensocket_callback);
|
||||
break;
|
||||
|
||||
case CURLOPT_OPENSOCKETDATA:
|
||||
/*
|
||||
* socket callback data pointer. Might be NULL.
|
||||
*/
|
||||
data->set.opensocket_client = va_arg(param, void *);
|
||||
break;
|
||||
|
||||
case CURLOPT_SSL_SESSIONID_CACHE:
|
||||
data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
|
||||
break;
|
||||
|
@ -1328,6 +1328,9 @@ struct UserDefined {
|
||||
curl_ioctl_callback ioctl_func; /* function for I/O control */
|
||||
curl_sockopt_callback fsockopt; /* function for setting socket options */
|
||||
void *sockopt_client; /* pointer to pass to the socket options callback */
|
||||
curl_opensocket_callback fopensocket; /* function for checking/translating
|
||||
the address and opening the socket */
|
||||
void* opensocket_client;
|
||||
|
||||
/* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
|
||||
/* function to convert from the network encoding: */
|
||||
|
Loading…
x
Reference in New Issue
Block a user