VirtualBox

source: vbox/trunk/src/libs/curl-8.11.1/lib/cfilters.h

Last change on this file was 108048, checked in by vboxsync, 3 months ago

curl-8.11.1: Applied and adjusted our curl changes to 8.7.1. jiraref:VBP-1535

  • Property svn:eol-style set to native
File size: 27.7 KB
Line 
1#ifndef HEADER_CURL_CFILTERS_H
2#define HEADER_CURL_CFILTERS_H
3/***************************************************************************
4 * _ _ ____ _
5 * Project ___| | | | _ \| |
6 * / __| | | | |_) | |
7 * | (__| |_| | _ <| |___
8 * \___|\___/|_| \_\_____|
9 *
10 * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
11 *
12 * This software is licensed as described in the file COPYING, which
13 * you should have received as part of this distribution. The terms
14 * are also available at https://curl.se/docs/copyright.html.
15 *
16 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17 * copies of the Software, and permit persons to whom the Software is
18 * furnished to do so, under the terms of the COPYING file.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 * SPDX-License-Identifier: curl
24 *
25 ***************************************************************************/
26
27#include "timediff.h"
28
29struct Curl_cfilter;
30struct Curl_easy;
31struct Curl_dns_entry;
32struct connectdata;
33struct ip_quadruple;
34
35/* Callback to destroy resources held by this filter instance.
36 * Implementations MUST NOT chain calls to cf->next.
37 */
38typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf,
39 struct Curl_easy *data);
40
41/* Callback to close the connection immediately. */
42typedef void Curl_cft_close(struct Curl_cfilter *cf,
43 struct Curl_easy *data);
44
45/* Callback to close the connection filter gracefully, non-blocking.
46 * Implementations MUST NOT chain calls to cf->next.
47 */
48typedef CURLcode Curl_cft_shutdown(struct Curl_cfilter *cf,
49 struct Curl_easy *data,
50 bool *done);
51
52typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf,
53 struct Curl_easy *data,
54 bool blocking, bool *done);
55
56/* Return the hostname and port the connection goes to.
57 * This may change with the connection state of filters when tunneling
58 * is involved.
59 * @param cf the filter to ask
60 * @param data the easy handle currently active
61 * @param phost on return, points to the relevant, real hostname.
62 * this is owned by the connection.
63 * @param pdisplay_host on return, points to the printable hostname.
64 * this is owned by the connection.
65 * @param pport on return, contains the port number
66 */
67typedef void Curl_cft_get_host(struct Curl_cfilter *cf,
68 struct Curl_easy *data,
69 const char **phost,
70 const char **pdisplay_host,
71 int *pport);
72
73struct easy_pollset;
74
75/* Passing in an easy_pollset for monitoring of sockets, let
76 * filters add or remove sockets actions (CURL_POLL_OUT, CURL_POLL_IN).
77 * This may add a socket or, in case no actions remain, remove
78 * a socket from the set.
79 *
80 * Filter implementations need to call filters "below" *after* they have
81 * made their adjustments. This allows lower filters to override "upper"
82 * actions. If a "lower" filter is unable to write, it needs to be able
83 * to disallow POLL_OUT.
84 *
85 * A filter without own restrictions/preferences should not modify
86 * the pollset. Filters, whose filter "below" is not connected, should
87 * also do no adjustments.
88 *
89 * Examples: a TLS handshake, while ongoing, might remove POLL_IN when it
90 * needs to write, or vice versa. An HTTP/2 filter might remove POLL_OUT when
91 * a stream window is exhausted and a WINDOW_UPDATE needs to be received first
92 * and add instead POLL_IN.
93 *
94 * @param cf the filter to ask
95 * @param data the easy handle the pollset is about
96 * @param ps the pollset (inout) for the easy handle
97 */
98typedef void Curl_cft_adjust_pollset(struct Curl_cfilter *cf,
99 struct Curl_easy *data,
100 struct easy_pollset *ps);
101
102typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
103 const struct Curl_easy *data);
104
105typedef ssize_t Curl_cft_send(struct Curl_cfilter *cf,
106 struct Curl_easy *data, /* transfer */
107 const void *buf, /* data to write */
108 size_t len, /* amount to write */
109 bool eos, /* last chunk */
110 CURLcode *err); /* error to return */
111
112typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf,
113 struct Curl_easy *data, /* transfer */
114 char *buf, /* store data here */
115 size_t len, /* amount to read */
116 CURLcode *err); /* error to return */
117
118typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf,
119 struct Curl_easy *data,
120 bool *input_pending);
121
122typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
123 struct Curl_easy *data);
124
125/**
126 * Events/controls for connection filters, their arguments and
127 * return code handling. Filter callbacks are invoked "top down".
128 * Return code handling:
129 * "first fail" meaning that the first filter returning != CURLE_OK, will
130 * abort further event distribution and determine the result.
131 * "ignored" meaning return values are ignored and the event is distributed
132 * to all filters in the chain. Overall result is always CURLE_OK.
133 */
134/* data event arg1 arg2 return */
135#define CF_CTRL_DATA_ATTACH 1 /* 0 NULL ignored */
136#define CF_CTRL_DATA_DETACH 2 /* 0 NULL ignored */
137#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
138#define CF_CTRL_DATA_IDLE 5 /* 0 NULL first fail */
139#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
140#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
141#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
142/* update conn info at connection and data */
143#define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */
144#define CF_CTRL_FORGET_SOCKET (256+1) /* 0 NULL ignored */
145#define CF_CTRL_FLUSH (256+2) /* 0 NULL first fail */
146
147/**
148 * Handle event/control for the filter.
149 * Implementations MUST NOT chain calls to cf->next.
150 */
151typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
152 struct Curl_easy *data,
153 int event, int arg1, void *arg2);
154
155
156/**
157 * Queries to ask via a `Curl_cft_query *query` method on a cfilter chain.
158 * - MAX_CONCURRENT: the maximum number of parallel transfers the filter
159 * chain expects to handle at the same time.
160 * default: 1 if no filter overrides.
161 * - CONNECT_REPLY_MS: milliseconds until the first indication of a server
162 * response was received on a connect. For TCP, this
163 * reflects the time until the socket connected. On UDP
164 * this gives the time the first bytes from the server
165 * were received.
166 * -1 if not determined yet.
167 * - CF_QUERY_SOCKET: the socket used by the filter chain
168 * - CF_QUERY_NEED_FLUSH: TRUE iff any of the filters have unsent data
169 * - CF_QUERY_IP_INFO: res1 says if connection used IPv6, res2 is the
170 * ip quadruple
171 */
172/* query res1 res2 */
173#define CF_QUERY_MAX_CONCURRENT 1 /* number - */
174#define CF_QUERY_CONNECT_REPLY_MS 2 /* number - */
175#define CF_QUERY_SOCKET 3 /* - curl_socket_t */
176#define CF_QUERY_TIMER_CONNECT 4 /* - struct curltime */
177#define CF_QUERY_TIMER_APPCONNECT 5 /* - struct curltime */
178#define CF_QUERY_STREAM_ERROR 6 /* error code - */
179#define CF_QUERY_NEED_FLUSH 7 /* TRUE/FALSE - */
180#define CF_QUERY_IP_INFO 8 /* TRUE/FALSE struct ip_quadruple */
181
182/**
183 * Query the cfilter for properties. Filters ignorant of a query will
184 * pass it "down" the filter chain.
185 */
186typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
187 struct Curl_easy *data,
188 int query, int *pres1, void *pres2);
189
190/**
191 * Type flags for connection filters. A filter can have none, one or
192 * many of those. Use to evaluate state/capabilities of a filter chain.
193 *
194 * CF_TYPE_IP_CONNECT: provides an IP connection or sth equivalent, like
195 * a CONNECT tunnel, a UNIX domain socket, a QUIC
196 * connection, etc.
197 * CF_TYPE_SSL: provide SSL/TLS
198 * CF_TYPE_MULTIPLEX: provides multiplexing of easy handles
199 * CF_TYPE_PROXY provides proxying
200 */
201#define CF_TYPE_IP_CONNECT (1 << 0)
202#define CF_TYPE_SSL (1 << 1)
203#define CF_TYPE_MULTIPLEX (1 << 2)
204#define CF_TYPE_PROXY (1 << 3)
205
206/* A connection filter type, e.g. specific implementation. */
207struct Curl_cftype {
208 const char *name; /* name of the filter type */
209 int flags; /* flags of filter type */
210 int log_level; /* log level for such filters */
211 Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
212 Curl_cft_connect *do_connect; /* establish connection */
213 Curl_cft_close *do_close; /* close conn */
214 Curl_cft_shutdown *do_shutdown; /* shutdown conn */
215 Curl_cft_get_host *get_host; /* host filter talks to */
216 Curl_cft_adjust_pollset *adjust_pollset; /* adjust transfer poll set */
217 Curl_cft_data_pending *has_data_pending;/* conn has data pending */
218 Curl_cft_send *do_send; /* send data */
219 Curl_cft_recv *do_recv; /* receive data */
220 Curl_cft_cntrl *cntrl; /* events/control */
221 Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */
222 Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */
223 Curl_cft_query *query; /* query filter chain */
224};
225
226/* A connection filter instance, e.g. registered at a connection */
227struct Curl_cfilter {
228 const struct Curl_cftype *cft; /* the type providing implementation */
229 struct Curl_cfilter *next; /* next filter in chain */
230 void *ctx; /* filter type specific settings */
231 struct connectdata *conn; /* the connection this filter belongs to */
232 int sockindex; /* the index the filter is installed at */
233 BIT(connected); /* != 0 iff this filter is connected */
234 BIT(shutdown); /* != 0 iff this filter has shut down */
235};
236
237/* Default implementations for the type functions, implementing nop. */
238void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
239 struct Curl_easy *data);
240
241/* Default implementations for the type functions, implementing pass-through
242 * the filter chain. */
243void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
244 const char **phost, const char **pdisplay_host,
245 int *pport);
246void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
247 struct Curl_easy *data,
248 struct easy_pollset *ps);
249bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
250 const struct Curl_easy *data);
251ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
252 const void *buf, size_t len, bool eos,
253 CURLcode *err);
254ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
255 char *buf, size_t len, CURLcode *err);
256CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
257 struct Curl_easy *data,
258 int event, int arg1, void *arg2);
259bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
260 struct Curl_easy *data,
261 bool *input_pending);
262CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
263 struct Curl_easy *data);
264CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
265 struct Curl_easy *data,
266 int query, int *pres1, void *pres2);
267CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf,
268 struct Curl_easy *data, bool *done);
269
270/**
271 * Create a new filter instance, unattached to the filter chain.
272 * Use Curl_conn_cf_add() to add it to the chain.
273 * @param pcf on success holds the created instance
274 * @param cft the filter type
275 * @param ctx the type specific context to use
276 */
277CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
278 const struct Curl_cftype *cft,
279 void *ctx);
280
281/**
282 * Add a filter instance to the `sockindex` filter chain at connection
283 * `conn`. The filter must not already be attached. It is inserted at
284 * the start of the chain (top).
285 */
286void Curl_conn_cf_add(struct Curl_easy *data,
287 struct connectdata *conn,
288 int sockindex,
289 struct Curl_cfilter *cf);
290
291/**
292 * Insert a filter (chain) after `cf_at`.
293 * `cf_new` must not already be attached.
294 */
295void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
296 struct Curl_cfilter *cf_new);
297
298/**
299 * Discard, e.g. remove and destroy `discard` iff
300 * it still is in the filter chain below `cf`. If `discard`
301 * is no longer found beneath `cf` return FALSE.
302 * if `destroy_always` is TRUE, will call `discard`s destroy
303 * function and free it even if not found in the subchain.
304 */
305bool Curl_conn_cf_discard_sub(struct Curl_cfilter *cf,
306 struct Curl_cfilter *discard,
307 struct Curl_easy *data,
308 bool destroy_always);
309
310/**
311 * Discard all cfilters starting with `*pcf` and clearing it afterwards.
312 */
313void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
314 struct Curl_easy *data);
315
316/**
317 * Remove and destroy all filters at chain `sockindex` on connection `conn`.
318 */
319void Curl_conn_cf_discard_all(struct Curl_easy *data,
320 struct connectdata *conn,
321 int sockindex);
322
323
324CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
325 struct Curl_easy *data,
326 bool blocking, bool *done);
327void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
328ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
329 const void *buf, size_t len, bool eos,
330 CURLcode *err);
331ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
332 char *buf, size_t len, CURLcode *err);
333CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
334 struct Curl_easy *data,
335 bool ignore_result,
336 int event, int arg1, void *arg2);
337
338/**
339 * Determine if the connection filter chain is using SSL to the remote host
340 * (or will be once connected).
341 */
342bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf);
343
344/**
345 * Get the socket used by the filter chain starting at `cf`.
346 * Returns CURL_SOCKET_BAD if not available.
347 */
348curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
349 struct Curl_easy *data);
350
351CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf,
352 struct Curl_easy *data,
353 int *is_ipv6, struct ip_quadruple *ipquad);
354
355bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf,
356 struct Curl_easy *data);
357
358#define CURL_CF_SSL_DEFAULT -1
359#define CURL_CF_SSL_DISABLE 0
360#define CURL_CF_SSL_ENABLE 1
361
362/**
363 * Bring the filter chain at `sockindex` for connection `data->conn` into
364 * connected state. Which will set `*done` to TRUE.
365 * This can be called on an already connected chain with no side effects.
366 * When not `blocking`, calls may return without error and `*done != TRUE`,
367 * while the individual filters negotiated the connection.
368 */
369CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
370 bool blocking, bool *done);
371
372/**
373 * Check if the filter chain at `sockindex` for connection `conn` is
374 * completely connected.
375 */
376bool Curl_conn_is_connected(struct connectdata *conn, int sockindex);
377
378/**
379 * Determine if we have reached the remote host on IP level, e.g.
380 * have a TCP connection. This turns TRUE before a possible SSL
381 * handshake has been started/done.
382 */
383bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
384
385/**
386 * Determine if the connection is using SSL to the remote host
387 * (or will be once connected). This will return FALSE, if SSL
388 * is only used in proxying and not for the tunnel itself.
389 */
390bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex);
391
392/**
393 * Connection provides multiplexing of easy handles at `socketindex`.
394 */
395bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex);
396
397/**
398 * Close the filter chain at `sockindex` for connection `data->conn`.
399 * Filters remain in place and may be connected again afterwards.
400 */
401void Curl_conn_close(struct Curl_easy *data, int sockindex);
402
403/**
404 * Shutdown the connection at `sockindex` non-blocking, using timeout
405 * from `data->set.shutdowntimeout`, default DEFAULT_SHUTDOWN_TIMEOUT_MS.
406 * Will return CURLE_OK and *done == FALSE if not finished.
407 */
408CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done);
409
410/**
411 * Return if data is pending in some connection filter at chain
412 * `sockindex` for connection `data->conn`.
413 */
414bool Curl_conn_data_pending(struct Curl_easy *data,
415 int sockindex);
416
417/**
418 * Return TRUE if any of the connection filters at chain `sockindex`
419 * have data still to send.
420 */
421bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex);
422
423/**
424 * Flush any pending data on the connection filters at chain `sockindex`.
425 */
426CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex);
427
428/**
429 * Return the socket used on data's connection for the index.
430 * Returns CURL_SOCKET_BAD if not available.
431 */
432curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
433
434/**
435 * Tell filters to forget about the socket at sockindex.
436 */
437void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex);
438
439/**
440 * Adjust the pollset for the filter chain startgin at `cf`.
441 */
442void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
443 struct Curl_easy *data,
444 struct easy_pollset *ps);
445
446/**
447 * Adjust pollset from filters installed at transfer's connection.
448 */
449void Curl_conn_adjust_pollset(struct Curl_easy *data,
450 struct easy_pollset *ps);
451
452/**
453 * Curl_poll() the filter chain at `cf` with timeout `timeout_ms`.
454 * Returns 0 on timeout, negative on error or number of sockets
455 * with requested poll events.
456 */
457int Curl_conn_cf_poll(struct Curl_cfilter *cf,
458 struct Curl_easy *data,
459 timediff_t timeout_ms);
460
461/**
462 * Receive data through the filter chain at `sockindex` for connection
463 * `data->conn`. Copy at most `len` bytes into `buf`. Return the
464 * actual number of bytes copied or a negative value on error.
465 * The error code is placed into `*code`.
466 */
467ssize_t Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf,
468 size_t len, CURLcode *code);
469
470/**
471 * Send `len` bytes of data from `buf` through the filter chain `sockindex`
472 * at connection `data->conn`. Return the actual number of bytes written
473 * or a negative value on error.
474 * The error code is placed into `*code`.
475 */
476ssize_t Curl_cf_send(struct Curl_easy *data, int sockindex,
477 const void *buf, size_t len, bool eos, CURLcode *code);
478
479/**
480 * The easy handle `data` is being attached to `conn`. This does
481 * not mean that data will actually do a transfer. Attachment is
482 * also used for temporary actions on the connection.
483 */
484void Curl_conn_ev_data_attach(struct connectdata *conn,
485 struct Curl_easy *data);
486
487/**
488 * The easy handle `data` is being detached (no longer served)
489 * by connection `conn`. All filters are informed to release any resources
490 * related to `data`.
491 * Note: there may be several `data` attached to a connection at the same
492 * time.
493 */
494void Curl_conn_ev_data_detach(struct connectdata *conn,
495 struct Curl_easy *data);
496
497/**
498 * Notify connection filters that they need to setup data for
499 * a transfer.
500 */
501CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data);
502
503/**
504 * Notify connection filters that now would be a good time to
505 * perform any idle, e.g. time related, actions.
506 */
507CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data);
508
509/**
510 * Notify connection filters that the transfer represented by `data`
511 * is done with sending data (e.g. has uploaded everything).
512 */
513void Curl_conn_ev_data_done_send(struct Curl_easy *data);
514
515/**
516 * Notify connection filters that the transfer represented by `data`
517 * is finished - eventually premature, e.g. before being complete.
518 */
519void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature);
520
521/**
522 * Notify connection filters that the transfer of data is paused/unpaused.
523 */
524CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause);
525
526/**
527 * Check if FIRSTSOCKET's cfilter chain deems connection alive.
528 */
529bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
530 bool *input_pending);
531
532/**
533 * Try to upkeep the connection filters at sockindex.
534 */
535CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
536 struct connectdata *conn,
537 int sockindex);
538
539#ifdef UNITTESTS
540void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
541#endif
542void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
543 const char **phost, const char **pdisplay_host,
544 int *pport);
545
546/**
547 * Get the maximum number of parallel transfers the connection
548 * expects to be able to handle at `sockindex`.
549 */
550size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
551 struct connectdata *conn,
552 int sockindex);
553
554/**
555 * Get the underlying error code for a transfer stream or 0 if not known.
556 */
557int Curl_conn_get_stream_error(struct Curl_easy *data,
558 struct connectdata *conn,
559 int sockindex);
560
561/**
562 * Get the index of the given socket in the connection's sockets.
563 * Useful in calling `Curl_conn_send()/Curl_conn_recv()` with the
564 * correct socket index.
565 */
566int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd);
567
568/*
569 * Receive data on the connection, using FIRSTSOCKET/SECONDARYSOCKET.
570 * Will return CURLE_AGAIN iff blocked on receiving.
571 */
572CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
573 char *buf, size_t buffersize,
574 ssize_t *pnread);
575
576/*
577 * Send data on the connection, using FIRSTSOCKET/SECONDARYSOCKET.
578 * Will return CURLE_AGAIN iff blocked on sending.
579 */
580CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
581 const void *buf, size_t blen, bool eos,
582 size_t *pnwritten);
583
584
585void Curl_pollset_reset(struct Curl_easy *data,
586 struct easy_pollset *ps);
587
588/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for
589 * socket `sock`. If the socket is not already part of the poll set, it
590 * will be added.
591 * If the socket is present and all poll flags are cleared, it will be removed.
592 */
593void Curl_pollset_change(struct Curl_easy *data,
594 struct easy_pollset *ps, curl_socket_t sock,
595 int add_flags, int remove_flags);
596
597void Curl_pollset_set(struct Curl_easy *data,
598 struct easy_pollset *ps, curl_socket_t sock,
599 bool do_in, bool do_out);
600
601#define Curl_pollset_add_in(data, ps, sock) \
602 Curl_pollset_change((data), (ps), (sock), CURL_POLL_IN, 0)
603#define Curl_pollset_add_out(data, ps, sock) \
604 Curl_pollset_change((data), (ps), (sock), CURL_POLL_OUT, 0)
605#define Curl_pollset_add_inout(data, ps, sock) \
606 Curl_pollset_change((data), (ps), (sock), \
607 CURL_POLL_IN|CURL_POLL_OUT, 0)
608#define Curl_pollset_set_in_only(data, ps, sock) \
609 Curl_pollset_change((data), (ps), (sock), \
610 CURL_POLL_IN, CURL_POLL_OUT)
611#define Curl_pollset_set_out_only(data, ps, sock) \
612 Curl_pollset_change((data), (ps), (sock), \
613 CURL_POLL_OUT, CURL_POLL_IN)
614
615void Curl_pollset_add_socks(struct Curl_easy *data,
616 struct easy_pollset *ps,
617 int (*get_socks_cb)(struct Curl_easy *data,
618 curl_socket_t *socks));
619
620/**
621 * Check if the pollset, as is, wants to read and/or write regarding
622 * the given socket.
623 */
624void Curl_pollset_check(struct Curl_easy *data,
625 struct easy_pollset *ps, curl_socket_t sock,
626 bool *pwant_read, bool *pwant_write);
627
628/**
629 * Types and macros used to keep the current easy handle in filter calls,
630 * allowing for nested invocations. See #10336.
631 *
632 * `cf_call_data` is intended to be a member of the cfilter's `ctx` type.
633 * A filter defines the macro `CF_CTX_CALL_DATA` to give access to that.
634 *
635 * With all values 0, the default, this indicates that there is no cfilter
636 * call with `data` ongoing.
637 * Macro `CF_DATA_SAVE` preserves the current `cf_call_data` in a local
638 * variable and sets the `data` given, incrementing the `depth` counter.
639 *
640 * Macro `CF_DATA_RESTORE` restores the old values from the local variable,
641 * while checking that `depth` values are as expected (debug build), catching
642 * cases where a "lower" RESTORE was not called.
643 *
644 * Finally, macro `CF_DATA_CURRENT` gives the easy handle of the current
645 * invocation.
646 */
647struct cf_call_data {
648 struct Curl_easy *data;
649#ifdef DEBUGBUILD
650 int depth;
651#endif
652};
653
654/**
655 * define to access the `struct cf_call_data for a cfilter. Normally
656 * a member in the cfilter's `ctx`.
657 *
658 * #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance
659*/
660
661#ifdef DEBUGBUILD
662
663#define CF_DATA_SAVE(save, cf, data) \
664 do { \
665 (save) = CF_CTX_CALL_DATA(cf); \
666 DEBUGASSERT((save).data == NULL || (save).depth > 0); \
667 CF_CTX_CALL_DATA(cf).depth++; \
668 CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
669 } while(0)
670
671#define CF_DATA_RESTORE(cf, save) \
672 do { \
673 DEBUGASSERT(CF_CTX_CALL_DATA(cf).depth == (save).depth + 1); \
674 DEBUGASSERT((save).data == NULL || (save).depth > 0); \
675 CF_CTX_CALL_DATA(cf) = (save); \
676 } while(0)
677
678#else /* DEBUGBUILD */
679
680#define CF_DATA_SAVE(save, cf, data) \
681 do { \
682 (save) = CF_CTX_CALL_DATA(cf); \
683 CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
684 } while(0)
685
686#define CF_DATA_RESTORE(cf, save) \
687 do { \
688 CF_CTX_CALL_DATA(cf) = (save); \
689 } while(0)
690
691#endif /* !DEBUGBUILD */
692
693#define CF_DATA_CURRENT(cf) \
694 ((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
695
696#endif /* HEADER_CURL_CFILTERS_H */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette