1---
2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
3SPDX-License-Identifier: curl
4Title: CURLOPT_SOCKOPTFUNCTION
5Section: 3
6Source: libcurl
7See-also:
8  - CURLOPT_OPENSOCKETFUNCTION (3)
9  - CURLOPT_SEEKFUNCTION (3)
10  - CURLOPT_SOCKOPTDATA (3)
11Protocol:
12  - All
13---
14
15# NAME
16
17CURLOPT_SOCKOPTFUNCTION - callback for setting socket options
18
19# SYNOPSIS
20
21~~~c
22#include <curl/curl.h>
23
24typedef enum  {
25  CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
26  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
27  CURLSOCKTYPE_LAST    /* never use */
28} curlsocktype;
29
30#define CURL_SOCKOPT_OK 0
31#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
32                                CURLE_ABORTED_BY_CALLBACK */
33#define CURL_SOCKOPT_ALREADY_CONNECTED 2
34
35int sockopt_callback(void *clientp,
36                     curl_socket_t curlfd,
37                     curlsocktype purpose);
38
39CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
40~~~
41
42# DESCRIPTION
43
44Pass a pointer to your callback function, which should match the prototype
45shown above.
46
47When set, this callback function gets called by libcurl when the socket has
48been created, but before the connect call to allow applications to change
49specific socket options. The callback's *purpose* argument identifies the
50exact purpose for this particular socket:
51
52*CURLSOCKTYPE_IPCXN* for actively created connections or since 7.28.0
53*CURLSOCKTYPE_ACCEPT* for FTP when the connection was setup with PORT/EPSV
54(in earlier versions these sockets were not passed to this callback).
55
56Future versions of libcurl may support more purposes. libcurl passes the newly
57created socket descriptor to the callback in the *curlfd* parameter so
58additional setsockopt() calls can be done at the user's discretion.
59
60The *clientp* pointer contains whatever user-defined value set using the
61CURLOPT_SOCKOPTDATA(3) function.
62
63Return *CURL_SOCKOPT_OK* from the callback on success. Return
64*CURL_SOCKOPT_ERROR* from the callback function to signal an unrecoverable
65error to the library and it closes the socket and returns
66*CURLE_COULDNT_CONNECT*. Alternatively, the callback function can return
67*CURL_SOCKOPT_ALREADY_CONNECTED*, to tell libcurl that the socket is
68already connected and then libcurl does no attempt to connect. This allows an
69application to pass in an already connected socket with
70CURLOPT_OPENSOCKETFUNCTION(3) and then have this function make libcurl
71not attempt to connect (again).
72
73# DEFAULT
74
75By default, this callback is NULL and unused.
76
77# EXAMPLE
78
79~~~c
80/* make libcurl use the already established socket 'sockfd' */
81
82static curl_socket_t opensocket(void *clientp,
83                                curlsocktype purpose,
84                                struct curl_sockaddr *address)
85{
86  curl_socket_t sockfd;
87  sockfd = *(curl_socket_t *)clientp;
88  /* the actual externally set socket is passed in via the OPENSOCKETDATA
89     option */
90  return sockfd;
91}
92
93static int sockopt_callback(void *clientp, curl_socket_t curlfd,
94                            curlsocktype purpose)
95{
96  /* This return code was added in libcurl 7.21.5 */
97  return CURL_SOCKOPT_ALREADY_CONNECTED;
98}
99
100int main(void)
101{
102  CURL *curl = curl_easy_init();
103  if(curl) {
104    CURLcode res;
105    int sockfd; /* our custom file descriptor */
106    /* libcurl thinks that you connect to the host
107     * and port that you specify in the URL option. */
108    curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
109    /* call this function to get a socket */
110    curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
111    curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
112
113    /* call this function to set options for the socket */
114    curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
115
116    res = curl_easy_perform(curl);
117
118    curl_easy_cleanup(curl);
119  }
120}
121~~~
122
123# AVAILABILITY
124
125Added in 7.16.0. The *CURL_SOCKOPT_ALREADY_CONNECTED* return code was
126added in 7.21.5.
127
128# RETURN VALUE
129
130Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
131