#ifndef HEADER_CURL_CFILTERS_H
#define HEADER_CURL_CFILTERS_H
#include "curlx/timediff.h"
struct bufq;
struct Curl_cfilter;
struct Curl_easy;
struct Curl_dns_entry;
struct connectdata;
struct ip_quadruple;
struct curl_tlssessioninfo;
typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf,
struct Curl_easy *data);
typedef void Curl_cft_close(struct Curl_cfilter *cf,
struct Curl_easy *data);
typedef CURLcode Curl_cft_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *done);
typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *done);
struct easy_pollset;
typedef CURLcode Curl_cft_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct easy_pollset *ps);
typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data);
typedef CURLcode Curl_cft_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf,
size_t len,
bool eos,
size_t *pnwritten);
typedef CURLcode Curl_cft_recv(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf,
size_t len,
size_t *pnread);
typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *input_pending);
typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
struct Curl_easy *data);
#define CF_CTRL_DATA_SETUP 4
#define CF_CTRL_DATA_PAUSE 6
#define CF_CTRL_DATA_DONE 7
#define CF_CTRL_DATA_DONE_SEND 8
#define CF_CTRL_CONN_INFO_UPDATE (256+0)
#define CF_CTRL_FORGET_SOCKET (256+1)
#define CF_CTRL_FLUSH (256+2)
typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
int event, int arg1, void *arg2);
#define CF_QUERY_MAX_CONCURRENT 1
#define CF_QUERY_CONNECT_REPLY_MS 2
#define CF_QUERY_SOCKET 3
#define CF_QUERY_TIMER_CONNECT 4
#define CF_QUERY_TIMER_APPCONNECT 5
#define CF_QUERY_STREAM_ERROR 6
#define CF_QUERY_NEED_FLUSH 7
#define CF_QUERY_IP_INFO 8
#define CF_QUERY_HTTP_VERSION 9
#define CF_QUERY_REMOTE_ADDR 10
#define CF_QUERY_HOST_PORT 11
#define CF_QUERY_SSL_INFO 12
#define CF_QUERY_SSL_CTX_INFO 13
#define CF_QUERY_TRANSPORT 14
#define CF_QUERY_ALPN_NEGOTIATED 15
typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
struct Curl_easy *data,
int query, int *pres1, void *pres2);
#define CF_TYPE_IP_CONNECT (1 << 0)
#define CF_TYPE_SSL (1 << 1)
#define CF_TYPE_MULTIPLEX (1 << 2)
#define CF_TYPE_PROXY (1 << 3)
#define CF_TYPE_HTTP (1 << 4)
struct Curl_cftype {
const char *name;
int flags;
int log_level;
Curl_cft_destroy_this *destroy;
Curl_cft_connect *do_connect;
Curl_cft_close *do_close;
Curl_cft_shutdown *do_shutdown;
Curl_cft_adjust_pollset *adjust_pollset;
Curl_cft_data_pending *has_data_pending;
Curl_cft_send *do_send;
Curl_cft_recv *do_recv;
Curl_cft_cntrl *cntrl;
Curl_cft_conn_is_alive *is_alive;
Curl_cft_conn_keep_alive *keep_alive;
Curl_cft_query *query;
};
struct Curl_cfilter {
const struct Curl_cftype *cft;
struct Curl_cfilter *next;
void *ctx;
struct connectdata *conn;
int sockindex;
BIT(connected);
BIT(shutdown);
};
void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
struct Curl_easy *data);
CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct easy_pollset *ps);
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data);
CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, bool eos,
size_t *pnwritten);
CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, size_t *pnread);
CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
int event, int arg1, void *arg2);
bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *input_pending);
CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
struct Curl_easy *data);
CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
struct Curl_easy *data,
int query, int *pres1, void *pres2);
CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data, bool *done);
CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
const struct Curl_cftype *cft,
void *ctx);
void Curl_conn_cf_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
struct Curl_cfilter *cf);
void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
struct Curl_cfilter *cf_new);
bool Curl_conn_cf_discard(struct Curl_cfilter **pcf,
struct Curl_easy *data);
void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
struct Curl_easy *data);
void Curl_conn_cf_discard_all(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *done);
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, bool eos,
size_t *pnwritten);
CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, size_t *pnread);
CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool ignore_result,
int event, int arg1, void *arg2);
curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
struct Curl_easy *data);
CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *is_ipv6, struct ip_quadruple *ipquad);
bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf,
struct Curl_easy *data);
unsigned char Curl_conn_cf_get_transport(struct Curl_cfilter *cf,
struct Curl_easy *data);
const char *Curl_conn_cf_get_alpn_negotiated(struct Curl_cfilter *cf,
struct Curl_easy *data);
#define CURL_CF_SSL_DEFAULT -1
#define CURL_CF_SSL_DISABLE 0
#define CURL_CF_SSL_ENABLE 1
CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
bool blocking, bool *done);
bool Curl_conn_is_setup(struct connectdata *conn, int sockindex);
bool Curl_conn_is_connected(struct connectdata *conn, int sockindex);
bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex);
bool Curl_conn_get_ssl_info(struct Curl_easy *data,
struct connectdata *conn, int sockindex,
struct curl_tlssessioninfo *info);
CURLcode Curl_conn_get_ip_info(struct Curl_easy *data,
struct connectdata *conn, int sockindex,
bool *is_ipv6, struct ip_quadruple *ipquad);
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex);
unsigned char Curl_conn_http_version(struct Curl_easy *data,
struct connectdata *conn);
unsigned char Curl_conn_get_transport(struct Curl_easy *data,
struct connectdata *conn);
const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data,
struct connectdata *conn);
void Curl_conn_close(struct Curl_easy *data, int sockindex);
CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done);
bool Curl_conn_data_pending(struct Curl_easy *data,
int sockindex);
bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex);
CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex);
curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data);
const struct Curl_sockaddr_ex *
Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex);
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex);
CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct easy_pollset *ps);
CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data,
struct connectdata *conn,
struct easy_pollset *ps);
int Curl_conn_cf_poll(struct Curl_cfilter *cf,
struct Curl_easy *data,
timediff_t timeout_ms);
CURLcode Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf,
size_t len, size_t *pnread);
CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex,
const void *buf, size_t len, bool eos,
size_t *pnwritten);
CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct bufq *bufq,
size_t maxlen,
size_t *pnread);
CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct bufq *bufq,
const unsigned char *buf, size_t blen,
size_t *pnwritten);
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data);
void Curl_conn_ev_data_done_send(struct Curl_easy *data);
void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature);
CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause);
bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn,
bool *input_pending);
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
#ifdef UNITTESTS
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
#endif
void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
const char **phost, int *pport);
size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
int Curl_conn_get_stream_error(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd);
CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
char *buf, size_t buffersize,
size_t *pnread);
CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
const void *buf, size_t blen, bool eos,
size_t *pnwritten);
struct cf_call_data {
struct Curl_easy *data;
#ifdef DEBUGBUILD
int depth;
#endif
};
#ifdef DEBUGBUILD
#define CF_DATA_SAVE(save, cf, data) \
do { \
(save) = CF_CTX_CALL_DATA(cf); \
DEBUGASSERT((save).data == NULL || (save).depth > 0); \
CF_CTX_CALL_DATA(cf).depth++; \
CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)CURL_UNCONST(data); \
} while(0)
#define CF_DATA_RESTORE(cf, save) \
do { \
DEBUGASSERT(CF_CTX_CALL_DATA(cf).depth == (save).depth + 1); \
DEBUGASSERT((save).data == NULL || (save).depth > 0); \
CF_CTX_CALL_DATA(cf) = (save); \
} while(0)
#else
#define CF_DATA_SAVE(save, cf, data) \
do { \
(save) = CF_CTX_CALL_DATA(cf); \
CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)CURL_UNCONST(data); \
} while(0)
#define CF_DATA_RESTORE(cf, save) \
do { \
CF_CTX_CALL_DATA(cf) = (save); \
} while(0)
#endif
#define CF_DATA_CURRENT(cf) \
((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
#endif