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