From 5050edb12484551f4c666212409c117cf38f9784 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Sep 2019 23:22:15 +0200 Subject: cleanup: move functions out of url.c and make them static Closes #4289 --- lib/connect.c | 55 +++++++++++++++- lib/easy.c | 31 ++++++++- lib/multi.c | 150 +++++++++++++++++++++++++++++++++++++++---- lib/url.c | 203 ---------------------------------------------------------- lib/url.h | 10 --- 5 files changed, 220 insertions(+), 229 deletions(-) diff --git a/lib/connect.c b/lib/connect.c index 79b8094e7..77196250d 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -76,6 +76,7 @@ #include "multihandle.h" #include "system_win32.h" #include "quic.h" +#include "socks.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -744,6 +745,58 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) Curl_persistconninfo(conn); } +/* after a TCP connection to the proxy has been verified, this function does + the next magic step. + + Note: this function's sub-functions call failf() + +*/ +static CURLcode connected_proxy(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + + if(conn->bits.socksproxy) { +#ifndef CURL_DISABLE_PROXY + /* for the secondary socket (FTP), use the "connect to host" + * but ignore the "connect to port" (use the secondary port) + */ + const char * const host = conn->bits.httpproxy ? + conn->http_proxy.host.name : + conn->bits.conn_to_host ? + conn->conn_to_host.name : + sockindex == SECONDARYSOCKET ? + conn->secondaryhostname : conn->host.name; + const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port : + sockindex == SECONDARYSOCKET ? conn->secondary_port : + conn->bits.conn_to_port ? conn->conn_to_port : + conn->remote_port; + conn->bits.socksproxy_connecting = TRUE; + switch(conn->socks_proxy.proxytype) { + case CURLPROXY_SOCKS5: + case CURLPROXY_SOCKS5_HOSTNAME: + result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd, + host, port, sockindex, conn); + break; + + case CURLPROXY_SOCKS4: + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex, + conn); + break; + + default: + failf(conn->data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + } /* switch proxytype */ + conn->bits.socksproxy_connecting = FALSE; +#else + (void)sockindex; +#endif /* CURL_DISABLE_PROXY */ + } + + return result; +} + /* * Curl_is_connected() checks if the socket has connected. */ @@ -848,7 +901,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, } /* see if we need to do any proxy magic first once we connected */ - result = Curl_connected_proxy(conn, sockindex); + result = connected_proxy(conn, sockindex); if(result) return result; diff --git a/lib/easy.c b/lib/easy.c index 1d49a0366..0b0016be4 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1124,6 +1124,35 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, return result; } +/* + * Wrapper to call functions in Curl_conncache_foreach() + * + * Returns always 0. + */ +static int conn_upkeep(struct connectdata *conn, + void *param) +{ + /* Param is unused. */ + (void)param; + + if(conn->handler->connection_check) { + /* Do a protocol-specific keepalive check on the connection. */ + conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE); + } + + return 0; /* continue iteration */ +} + +static CURLcode upkeep(struct conncache *conn_cache, void *data) +{ + /* Loop over every connection and make connection alive. */ + Curl_conncache_foreach(data, + conn_cache, + data, + conn_upkeep); + return CURLE_OK; +} + /* * Performs connection upkeep for the given session handle. */ @@ -1135,7 +1164,7 @@ CURLcode curl_easy_upkeep(struct Curl_easy *data) if(data->multi_easy) { /* Use the common function to keep connections alive. */ - return Curl_upkeep(&data->multi_easy->conn_cache, data); + return upkeep(&data->multi_easy->conn_cache, data); } else { /* No connections, so just return success */ diff --git a/lib/multi.c b/lib/multi.c index 37c4e55a5..2e91e4ff3 100755 --- a/lib/multi.c +++ b/lib/multi.c @@ -866,6 +866,26 @@ static int domore_getsock(struct connectdata *conn, return GETSOCK_BLANK; } +static int doing_getsock(struct connectdata *conn, + curl_socket_t *socks) +{ + if(conn && conn->handler->doing_getsock) + return conn->handler->doing_getsock(conn, socks); + return GETSOCK_BLANK; +} + +static int protocol_getsock(struct connectdata *conn, + curl_socket_t *socks) +{ + if(conn->handler->proto_getsock) + return conn->handler->proto_getsock(conn, socks); + /* Backup getsock logic. Since there is a live socket in use, we must wait + for it or it will be removed from watching when the multi_socket API is + used. */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); +} + /* returns bitmapped flags for this handle and its sockets. The 'socks[]' array contains MAX_SOCKSPEREASYHANDLE entries. */ static int multi_getsock(struct Curl_easy *data, @@ -905,11 +925,11 @@ static int multi_getsock(struct Curl_easy *data, case CURLM_STATE_PROTOCONNECT: case CURLM_STATE_SENDPROTOCONNECT: - return Curl_protocol_getsock(data->conn, socks); + return protocol_getsock(data->conn, socks); case CURLM_STATE_DO: case CURLM_STATE_DOING: - return Curl_doing_getsock(data->conn, socks); + return doing_getsock(data->conn, socks); case CURLM_STATE_WAITPROXYCONNECT: return waitproxyconnect_getsock(data->conn, socks); @@ -1259,6 +1279,109 @@ static CURLcode multi_do_more(struct connectdata *conn, int *complete) return result; } +/* + * We are doing protocol-specific connecting and this is being called over and + * over from the multi interface until the connection phase is done on + * protocol layer. + */ + +static CURLcode protocol_connecting(struct connectdata *conn, + bool *done) +{ + CURLcode result = CURLE_OK; + + if(conn && conn->handler->connecting) { + *done = FALSE; + result = conn->handler->connecting(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We are DOING this is being called over and over from the multi interface + * until the DOING phase is done on protocol layer. + */ + +static CURLcode protocol_doing(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + + if(conn && conn->handler->doing) { + *done = FALSE; + result = conn->handler->doing(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We have discovered that the TCP connection has been successful, we can now + * proceed with some action. + * + */ +static CURLcode protocol_connect(struct connectdata *conn, + bool *protocol_done) +{ + CURLcode result = CURLE_OK; + + DEBUGASSERT(conn); + DEBUGASSERT(protocol_done); + + *protocol_done = FALSE; + + if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { + /* We already are connected, get back. This may happen when the connect + worked fine in the first call, like when we connect to a local server + or proxy. Note that we don't know if the protocol is actually done. + + Unless this protocol doesn't have any protocol-connect callback, as + then we know we're done. */ + if(!conn->handler->connecting) + *protocol_done = TRUE; + + return CURLE_OK; + } + + if(!conn->bits.protoconnstart) { + + result = Curl_proxy_connect(conn, FIRSTSOCKET); + if(result) + return result; + + if(CONNECT_FIRSTSOCKET_PROXY_SSL()) + /* wait for HTTPS proxy SSL initialization to complete */ + return CURLE_OK; + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy && + Curl_connect_ongoing(conn)) + /* when using an HTTP tunnel proxy, await complete tunnel establishment + before proceeding further. Return CURLE_OK so we'll be called again */ + return CURLE_OK; + + if(conn->handler->connect_it) { + /* is there a protocol-specific connect() procedure? */ + + /* Call the protocol-specific connect function */ + result = conn->handler->connect_it(conn, protocol_done); + } + else + *protocol_done = TRUE; + + /* it has started, possibly even completed but that knowledge isn't stored + in this bit! */ + if(!result) + conn->bits.protoconnstart = TRUE; + } + + return result; /* pass back status */ +} + + static CURLMcode multi_runsingle(struct Curl_multi *multi, struct curltime now, struct Curl_easy *data) @@ -1266,7 +1389,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct Curl_message *msg = NULL; bool connected; bool async; - bool protocol_connect = FALSE; + bool protocol_connected = FALSE; bool dophase_done = FALSE; bool done = FALSE; CURLMcode rc; @@ -1385,7 +1508,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(data->set.connecttimeout) Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT); - result = Curl_connect(data, &async, &protocol_connect); + result = Curl_connect(data, &async, &protocol_connected); if(CURLE_NO_CONNECTION_AVAILABLE == result) { /* There was no connection available. We will go to the pending state and wait for an available connection. */ @@ -1413,7 +1536,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, WAITDO or DO! */ rc = CURLM_CALL_MULTI_PERFORM; - if(protocol_connect) + if(protocol_connected) multistate(data, CURLM_STATE_DO); else { #ifndef CURL_DISABLE_HTTP @@ -1468,7 +1591,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(dns) { /* Perform the next step in the connection phase, and then move on to the WAITCONNECT state */ - result = Curl_once_resolved(data->conn, &protocol_connect); + result = Curl_once_resolved(data->conn, &protocol_connected); if(result) /* if Curl_once_resolved() returns failure, the connection struct @@ -1477,7 +1600,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* call again please so that we get the next socket setup */ rc = CURLM_CALL_MULTI_PERFORM; - if(protocol_connect) + if(protocol_connected) multistate(data, CURLM_STATE_DO); else { #ifndef CURL_DISABLE_HTTP @@ -1502,7 +1625,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_WAITPROXYCONNECT: /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ DEBUGASSERT(data->conn); - result = Curl_http_connect(data->conn, &protocol_connect); + result = Curl_http_connect(data->conn, &protocol_connected); if(data->conn->bits.proxy_connect_closed) { rc = CURLM_CALL_MULTI_PERFORM; @@ -1553,8 +1676,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, break; case CURLM_STATE_SENDPROTOCONNECT: - result = Curl_protocol_connect(data->conn, &protocol_connect); - if(!result && !protocol_connect) + result = protocol_connect(data->conn, &protocol_connected); + if(!result && !protocol_connected) /* switch to waiting state */ multistate(data, CURLM_STATE_PROTOCONNECT); else if(!result) { @@ -1572,8 +1695,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_PROTOCONNECT: /* protocol-specific connect phase */ - result = Curl_protocol_connecting(data->conn, &protocol_connect); - if(!result && protocol_connect) { + result = protocol_connecting(data->conn, &protocol_connected); + if(!result && protocol_connected) { /* after the connect has completed, go WAITDO or DO */ multistate(data, CURLM_STATE_DO); rc = CURLM_CALL_MULTI_PERFORM; @@ -1695,8 +1818,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_DOING: /* we continue DOING until the DO phase is complete */ DEBUGASSERT(data->conn); - result = Curl_protocol_doing(data->conn, - &dophase_done); + result = protocol_doing(data->conn, &dophase_done); if(!result) { if(dophase_done) { /* after DO, go DO_DONE or DO_MORE */ diff --git a/lib/url.c b/lib/url.c index 437b5d85c..b7cf7bedd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -112,7 +112,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "connect.h" #include "inet_ntop.h" #include "http_ntlm.h" -#include "socks.h" #include "curl_rtmp.h" #include "gopher.h" #include "http_proxy.h" @@ -1373,58 +1372,6 @@ ConnectionExists(struct Curl_easy *data, return FALSE; /* no matching connecting exists */ } -/* after a TCP connection to the proxy has been verified, this function does - the next magic step. - - Note: this function's sub-functions call failf() - -*/ -CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex) -{ - CURLcode result = CURLE_OK; - - if(conn->bits.socksproxy) { -#ifndef CURL_DISABLE_PROXY - /* for the secondary socket (FTP), use the "connect to host" - * but ignore the "connect to port" (use the secondary port) - */ - const char * const host = conn->bits.httpproxy ? - conn->http_proxy.host.name : - conn->bits.conn_to_host ? - conn->conn_to_host.name : - sockindex == SECONDARYSOCKET ? - conn->secondaryhostname : conn->host.name; - const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port : - sockindex == SECONDARYSOCKET ? conn->secondary_port : - conn->bits.conn_to_port ? conn->conn_to_port : - conn->remote_port; - conn->bits.socksproxy_connecting = TRUE; - switch(conn->socks_proxy.proxytype) { - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd, - host, port, sockindex, conn); - break; - - case CURLPROXY_SOCKS4: - case CURLPROXY_SOCKS4A: - result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex, - conn); - break; - - default: - failf(conn->data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - } /* switch proxytype */ - conn->bits.socksproxy_connecting = FALSE; -#else - (void)sockindex; -#endif /* CURL_DISABLE_PROXY */ - } - - return result; -} - /* * verboseconnect() displays verbose information after a connect */ @@ -1441,125 +1388,6 @@ void Curl_verboseconnect(struct connectdata *conn) } #endif -int Curl_protocol_getsock(struct connectdata *conn, - curl_socket_t *socks) -{ - if(conn->handler->proto_getsock) - return conn->handler->proto_getsock(conn, socks); - /* Backup getsock logic. Since there is a live socket in use, we must wait - for it or it will be removed from watching when the multi_socket API is - used. */ - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); -} - -int Curl_doing_getsock(struct connectdata *conn, - curl_socket_t *socks) -{ - if(conn && conn->handler->doing_getsock) - return conn->handler->doing_getsock(conn, socks); - return GETSOCK_BLANK; -} - -/* - * We are doing protocol-specific connecting and this is being called over and - * over from the multi interface until the connection phase is done on - * protocol layer. - */ - -CURLcode Curl_protocol_connecting(struct connectdata *conn, - bool *done) -{ - CURLcode result = CURLE_OK; - - if(conn && conn->handler->connecting) { - *done = FALSE; - result = conn->handler->connecting(conn, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We are DOING this is being called over and over from the multi interface - * until the DOING phase is done on protocol layer. - */ - -CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - - if(conn && conn->handler->doing) { - *done = FALSE; - result = conn->handler->doing(conn, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We have discovered that the TCP connection has been successful, we can now - * proceed with some action. - * - */ -CURLcode Curl_protocol_connect(struct connectdata *conn, - bool *protocol_done) -{ - CURLcode result = CURLE_OK; - - *protocol_done = FALSE; - - if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { - /* We already are connected, get back. This may happen when the connect - worked fine in the first call, like when we connect to a local server - or proxy. Note that we don't know if the protocol is actually done. - - Unless this protocol doesn't have any protocol-connect callback, as - then we know we're done. */ - if(!conn->handler->connecting) - *protocol_done = TRUE; - - return CURLE_OK; - } - - if(!conn->bits.protoconnstart) { - - result = Curl_proxy_connect(conn, FIRSTSOCKET); - if(result) - return result; - - if(CONNECT_FIRSTSOCKET_PROXY_SSL()) - /* wait for HTTPS proxy SSL initialization to complete */ - return CURLE_OK; - - if(conn->bits.tunnel_proxy && conn->bits.httpproxy && - Curl_connect_ongoing(conn)) - /* when using an HTTP tunnel proxy, await complete tunnel establishment - before proceeding further. Return CURLE_OK so we'll be called again */ - return CURLE_OK; - - if(conn->handler->connect_it) { - /* is there a protocol-specific connect() procedure? */ - - /* Call the protocol-specific connect function */ - result = conn->handler->connect_it(conn, protocol_done); - } - else - *protocol_done = TRUE; - - /* it has started, possibly even completed but that knowledge isn't stored - in this bit! */ - if(!result) - conn->bits.protoconnstart = TRUE; - } - - return result; /* pass back status */ -} - /* * Helpers for IDNA conversions. */ @@ -4208,34 +4036,3 @@ static unsigned int get_protocol_family(unsigned int protocol) return family; } - - -/* - * Wrapper to call functions in Curl_conncache_foreach() - * - * Returns always 0. - */ -static int conn_upkeep(struct connectdata *conn, - void *param) -{ - /* Param is unused. */ - (void)param; - - if(conn->handler->connection_check) { - /* Do a protocol-specific keepalive check on the connection. */ - conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE); - } - - return 0; /* continue iteration */ -} - -CURLcode Curl_upkeep(struct conncache *conn_cache, - void *data) -{ - /* Loop over every connection and make connection alive. */ - Curl_conncache_foreach(data, - conn_cache, - data, - conn_upkeep); - return CURLE_OK; -} diff --git a/lib/url.h b/lib/url.h index 4c739b008..f4d611add 100644 --- a/lib/url.h +++ b/lib/url.h @@ -53,20 +53,12 @@ CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */ CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect); CURLcode Curl_disconnect(struct Curl_easy *data, struct connectdata *, bool dead_connection); -CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done); -CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); -CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done); CURLcode Curl_setup_conn(struct connectdata *conn, bool *protocol_done); void Curl_free_request_state(struct Curl_easy *data); - -int Curl_protocol_getsock(struct connectdata *conn, - curl_socket_t *socks); -int Curl_doing_getsock(struct connectdata *conn, curl_socket_t *socks); CURLcode Curl_parse_login_details(const char *login, const size_t len, char **userptr, char **passwdptr, char **optionsptr); -CURLcode Curl_upkeep(struct conncache *conn_cache, void *data); const struct Curl_handler *Curl_builtin_scheme(const char *scheme); @@ -74,8 +66,6 @@ const struct Curl_handler *Curl_builtin_scheme(const char *scheme); #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless specified */ -CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex); - #ifdef CURL_DISABLE_VERBOSE_STRINGS #define Curl_verboseconnect(x) Curl_nop_stmt #else -- cgit v1.2.3