From 317096dd9789a2a5b101d4f3861c137a75d6258e Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Sat, 2 Aug 2025 15:38:12 +0200 Subject: [PATCH] pollset/getsock, increase limit to 16 Let a pollset keep up to 16 sockets, now that IP happy eyeballing can have several connect attempts open. Make the return bits from `getsock()` calls unsigned. This is a stopgap, as even 16 might not be enough when there is HTTPS eyeballing in top of IP eyeballing with many A+AAAA entries that do not respond right away. --- lib/asyn-ares.c | 2 +- lib/asyn-base.c | 11 ++++++----- lib/asyn-thrdd.c | 4 ++-- lib/asyn.h | 8 ++++---- lib/cfilters.c | 12 ++++++------ lib/cfilters.h | 4 ++-- lib/ftp.c | 21 ++++++++++++--------- lib/hostip.c | 4 ++-- lib/hostip.h | 4 ++-- lib/http.c | 6 +++--- lib/http.h | 5 +++-- lib/imap.c | 11 ++++++----- lib/mqtt.c | 11 ++++++----- lib/multi.c | 15 ++++++++++----- lib/multihandle.h | 6 ------ lib/multiif.h | 14 -------------- lib/pingpong.c | 5 +++-- lib/pingpong.h | 5 +++-- lib/pop3.c | 10 ++++++---- lib/rtsp.c | 10 ++++++---- lib/smb.c | 10 ++++++---- lib/smtp.c | 10 ++++++---- lib/tftp.c | 10 ++++++---- lib/transfer.h | 5 +++-- lib/urldata.h | 39 +++++++++++++++++++++++++++++++-------- lib/vssh/libssh.c | 11 ++++++----- lib/vssh/libssh2.c | 11 ++++++----- lib/vssh/wolfssh.c | 12 ++++++------ 28 files changed, 153 insertions(+), 123 deletions(-) diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 007f1d7123..451964ec1c 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -277,7 +277,7 @@ static void async_ares_cleanup(struct Curl_easy *data) * (using curl_multi_fdset()) wants to get our fd_set setup. */ -int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) +unsigned int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) { struct async_ares_ctx *ares = &data->state.async.ares; DEBUGASSERT(ares->channel); diff --git a/lib/asyn-base.c b/lib/asyn-base.c index ea89fba15c..bd4cf99a7d 100644 --- a/lib/asyn-base.c +++ b/lib/asyn-base.c @@ -78,14 +78,15 @@ * Returns: sockets-in-use-bitmap */ -int Curl_ares_getsock(struct Curl_easy *data, - ares_channel channel, - curl_socket_t *socks) +unsigned int Curl_ares_getsock(struct Curl_easy *data, + ares_channel channel, + curl_socket_t *socks) { struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 }; struct timeval timebuf; - int max = ares_getsock(channel, - (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE); + unsigned int max = ares_getsock(channel, + (ares_socket_t *)socks, + MAX_SOCKSPEREASYHANDLE); struct timeval *timeout = ares_timeout(channel, &maxtime, &timebuf); timediff_t milli = curlx_tvtoms(timeout); Curl_expire(data, milli, EXPIRE_ASYNC_NAME); diff --git a/lib/asyn-thrdd.c b/lib/asyn-thrdd.c index 19d1336854..448487db8f 100644 --- a/lib/asyn-thrdd.c +++ b/lib/asyn-thrdd.c @@ -629,10 +629,10 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data, } } -int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) +unsigned int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *socks) { struct async_thrdd_ctx *thrdd = &data->state.async.thrdd; - int ret_val = 0; + unsigned int ret_val = 0; #if !defined(CURL_DISABLE_SOCKETPAIR) || defined(USE_HTTPSRR_ARES) int socketi = 0; #else diff --git a/lib/asyn.h b/lib/asyn.h index a336c1e254..ae9b670ecf 100644 --- a/lib/asyn.h +++ b/lib/asyn.h @@ -78,7 +78,7 @@ CURLcode Curl_async_get_impl(struct Curl_easy *easy, void **impl); * return bitmask indicating what file descriptors (referring to array indexes * in the 'sock' array) to wait for, read/write. */ -int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *sock); +unsigned int Curl_async_getsock(struct Curl_easy *data, curl_socket_t *sock); /* * Curl_async_is_resolved() @@ -127,9 +127,9 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data, /* common functions for c-ares and threaded resolver with HTTPSRR */ #include -int Curl_ares_getsock(struct Curl_easy *data, - ares_channel channel, - curl_socket_t *socks); +unsigned int Curl_ares_getsock(struct Curl_easy *data, + ares_channel channel, + curl_socket_t *socks); int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms); #endif diff --git a/lib/cfilters.c b/lib/cfilters.c index c7333e12b0..424fc98c30 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -1175,10 +1175,10 @@ void Curl_pollset_set(struct Curl_easy *data, } static void ps_add(struct Curl_easy *data, struct easy_pollset *ps, - int bitmap, curl_socket_t *socks) + unsigned int bitmap, curl_socket_t *socks) { if(bitmap) { - int i; + unsigned int i; for(i = 0; i < MAX_SOCKSPEREASYHANDLE; ++i) { if(!(bitmap & GETSOCK_MASK_RW(i)) || !VALID_SOCK((socks[i]))) { break; @@ -1198,13 +1198,13 @@ static void ps_add(struct Curl_easy *data, struct easy_pollset *ps, void Curl_pollset_add_socks(struct Curl_easy *data, struct easy_pollset *ps, - int (*get_socks_cb)(struct Curl_easy *data, - curl_socket_t *socks)) + unsigned int (*socks_cb)(struct Curl_easy *data, + curl_socket_t *socks)) { curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; - int bitmap; + unsigned int bitmap; - bitmap = get_socks_cb(data, socks); + bitmap = socks_cb(data, socks); ps_add(data, ps, bitmap, socks); } diff --git a/lib/cfilters.h b/lib/cfilters.h index 0b6e1044fc..509063e1d8 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -664,8 +664,8 @@ void Curl_pollset_set(struct Curl_easy *data, void Curl_pollset_add_socks(struct Curl_easy *data, struct easy_pollset *ps, - int (*get_socks_cb)(struct Curl_easy *data, - curl_socket_t *socks)); + unsigned int (*socks_cb)(struct Curl_easy *data, + curl_socket_t *socks)); /** * Check if the pollset, as is, wants to read and/or write regarding diff --git a/lib/ftp.c b/lib/ftp.c index 18613ae80e..c71e39f0bc 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -214,10 +214,12 @@ static CURLcode ftp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead_connection); static CURLcode ftp_do_more(struct Curl_easy *data, int *completed); static CURLcode ftp_multi_statemach(struct Curl_easy *data, bool *done); -static int ftp_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); -static int ftp_domore_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static unsigned int ftp_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); +static unsigned int ftp_domore_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); static CURLcode ftp_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode ftp_setup_connection(struct Curl_easy *data, @@ -781,17 +783,18 @@ static CURLcode ftp_state_pwd(struct Curl_easy *data, } /* For the FTP "protocol connect" and "doing" phases only */ -static int ftp_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *socks) +static unsigned int ftp_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); return ftpc ? Curl_pp_getsock(data, &ftpc->pp, socks) : GETSOCK_BLANK; } /* For the FTP "DO_MORE" phase only */ -static int ftp_domore_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static unsigned int ftp_domore_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); (void)data; diff --git a/lib/hostip.c b/lib/hostip.c index 95c2c62242..ae63ab3293 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -1523,8 +1523,8 @@ CURLcode Curl_resolv_check(struct Curl_easy *data, } #endif -int Curl_resolv_getsock(struct Curl_easy *data, - curl_socket_t *socks) +unsigned int Curl_resolv_getsock(struct Curl_easy *data, + curl_socket_t *socks) { #ifdef CURLRES_ASYNCH #ifndef CURL_DISABLE_DOH diff --git a/lib/hostip.h b/lib/hostip.h index 56c5e9cad1..978cd83909 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -199,8 +199,8 @@ CURLcode Curl_resolv_check(struct Curl_easy *data, #else #define Curl_resolv_check(x,y) CURLE_NOT_BUILT_IN #endif -int Curl_resolv_getsock(struct Curl_easy *data, - curl_socket_t *socks); +unsigned int Curl_resolv_getsock(struct Curl_easy *data, + curl_socket_t *socks); CURLcode Curl_resolver_error(struct Curl_easy *data); diff --git a/lib/http.c b/lib/http.c index aa48887723..2fb59356a0 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1524,9 +1524,9 @@ CURLcode Curl_http_connect(struct Curl_easy *data, bool *done) /* this returns the socket to wait for in the DO and DOING state for the multi interface and then we are always _sending_ a request and thus we wait for the single socket to become writable only */ -int Curl_http_getsock_do(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *socks) +unsigned int Curl_http_getsock_do(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { /* write mode */ (void)conn; diff --git a/lib/http.h b/lib/http.h index a7bc2c6537..01068bf6ed 100644 --- a/lib/http.h +++ b/lib/http.h @@ -115,8 +115,9 @@ CURLcode Curl_http_setup_conn(struct Curl_easy *data, CURLcode Curl_http(struct Curl_easy *data, bool *done); CURLcode Curl_http_done(struct Curl_easy *data, CURLcode, bool premature); CURLcode Curl_http_connect(struct Curl_easy *data, bool *done); -int Curl_http_getsock_do(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +unsigned int Curl_http_getsock_do(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); CURLcode Curl_http_write_resp(struct Curl_easy *data, const char *buf, size_t blen, bool is_eos); diff --git a/lib/imap.c b/lib/imap.c index f25176bb9e..2c9d06676d 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -157,8 +157,9 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done); static CURLcode imap_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done); -static int imap_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +static unsigned int imap_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode imap_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -1560,9 +1561,9 @@ static CURLcode imap_block_statemach(struct Curl_easy *data, } /* For the IMAP "protocol connect" and "doing" phases only */ -static int imap_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *socks) +static unsigned int imap_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); return imapc ? diff --git a/lib/mqtt.c b/lib/mqtt.c index 90f857dca5..0b737135e1 100644 --- a/lib/mqtt.c +++ b/lib/mqtt.c @@ -107,8 +107,9 @@ static CURLcode mqtt_do(struct Curl_easy *data, bool *done); static CURLcode mqtt_done(struct Curl_easy *data, CURLcode status, bool premature); static CURLcode mqtt_doing(struct Curl_easy *data, bool *done); -static int mqtt_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *sock); +static unsigned int mqtt_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock); static CURLcode mqtt_setup_conn(struct Curl_easy *data, struct connectdata *conn); @@ -213,9 +214,9 @@ static CURLcode mqtt_send(struct Curl_easy *data, /* Generic function called by the multi interface to figure out what socket(s) to wait for and for what actions during the DOING and PROTOCONNECT states */ -static int mqtt_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static unsigned int mqtt_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock) { (void)data; sock[0] = conn->sock[FIRSTSOCKET]; diff --git a/lib/multi.c b/lib/multi.c index 194cf75d40..8fb9410124 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -907,7 +907,8 @@ void Curl_attach_connection(struct Curl_easy *data, conn->handler->attach(data, conn); } -static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks) +static unsigned int connecting_getsock(struct Curl_easy *data, + curl_socket_t *socks) { struct connectdata *conn = data->conn; curl_socket_t sockfd; @@ -923,7 +924,8 @@ static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks) return GETSOCK_BLANK; } -static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks) +static unsigned int protocol_getsock(struct Curl_easy *data, + curl_socket_t *socks) { struct connectdata *conn = data->conn; curl_socket_t sockfd; @@ -941,7 +943,8 @@ static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks) return GETSOCK_BLANK; } -static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks) +static unsigned int domore_getsock(struct Curl_easy *data, + curl_socket_t *socks) { struct connectdata *conn = data->conn; if(!conn) @@ -956,7 +959,8 @@ static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks) return GETSOCK_BLANK; } -static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks) +static unsigned int doing_getsock(struct Curl_easy *data, + curl_socket_t *socks) { struct connectdata *conn = data->conn; if(!conn) @@ -971,7 +975,8 @@ static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks) return GETSOCK_BLANK; } -static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock) +static unsigned int perform_getsock(struct Curl_easy *data, + curl_socket_t *sock) { struct connectdata *conn = data->conn; if(!conn) diff --git a/lib/multihandle.h b/lib/multihandle.h index dbad164bc5..cdedfb08ab 100644 --- a/lib/multihandle.h +++ b/lib/multihandle.h @@ -72,12 +72,6 @@ typedef enum { MSTATE_LAST /* 18 - not a true state, never use this */ } CURLMstate; -/* we support N sockets per easy handle. Set the corresponding bit to what - action we should wait for */ -#define MAX_SOCKSPEREASYHANDLE 5 -#define GETSOCK_READABLE (0x00ff) -#define GETSOCK_WRITABLE (0xff00) - #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) #ifndef CURL_DISABLE_SOCKETPAIR diff --git a/lib/multiif.h b/lib/multiif.h index 1ba0d0f838..221de04721 100644 --- a/lib/multiif.h +++ b/lib/multiif.h @@ -53,20 +53,6 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size, size_t dnssize, size_t sesssize); -/* the write bits start at bit 16 for the *getsock() bitmap */ -#define GETSOCK_WRITEBITSTART 16 - -#define GETSOCK_BLANK 0 /* no bits set */ - -/* set the bit for the given sock number to make the bitmap for writable */ -#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x))) - -/* set the bit for the given sock number to make the bitmap for readable */ -#define GETSOCK_READSOCK(x) (1 << (x)) - -/* mask for checking if read and/or write is set for index x */ -#define GETSOCK_MASK_RW(x) (GETSOCK_READSOCK(x)|GETSOCK_WRITESOCK(x)) - /** * Let the multi handle know that the socket is about to be closed. * The multi will then remove anything it knows about the socket, so diff --git a/lib/pingpong.c b/lib/pingpong.c index a661a0285b..c86cd7f619 100644 --- a/lib/pingpong.c +++ b/lib/pingpong.c @@ -397,8 +397,9 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, return result; } -int Curl_pp_getsock(struct Curl_easy *data, - struct pingpong *pp, curl_socket_t *socks) +unsigned int Curl_pp_getsock(struct Curl_easy *data, + struct pingpong *pp, + curl_socket_t *socks) { struct connectdata *conn = data->conn; socks[0] = conn->sock[FIRSTSOCKET]; diff --git a/lib/pingpong.h b/lib/pingpong.h index c6d0a56f0d..7cf60c4781 100644 --- a/lib/pingpong.h +++ b/lib/pingpong.h @@ -147,8 +147,9 @@ CURLcode Curl_pp_flushsend(struct Curl_easy *data, /* call this when a pingpong connection is disconnected */ CURLcode Curl_pp_disconnect(struct pingpong *pp); -int Curl_pp_getsock(struct Curl_easy *data, struct pingpong *pp, - curl_socket_t *socks); +unsigned int Curl_pp_getsock(struct Curl_easy *data, + struct pingpong *pp, + curl_socket_t *socks); /*********************************************************************** diff --git a/lib/pop3.c b/lib/pop3.c index 514c4b8fa5..c37cf15e2d 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -153,8 +153,9 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done); static CURLcode pop3_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done); -static int pop3_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static unsigned int pop3_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode pop3_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -1269,8 +1270,9 @@ static CURLcode pop3_block_statemach(struct Curl_easy *data, } /* For the POP3 "protocol connect" and "doing" phases only */ -static int pop3_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static unsigned int pop3_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); if(pop3c) diff --git a/lib/rtsp.c b/lib/rtsp.c index d50624158e..91ccc4ed0b 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -83,8 +83,9 @@ struct RTSP { static CURLcode rtsp_do(struct Curl_easy *data, bool *done); static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature); static CURLcode rtsp_connect(struct Curl_easy *data, bool *done); -static int rtsp_getsock_do(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static unsigned int rtsp_getsock_do(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); /* * Parse and write out an RTSP response. @@ -110,8 +111,9 @@ static unsigned int rtsp_conncheck(struct Curl_easy *data, /* this returns the socket to wait for in the DO and DOING state for the multi interface and then we are always _sending_ a request and thus we wait for the single socket to become writable only */ -static int rtsp_getsock_do(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks) +static unsigned int rtsp_getsock_do(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { /* write mode */ (void)data; diff --git a/lib/smb.c b/lib/smb.c index d6ef8f6f1d..f5235102b9 100644 --- a/lib/smb.c +++ b/lib/smb.c @@ -298,8 +298,9 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done); static CURLcode smb_connection_state(struct Curl_easy *data, bool *done); static CURLcode smb_do(struct Curl_easy *data, bool *done); static CURLcode smb_request_state(struct Curl_easy *data, bool *done); -static int smb_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +static unsigned int smb_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); static CURLcode smb_parse_url_path(struct Curl_easy *data, struct smb_conn *smbc, struct smb_request *req); @@ -1204,8 +1205,9 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done) return CURLE_OK; } -static int smb_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static unsigned int smb_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { (void)data; socks[0] = conn->sock[FIRSTSOCKET]; diff --git a/lib/smtp.c b/lib/smtp.c index 13b89b6ecc..4ba5d14171 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -157,8 +157,9 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done); static CURLcode smtp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done); -static int smtp_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +static unsigned int smtp_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done); static CURLcode smtp_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -1413,8 +1414,9 @@ static CURLcode smtp_block_statemach(struct Curl_easy *data, } /* For the SMTP "protocol connect" and "doing" phases only */ -static int smtp_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static unsigned int smtp_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { struct smtp_conn *smtpc = Curl_conn_meta_get(conn, CURL_META_SMTP_CONN); return smtpc ? diff --git a/lib/tftp.c b/lib/tftp.c index 5ea986dbb4..6412360ca4 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -160,8 +160,9 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data, struct connectdata *conn); static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done); static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done); -static int tftp_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *socks); +static unsigned int tftp_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); static CURLcode tftp_translate_code(tftp_error_t error); @@ -1081,8 +1082,9 @@ static CURLcode tftp_done(struct Curl_easy *data, CURLcode status, * The getsock callback * **********************************************************/ -static int tftp_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks) +static unsigned int tftp_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks) { (void)data; socks[0] = conn->sock[FIRSTSOCKET]; diff --git a/lib/transfer.h b/lib/transfer.h index 92278226be..8f1fe96a60 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -34,8 +34,9 @@ void Curl_init_CONNECT(struct Curl_easy *data); CURLcode Curl_pretransfer(struct Curl_easy *data); CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp); -int Curl_single_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); +unsigned int Curl_single_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); CURLcode Curl_retry_request(struct Curl_easy *data, char **url); bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc); diff --git a/lib/urldata.h b/lib/urldata.h index 2ae52840f5..dcc76d222f 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -471,6 +471,25 @@ struct hostname { #define FIRSTSOCKET 0 #define SECONDARYSOCKET 1 +/* we support N sockets per easy handle. Set the corresponding bit to what + action we should wait for */ +#define MAX_SOCKSPEREASYHANDLE 16 + +/* the write bits start at bit 16 for the *getsock() bitmap */ +#define GETSOCK_WRITEBITSTART 16 + +#define GETSOCK_BLANK 0U /* no bits set */ + +/* set the bit for the given sock number to make the bitmap for writable */ +#define GETSOCK_WRITESOCK(x) (1U << (GETSOCK_WRITEBITSTART + (x))) + +/* set the bit for the given sock number to make the bitmap for readable */ +#define GETSOCK_READSOCK(x) (1U << (x)) + +/* mask for checking if read and/or write is set for index x */ +#define GETSOCK_MASK_RW(x) (GETSOCK_READSOCK(x)|GETSOCK_WRITESOCK(x)) + + /* Polling requested by an easy handle. * `action` is CURL_POLL_IN, CURL_POLL_OUT or CURL_POLL_INOUT. */ @@ -516,24 +535,28 @@ struct Curl_handler { /* Called from the multi interface during the PROTOCONNECT phase, and it should then return a proper fd set */ - int (*proto_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + unsigned int (*proto_getsock)(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); /* Called from the multi interface during the DOING phase, and it should then return a proper fd set */ - int (*doing_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + unsigned int (*doing_getsock)(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); /* Called from the multi interface during the DO_MORE phase, and it should then return a proper fd set */ - int (*domore_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + unsigned int (*domore_getsock)(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); /* Called from the multi interface during the DO_DONE, PERFORM and WAITPERFORM phases, and it should then return a proper fd set. Not setting this will make libcurl use the generic default one. */ - int (*perform_getsock)(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *socks); + unsigned int (*perform_getsock)(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *socks); /* This function *MAY* be set to a protocol-dependent function that is run * by the curl_disconnect(), as a step in the disconnection. If the handler diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index d9c37f9db5..8cc976e0b2 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -125,8 +125,9 @@ CURLcode sftp_perform(struct Curl_easy *data, bool *connected, bool *dophase_done); -static int myssh_getsock(struct Curl_easy *data, - struct connectdata *conn, curl_socket_t *sock); +static unsigned int myssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock); static void myssh_block2waitfor(struct connectdata *conn, struct ssh_conn *sshc, bool block); @@ -2390,9 +2391,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, /* called by the multi interface to figure out what socket(s) to wait for and for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int myssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static unsigned int myssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock) { int bitmap = GETSOCK_BLANK; (void)data; diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index ab57dd87f5..07a87b5c79 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -99,8 +99,9 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); static CURLcode sftp_perform(struct Curl_easy *data, bool *connected, bool *dophase_done); -static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t *sock); +static unsigned int ssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock); static CURLcode ssh_setup_connection(struct Curl_easy *data, struct connectdata *conn); static void ssh_attach(struct Curl_easy *data, struct connectdata *conn); @@ -3087,9 +3088,9 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, /* called by the multi interface to figure out what socket(s) to wait for and for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int ssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static unsigned int ssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock) { int bitmap = GETSOCK_BLANK; (void)data; diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index eed73fd919..0555a1af70 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -66,9 +66,9 @@ static CURLcode wsftp_doing(struct Curl_easy *data, static CURLcode wsftp_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead); -static int wssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock); +static unsigned int wssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock); static CURLcode wssh_setup_connection(struct Curl_easy *data, struct connectdata *conn); static void wssh_sshc_cleanup(struct ssh_conn *sshc); @@ -1185,9 +1185,9 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data, return result; } -static int wssh_getsock(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t *sock) +static unsigned int wssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock) { int bitmap = GETSOCK_BLANK; int dir = conn->waitfor;