From a1f32ffee540bcef046dc499938585c5da9d0aa8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 11 Nov 2010 14:51:39 +0100 Subject: [PATCH] ip_version: moved to connection struct The IP version choice was previously only in the UserDefined struct within the SessionHandle, but since we sometimes alter that option during a request we need to have it on a per-connection basis. I also moved more "init conn" code into the allocate_conn() function which is designed for that purpose more or less. --- lib/connect.c | 8 +-- lib/hostares.c | 2 +- lib/hostip.c | 2 +- lib/hostip.h | 2 +- lib/hostip4.c | 4 +- lib/hostip6.c | 6 +-- lib/hostthre.c | 2 +- lib/url.c | 137 ++++++++++++++++++++++++++----------------------- lib/urldata.h | 6 ++- 9 files changed, 89 insertions(+), 80 deletions(-) diff --git a/lib/connect.c b/lib/connect.c index e178633d8..88fb7eb76 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -310,20 +310,20 @@ static CURLcode bindlocal(struct connectdata *conn, * of the connection. The resolve functions should really be changed * to take a type parameter instead. */ - long ipver = data->set.ip_version; + long ipver = conn->ip_version; int rc; if (af == AF_INET) - data->set.ip_version = CURL_IPRESOLVE_V4; + conn->ip_version = CURL_IPRESOLVE_V4; #ifdef ENABLE_IPV6 else if (af == AF_INET6) - data->set.ip_version = CURL_IPRESOLVE_V6; + conn->ip_version = CURL_IPRESOLVE_V6; #endif rc = Curl_resolv(conn, dev, 0, &h); if(rc == CURLRESOLV_PENDING) (void)Curl_wait_for_resolv(conn, &h); - data->set.ip_version = ipver; + conn->ip_version = ipver; if(h) { /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */ diff --git a/lib/hostares.c b/lib/hostares.c index 5d54ac1b4..e31a677da 100644 --- a/lib/hostares.c +++ b/lib/hostares.c @@ -378,7 +378,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, return Curl_ip2addr(AF_INET6, &in6, hostname, port); } - switch(data->set.ip_version) { + switch(conn->ip_version) { default: #if ARES_VERSION >= 0x010601 family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older diff --git a/lib/hostip.c b/lib/hostip.c index 8e1494e3f..b5bde96e4 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -444,7 +444,7 @@ int Curl_resolv(struct connectdata *conn, /* Check what IP specifics the app has requested and if we can provide it. * If not, bail out. */ - if(!Curl_ipvalid(data)) + if(!Curl_ipvalid(conn)) return CURLRESOLV_ERROR; /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a diff --git a/lib/hostip.h b/lib/hostip.h index 33e573cdd..2f8d4b56c 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -111,7 +111,7 @@ int Curl_resolv_timeout(struct connectdata *conn, const char *hostname, * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've * been set and returns TRUE if they are OK. */ -bool Curl_ipvalid(struct SessionHandle *data); +bool Curl_ipvalid(struct connectdata *conn); /* * Curl_getaddrinfo() is the generic low-level name resolve API within this diff --git a/lib/hostip4.c b/lib/hostip4.c index 05dd73e0a..6dc525765 100644 --- a/lib/hostip4.c +++ b/lib/hostip4.c @@ -77,9 +77,9 @@ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've * been set and returns TRUE if they are OK. */ -bool Curl_ipvalid(struct SessionHandle *data) +bool Curl_ipvalid(struct connectdata *conn) { - if(data->set.ip_version == CURL_IPRESOLVE_V6) + if(conn->ip_version == CURL_IPRESOLVE_V6) /* an ipv6 address was requested and we can't get/use one */ return FALSE; diff --git a/lib/hostip6.c b/lib/hostip6.c index 7d0a9122f..ca0280790 100644 --- a/lib/hostip6.c +++ b/lib/hostip6.c @@ -112,9 +112,9 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa, * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've * been set and returns TRUE if they are OK. */ -bool Curl_ipvalid(struct SessionHandle *data) +bool Curl_ipvalid(struct connectdata *conn) { - if(data->set.ip_version == CURL_IPRESOLVE_V6) { + if(conn->ip_version == CURL_IPRESOLVE_V6) { /* see if we have an IPv6 stack */ curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0); if(s == CURL_SOCKET_BAD) @@ -174,7 +174,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, /* * Check if a limited name resolve has been requested. */ - switch(data->set.ip_version) { + switch(conn->ip_version) { case CURL_IPRESOLVE_V4: pf = PF_INET; break; diff --git a/lib/hostthre.c b/lib/hostthre.c index e8dfa5400..d45a8993c 100644 --- a/lib/hostthre.c +++ b/lib/hostthre.c @@ -518,7 +518,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, /* * Check if a limited name resolve has been requested. */ - switch(data->set.ip_version) { + switch(conn->ip_version) { case CURL_IPRESOLVE_V4: pf = PF_INET; break; diff --git a/lib/url.c b/lib/url.c index 4a45256d4..fb5122d65 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2196,7 +2196,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; case CURLOPT_IPRESOLVE: - data->set.ip_version = va_arg(param, long); + data->set.ipver = va_arg(param, long); break; case CURLOPT_MAXFILESIZE_LARGE: @@ -3455,14 +3455,19 @@ static void fix_hostname(struct SessionHandle *data, #endif } +static void llist_dtor(void *user, void *element) +{ + (void)user; + (void)element; + /* Do nothing */ +} + /* * Allocate and initialize a new connectdata object. */ -static struct connectdata *allocate_conn(void) +static struct connectdata *allocate_conn(struct SessionHandle *data) { - struct connectdata *conn; - - conn = calloc(1, sizeof(struct connectdata)); + struct connectdata *conn = calloc(1, sizeof(struct connectdata)); if(!conn) return NULL; @@ -3485,7 +3490,66 @@ static struct connectdata *allocate_conn(void) /* Store creation time to help future close decision making */ conn->created = Curl_tvnow(); + conn->data = data; /* Setup the association between this connection + and the SessionHandle */ + + conn->proxytype = data->set.proxytype; /* type */ + +#ifdef CURL_DISABLE_PROXY + + conn->bits.proxy = FALSE; + conn->bits.httpproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; + +#else /* CURL_DISABLE_PROXY */ + + conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY]); + conn->bits.httpproxy = (bool)(conn->bits.proxy && + (conn->proxytype == CURLPROXY_HTTP || + conn->proxytype == CURLPROXY_HTTP_1_0)); + conn->bits.proxy_user_passwd = + (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; + +#endif /* CURL_DISABLE_PROXY */ + + conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; + + conn->verifypeer = data->set.ssl.verifypeer; + conn->verifyhost = data->set.ssl.verifyhost; + + conn->ip_version = data->set.ipver; + + if(data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ + conn->master_buffer = calloc(BUFSIZE, sizeof (char)); + if(!conn->master_buffer) + goto error; + } + + /* Initialize the pipeline lists */ + conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + conn->done_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); + if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe || + !conn->done_pipe) + goto error; + return conn; + error: + Curl_llist_destroy(conn->send_pipe, NULL); + Curl_llist_destroy(conn->recv_pipe, NULL); + Curl_llist_destroy(conn->pend_pipe, NULL); + Curl_llist_destroy(conn->done_pipe, NULL); + Curl_safefree(conn->master_buffer); + Curl_safefree(conn); + return NULL; } static CURLcode findprotocol(struct SessionHandle *data, @@ -3751,13 +3815,6 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, return findprotocol(data, conn, protop); } -static void llist_dtor(void *user, void *element) -{ - (void)user; - (void)element; - /* Do nothing */ -} - /* * If we're doing a resumed transfer, we need to setup our stuff * properly. @@ -4595,66 +4652,16 @@ static CURLcode create_conn(struct SessionHandle *data, parts for checking against the already present connections. In order to not have to modify everything at once, we allocate a temporary connection data struct and fill in for comparison purposes. */ + conn = allocate_conn(data); - conn = allocate_conn(); + if(!conn) + return CURLE_OUT_OF_MEMORY; /* We must set the return variable as soon as possible, so that our parent can cleanup any possible allocs we may have done before any failure */ *in_connect = conn; - if(!conn) - return CURLE_OUT_OF_MEMORY; - - conn->data = data; /* Setup the association between this connection - and the SessionHandle */ - - conn->proxytype = data->set.proxytype; /* type */ - -#ifdef CURL_DISABLE_PROXY - - conn->bits.proxy = FALSE; - conn->bits.httpproxy = FALSE; - conn->bits.proxy_user_passwd = FALSE; - conn->bits.tunnel_proxy = FALSE; - -#else /* CURL_DISABLE_PROXY */ - - conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (bool)(conn->bits.proxy && - (conn->proxytype == CURLPROXY_HTTP || - conn->proxytype == CURLPROXY_HTTP_1_0)); - conn->bits.proxy_user_passwd = - (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]); - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - -#endif /* CURL_DISABLE_PROXY */ - - conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]); - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - - conn->verifypeer = data->set.ssl.verifypeer; - conn->verifyhost = data->set.ssl.verifyhost; - - if(data->multi && Curl_multi_canPipeline(data->multi) && - !conn->master_buffer) { - /* Allocate master_buffer to be used for pipelining */ - conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if(!conn->master_buffer) - return CURLE_OUT_OF_MEMORY; - } - - /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->done_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe || - !conn->done_pipe) - return CURLE_OUT_OF_MEMORY; - /* This initing continues below, see the comment "Continue connectdata * initialization here" */ diff --git a/lib/urldata.h b/lib/urldata.h index 489ab16aa..16f365ae8 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -779,6 +779,8 @@ struct connectdata { const struct Curl_handler * handler; /* Connection's protocol handler. */ + long ip_version; /* copied from the SessionHandle at creation time */ + /**** curl_get() phase fields */ curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ @@ -1355,8 +1357,8 @@ struct UserDefined { struct curl_slist *http200aliases; /* linked list of aliases for http200 */ - long ip_version; /* the CURL_IPRESOLVE_* defines in the public header file - 0 - whatever, 1 - v2, 2 - v6 */ + long ipver; /* the CURL_IPRESOLVE_* defines in the public header file + 0 - whatever, 1 - v2, 2 - v6 */ curl_off_t max_filesize; /* Maximum file size to download */