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