quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

CURLOPT_OPENSOCKETFUNCTION.md (4278B)


      1 ---
      2 c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      3 SPDX-License-Identifier: curl
      4 Title: CURLOPT_OPENSOCKETFUNCTION
      5 Section: 3
      6 Source: libcurl
      7 See-also:
      8   - CURLOPT_CLOSESOCKETFUNCTION (3)
      9   - CURLOPT_OPENSOCKETFUNCTION (3)
     10   - CURLOPT_SOCKOPTFUNCTION (3)
     11 Protocol:
     12   - All
     13 Added-in: 7.17.1
     14 ---
     15 
     16 # NAME
     17 
     18 CURLOPT_OPENSOCKETFUNCTION - callback for opening socket
     19 
     20 # SYNOPSIS
     21 
     22 ~~~c
     23 #include <curl/curl.h>
     24 
     25 typedef enum  {
     26   CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
     27 } curlsocktype;
     28 
     29 struct curl_sockaddr {
     30   int family;
     31   int socktype;
     32   int protocol;
     33   unsigned int addrlen;
     34   struct sockaddr addr;
     35 };
     36 
     37 curl_socket_t opensocket_callback(void *clientp,
     38                                   curlsocktype purpose,
     39                                   struct curl_sockaddr *address);
     40 
     41 CURLcode curl_easy_setopt(CURL *handle, CURLOPT_OPENSOCKETFUNCTION, opensocket_callback);
     42 ~~~
     43 
     44 # DESCRIPTION
     45 
     46 Pass a pointer to your callback function, which should match the prototype
     47 shown above.
     48 
     49 This callback function gets called by libcurl instead of the *socket(2)*
     50 call. The callback's *purpose* argument identifies the exact purpose for
     51 this particular socket. *CURLSOCKTYPE_IPCXN* is for IP based connections
     52 and is the only purpose currently used in libcurl. Future versions of libcurl
     53 may support more purposes.
     54 
     55 The *clientp* pointer contains whatever user-defined value set using the
     56 CURLOPT_OPENSOCKETDATA(3) function.
     57 
     58 The callback gets the resolved peer address as the *address* argument and
     59 is allowed to modify the address or refuse to connect completely. The callback
     60 function should return the newly created socket or *CURL_SOCKET_BAD* in
     61 case no connection could be established or another error was detected. Any
     62 additional *setsockopt(2)* calls can of course be done on the socket at
     63 the user's discretion.
     64 
     65 If *CURL_SOCKET_BAD* is returned by the callback then libcurl treats it as a
     66 failed connection and tries to open a socket to connect to a different IP
     67 address associated with the transfer. If there are no more addresses to try
     68 then libcurl fails the transfer with error code *CURLE_COULDNT_CONNECT*.
     69 
     70 You can get the IP address that curl is opening the socket for by casting
     71 *address-\>addr* to `sockaddr_in` if *address-\>family* is `AF_INET`, or to
     72 `sockaddr_in6` if *address-\>family* is `AF_INET6`. For an example of how that
     73 data can be compared against refer to *docs/examples/block_ip.c*.
     74 
     75 If you want to pass in a socket with an already established connection, pass
     76 the socket back with this callback and then use CURLOPT_SOCKOPTFUNCTION(3) to
     77 signal that it already is connected.
     78 
     79 # DEFAULT
     80 
     81 The equivalent of this:
     82 ~~~c
     83    return socket(addr->family, addr->socktype, addr->protocol);
     84 ~~~
     85 
     86 # %PROTOCOLS%
     87 
     88 # EXAMPLE
     89 
     90 ~~~c
     91 /* make libcurl use the already established socket 'sockfd' */
     92 
     93 static curl_socket_t opensocket(void *clientp,
     94                                 curlsocktype purpose,
     95                                 struct curl_sockaddr *address)
     96 {
     97   curl_socket_t sockfd;
     98   sockfd = *(curl_socket_t *)clientp;
     99   /* the actual externally set socket is passed in via the OPENSOCKETDATA
    100      option */
    101   return sockfd;
    102 }
    103 
    104 static int sockopt_callback(void *clientp, curl_socket_t curlfd,
    105                             curlsocktype purpose)
    106 {
    107   /* This return code was added in libcurl 7.21.5 */
    108   return CURL_SOCKOPT_ALREADY_CONNECTED;
    109 }
    110 
    111 int main(void)
    112 {
    113   CURL *curl = curl_easy_init();
    114   if(curl) {
    115     CURLcode res;
    116     extern int sockfd; /* the already connected one */
    117     /* libcurl thinks that you connect to the host
    118      * and port that you specify in the URL option. */
    119     curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
    120     /* call this function to get a socket */
    121     curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
    122     curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
    123 
    124     /* call this function to set options for the socket */
    125     curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
    126 
    127     res = curl_easy_perform(curl);
    128 
    129     curl_easy_cleanup(curl);
    130   }
    131 }
    132 ~~~
    133 
    134 # %AVAILABILITY%
    135 
    136 # RETURN VALUE
    137 
    138 curl_easy_setopt(3) returns a CURLcode indicating success or error.
    139 
    140 CURLE_OK (0) means everything was OK, non-zero means an error occurred, see
    141 libcurl-errors(3).