Commit ce1cfcb7 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

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.)
parent ce81cd21
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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
+5 −2
Original line number Diff line number Diff line
@@ -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, Gnter 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)
+20 −0
Original line number Diff line number Diff line
@@ -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;

+32 −5
Original line number Diff line number Diff line
@@ -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? */
+77 −62
Original line number Diff line number Diff line
@@ -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;
Loading