diff options
author | Haibo Huang <hhb@google.com> | 2019-06-05 01:34:44 -0700 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2019-06-05 10:21:22 -0700 |
commit | b6336c15baf89d415956ffa6ba0153aad8f3c8a4 (patch) | |
tree | bdad9030ac485f3457b117b0ae00204c72565261 /lib | |
parent | 4ca25ace8f2f755ad868b137c04bc7bcefe14518 (diff) | |
download | external_curl-b6336c15baf89d415956ffa6ba0153aad8f3c8a4.tar.gz external_curl-b6336c15baf89d415956ffa6ba0153aad8f3c8a4.tar.bz2 external_curl-b6336c15baf89d415956ffa6ba0153aad8f3c8a4.zip |
Upgrade curl to curl-7_65_1
Test: None
Change-Id: Ida7e08ab7a97c60c9687f3a225ff826d14281d6b
Diffstat (limited to 'lib')
-rw-r--r-- | lib/config-win32.h | 16 | ||||
-rw-r--r-- | lib/conncache.c | 31 | ||||
-rw-r--r-- | lib/conncache.h | 3 | ||||
-rw-r--r-- | lib/curl_config.h | 3 | ||||
-rw-r--r-- | lib/curl_config.h.cmake | 26 | ||||
-rw-r--r-- | lib/curl_config.h.in | 3 | ||||
-rw-r--r-- | lib/curl_setup.h | 2 | ||||
-rw-r--r-- | lib/http.c | 18 | ||||
-rw-r--r-- | lib/http2.c | 7 | ||||
-rw-r--r-- | lib/http_proxy.c | 1 | ||||
-rw-r--r-- | lib/libcurl.plist | 6 | ||||
-rw-r--r-- | lib/md4.c | 7 | ||||
-rw-r--r-- | lib/multi.c | 46 | ||||
-rw-r--r-- | lib/progress.c | 110 | ||||
-rw-r--r-- | lib/rand.c | 5 | ||||
-rw-r--r-- | lib/rand.h | 5 | ||||
-rw-r--r-- | lib/system_win32.c | 36 | ||||
-rw-r--r-- | lib/system_win32.h | 13 | ||||
-rw-r--r-- | lib/url.c | 97 | ||||
-rw-r--r-- | lib/urldata.h | 10 | ||||
-rw-r--r-- | lib/vtls/nss.c | 5 | ||||
-rw-r--r-- | lib/vtls/sectransp.c | 27 |
22 files changed, 283 insertions, 194 deletions
diff --git a/lib/config-win32.h b/lib/config-win32.h index 24c35d33..90c10547 100644 --- a/lib/config-win32.h +++ b/lib/config-win32.h @@ -188,6 +188,9 @@ /* Define to 1 if you have the `getpeername' function. */ #define HAVE_GETPEERNAME 1 +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + /* Define if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 @@ -582,8 +585,9 @@ Vista # endif #endif -/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is - quite convoluted, compiler dependent and even build target dependent. */ +/* Availability of freeaddrinfo, getaddrinfo, getnameinfo and if_nametoindex + functions is quite convoluted, compiler dependent and even build target + dependent. */ #if defined(HAVE_WS2TCPIP_H) # if defined(__POCC__) # define HAVE_FREEADDRINFO 1 @@ -713,8 +717,12 @@ Vista #define USE_WIN32_CRYPTO /* Define to use Unix sockets. */ -#if defined(_MSC_VER) && _MSC_VER >= 1900 -/* #define USE_UNIX_SOCKETS */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) +/* sdkddkver.h first shipped with Platform SDK v6.0A included with VS2008 */ +#include <sdkddkver.h> +#if defined(NTDDI_WIN10_RS4) +#define USE_UNIX_SOCKETS +#endif #endif /* ---------------------------------------------------------------- */ diff --git a/lib/conncache.c b/lib/conncache.c index 53509199..2f4dd4bc 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -61,6 +61,8 @@ Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) #endif +#define HASHKEY_SIZE 128 + static void conn_llist_dtor(void *user, void *element) { struct connectdata *conn = element; @@ -159,23 +161,27 @@ void Curl_conncache_destroy(struct conncache *connc) /* creates a key to find a bundle for this connection */ static void hashkey(struct connectdata *conn, char *buf, - size_t len) /* something like 128 is fine */ + size_t len, /* something like 128 is fine */ + const char **hostp) { const char *hostname; + long port = conn->remote_port; - if(conn->bits.socksproxy) - hostname = conn->socks_proxy.host.name; - else if(conn->bits.httpproxy) + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { hostname = conn->http_proxy.host.name; + port = conn->port; + } else if(conn->bits.conn_to_host) hostname = conn->conn_to_host.name; else hostname = conn->host.name; - DEBUGASSERT(len > 32); + if(hostp) + /* report back which name we used */ + *hostp = hostname; /* put the number first so that the hostname gets cut off if too long */ - msnprintf(buf, len, "%ld%s", conn->port, hostname); + msnprintf(buf, len, "%ld%s", port, hostname); } void Curl_conncache_unlock(struct Curl_easy *data) @@ -212,13 +218,14 @@ size_t Curl_conncache_bundle_size(struct connectdata *conn) **NOTE**: When it returns, it holds the connection cache lock! */ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc) + struct conncache *connc, + const char **hostp) { struct connectbundle *bundle = NULL; CONN_LOCK(conn->data); if(connc) { - char key[128]; - hashkey(conn, key, sizeof(key)); + char key[HASHKEY_SIZE]; + hashkey(conn, key, sizeof(key), hostp); bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); } @@ -267,17 +274,17 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc, struct Curl_easy *data = conn->data; /* *find_bundle() locks the connection cache */ - bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); + bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache, NULL); if(!bundle) { int rc; - char key[128]; + char key[HASHKEY_SIZE]; result = bundle_create(data, &new_bundle); if(result) { goto unlock; } - hashkey(conn, key, sizeof(key)); + hashkey(conn, key, sizeof(key), NULL); rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle); if(!rc) { diff --git a/lib/conncache.h b/lib/conncache.h index 35be9e0a..58f90240 100644 --- a/lib/conncache.h +++ b/lib/conncache.h @@ -54,7 +54,8 @@ void Curl_conncache_destroy(struct conncache *connc); /* return the correct bundle, to a host or a proxy */ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc); + struct conncache *connc, + const char **hostp); void Curl_conncache_unlock(struct Curl_easy *data); /* returns number of connections currently held in the connection cache */ size_t Curl_conncache_size(struct Curl_easy *data); diff --git a/lib/curl_config.h b/lib/curl_config.h index 341b8353..9bc57198 100644 --- a/lib/curl_config.h +++ b/lib/curl_config.h @@ -962,9 +962,6 @@ /* if OpenSSL is in use */ #define USE_OPENSSL 1 -/* if PolarSSL is enabled */ -/* #undef USE_POLARSSL */ - /* to enable Windows native SSL/TLS support */ /* #undef USE_SCHANNEL */ diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake index 9ac64f65..3d96c498 100644 --- a/lib/curl_config.h.cmake +++ b/lib/curl_config.h.cmake @@ -241,6 +241,9 @@ /* Define to 1 if you have the `getsockname' function. */ #cmakedefine HAVE_GETSOCKNAME 1 +/* Define to 1 if you have the `if_nametoindex' function. */ +#cmakedefine HAVE_IF_NAMETOINDEX 1 + /* Define to 1 if you have the `getpwuid' function. */ #cmakedefine HAVE_GETPWUID 1 @@ -888,26 +891,35 @@ /* Define to the function return type for send. */ #cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV} +/* + Note: SIZEOF_* variables are fetched with CMake through check_type_size(). + As per CMake documentation on CheckTypeSize, C preprocessor code is + generated by CMake into SIZEOF_*_CODE. This is what we use in the + following statements. + + Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html +*/ + /* The size of `int', as computed by sizeof. */ -#cmakedefine SIZEOF_INT ${SIZEOF_INT} +${SIZEOF_INT_CODE} /* The size of `short', as computed by sizeof. */ -#cmakedefine SIZEOF_SHORT ${SIZEOF_SHORT} +${SIZEOF_SHORT_CODE} /* The size of `long', as computed by sizeof. */ -#cmakedefine SIZEOF_LONG ${SIZEOF_LONG} +${SIZEOF_LONG_CODE} /* The size of `off_t', as computed by sizeof. */ -#cmakedefine SIZEOF_OFF_T ${SIZEOF_OFF_T} +${SIZEOF_OFF_T_CODE} /* The size of `curl_off_t', as computed by sizeof. */ -#cmakedefine SIZEOF_CURL_OFF_T ${SIZEOF_CURL_OFF_T} +${SIZEOF_CURL_OFF_T_CODE} /* The size of `size_t', as computed by sizeof. */ -#cmakedefine SIZEOF_SIZE_T ${SIZEOF_SIZE_T} +${SIZEOF_SIZE_T_CODE} /* The size of `time_t', as computed by sizeof. */ -#cmakedefine SIZEOF_TIME_T ${SIZEOF_TIME_T} +${SIZEOF_TIME_T_CODE} /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 diff --git a/lib/curl_config.h.in b/lib/curl_config.h.in index 2be4755f..778991ca 100644 --- a/lib/curl_config.h.in +++ b/lib/curl_config.h.in @@ -979,9 +979,6 @@ /* if OpenSSL is in use */ #undef USE_OPENSSL -/* if PolarSSL is enabled */ -#undef USE_POLARSSL - /* to enable Windows native SSL/TLS support */ #undef USE_SCHANNEL diff --git a/lib/curl_setup.h b/lib/curl_setup.h index e5b5c863..a4601c49 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -647,7 +647,7 @@ int netware_init(void); #define LIBIDN_REQUIRED_VERSION "0.4.1" #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ - defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \ + defined(USE_MBEDTLS) || \ defined(USE_CYASSL) || defined(USE_SCHANNEL) || \ defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) #define USE_SSL /* SSL support has been enabled */ @@ -644,7 +644,7 @@ output_auth_headers(struct connectdata *conn, #endif #ifdef USE_SPNEGO - if((authstatus->picked == CURLAUTH_NEGOTIATE)) { + if(authstatus->picked == CURLAUTH_NEGOTIATE) { auth = "Negotiate"; result = Curl_output_negotiate(conn, proxy); if(result) @@ -3769,6 +3769,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, "HTTP 1.1 or later with persistent connection\n")); } + k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; switch(k->httpcode) { case 304: /* (quote from RFC2616, section 10.3.5): The 304 response @@ -3786,10 +3787,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, * empty line after the header fields. */ k->size = 0; k->maxdownload = 0; - k->ignorecl = TRUE; /* ignore Content-Length headers */ + k->http_bodyless = TRUE; break; default: - /* nothing */ break; } } @@ -3805,8 +3805,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, return result; /* Check for Content-Length: header lines to get size */ - if(!k->ignorecl && !data->set.ignorecl && - checkprefix("Content-Length:", k->p)) { + if(!k->http_bodyless && + !data->set.ignorecl && checkprefix("Content-Length:", k->p)) { curl_off_t contentlength; CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength); @@ -3895,7 +3895,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, */ streamclose(conn, "Connection: close used"); } - else if(checkprefix("Transfer-Encoding:", k->p)) { + else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", k->p)) { /* One or more encodings. We check for chunked and/or a compression algorithm. */ /* @@ -3911,7 +3911,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(result) return result; } - else if(checkprefix("Content-Encoding:", k->p) && + else if(!k->http_bodyless && checkprefix("Content-Encoding:", k->p) && data->set.str[STRING_ENCODING]) { /* * Process Content-Encoding. Look for the values: identity, @@ -3924,7 +3924,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(result) return result; } - else if(checkprefix("Content-Range:", k->p)) { + else if(!k->http_bodyless && checkprefix("Content-Range:", k->p)) { /* Content-Range: bytes [num]- Content-Range: bytes: [num]- Content-Range: [num]- @@ -3970,7 +3970,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } #endif - else if(checkprefix("Last-Modified:", k->p) && + else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) && (data->set.timecondition || data->set.get_filetime) ) { time_t secs = time(NULL); k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"), diff --git a/lib/http2.c b/lib/http2.c index 8e7bc217..a535d14b 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -1199,9 +1199,6 @@ void Curl_http2_done(struct connectdata *conn, bool premature) if(!httpc->h2) /* not HTTP/2 ? */ return; - if(data->state.drain) - drained_transfer(data, httpc); - if(premature) { /* RST_STREAM */ if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, @@ -1213,6 +1210,10 @@ void Curl_http2_done(struct connectdata *conn, bool premature) httpc->pause_stream_id = 0; } } + + if(data->state.drain) + drained_transfer(data, httpc); + /* -1 means unassigned and 0 means cleared */ if(http->stream_id > 0) { int rv = nghttp2_session_set_stream_user_data(httpc->h2, diff --git a/lib/http_proxy.c b/lib/http_proxy.c index d7ed1176..ba67b861 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -632,6 +632,7 @@ static CURLcode CONNECT(struct connectdata *conn, conn->allocptr.proxyuserpwd = NULL; data->state.authproxy.done = TRUE; + data->state.authproxy.multipass = FALSE; infof(data, "Proxy replied %d to CONNECT request\n", data->info.httpproxycode); diff --git a/lib/libcurl.plist b/lib/libcurl.plist index 8e7624a1..760130c9 100644 --- a/lib/libcurl.plist +++ b/lib/libcurl.plist @@ -15,7 +15,7 @@ <string>se.haxx.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.65.0</string> + <string>7.65.1</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.65.0</string> + <string>libcurl 7.65.1</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.65.0</string> + <string>libcurl.plist 7.65.1</string> </dict> </plist> @@ -38,6 +38,13 @@ #include "curl_setup.h" +#ifdef USE_OPENSSL +#include <openssl/opensslconf.h> +#endif +#ifdef USE_MBEDTLS +#include <mbedtls/config.h> +#endif + /* The NSS, OS/400, and when not included, OpenSSL and mbed TLS crypto * libraries do not provide the MD4 hash algorithm, so we use this * implementation of it */ diff --git a/lib/multi.c b/lib/multi.c index c7c46eef..02f84603 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -241,8 +241,17 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, /* delete the given socket + handle from the hash */ -static void sh_delentry(struct curl_hash *sh, curl_socket_t s) +static void sh_delentry(struct Curl_sh_entry *entry, + struct curl_hash *sh, curl_socket_t s) { + struct curl_llist *list = &entry->list; + struct curl_llist_element *e; + /* clear the list of transfers first */ + for(e = list->head; e; e = list->head) { + struct Curl_easy *dta = e->ptr; + Curl_llist_remove(&entry->list, e, NULL); + dta->sh_entry = NULL; + } /* We remove the hash entry. This will end up in a call to sh_freeentry(). */ Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t)); @@ -780,6 +789,11 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi) static void detach_connnection(struct Curl_easy *data) { struct connectdata *conn = data->conn; + if(data->sh_entry) { + /* still listed as a user of a socket hash entry, remove it */ + Curl_llist_remove(&data->sh_entry->list, &data->sh_queue, NULL); + data->sh_entry = NULL; + } if(conn) Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); data->conn = NULL; @@ -2238,14 +2252,14 @@ static CURLMcode singlesocket(struct Curl_multi *multi, actions[i] = action; if(entry) { /* check if new for this transfer */ - for(i = 0; i< data->numsocks; i++) { - if(s == data->sockets[i]) { - prevaction = data->actions[i]; + int j; + for(j = 0; j< data->numsocks; j++) { + if(s == data->sockets[j]) { + prevaction = data->actions[j]; sincebefore = TRUE; break; } } - } else { /* this is a socket we didn't have before, add it to the hash! */ @@ -2276,6 +2290,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, /* add 'data' to the list of handles using this socket! */ Curl_llist_insert_next(&entry->list, entry->list.tail, data, &data->sh_queue); + data->sh_entry = entry; } comboaction = (entry->writers? CURL_POLL_OUT : 0) | @@ -2335,11 +2350,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, multi->socket_cb(data, s, CURL_POLL_REMOVE, multi->socket_userp, entry->socketp); - sh_delentry(&multi->sockhash, s); - } - else { - /* remove this transfer as a user of this socket */ - Curl_llist_remove(&entry->list, &data->sh_queue, NULL); + sh_delentry(entry, &multi->sockhash, s); } } } /* for loop over numsocks */ @@ -2383,7 +2394,7 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) entry->socketp); /* now remove it from the socket hash */ - sh_delentry(&multi->sockhash, s); + sh_delentry(entry, &multi->sockhash, s); } } } @@ -2474,7 +2485,6 @@ static CURLMcode multi_socket(struct Curl_multi *multi, return result; } if(s != CURL_SOCKET_TIMEOUT) { - struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); if(!entry) @@ -2487,15 +2497,19 @@ static CURLMcode multi_socket(struct Curl_multi *multi, else { struct curl_llist *list = &entry->list; struct curl_llist_element *e; + struct curl_llist_element *enext; SIGPIPE_VARIABLE(pipe_st); /* the socket can be shared by many transfers, iterate */ - for(e = list->head; e; e = e->next) { + for(e = list->head; e; e = enext) { data = (struct Curl_easy *)e->ptr; - if(data->magic != CURLEASY_MAGIC_NUMBER) - /* bad bad bad bad bad bad bad */ - return CURLM_INTERNAL_ERROR; + /* assign 'enext' here since the 'e' struct might be cleared + further down in the singlesocket() call */ + enext = e->next; + + DEBUGASSERT(data); + DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER); if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK)) /* set socket event bitmask if they're not locked */ diff --git a/lib/progress.c b/lib/progress.c index f586d59b..fe9929bb 100644 --- a/lib/progress.c +++ b/lib/progress.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,7 +31,6 @@ /* check rate limits within this many recent milliseconds, at minimum. */ #define MIN_RATE_LIMIT_PERIOD 3000 -#ifndef CURL_DISABLE_PROGRESS_METER /* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero byte) */ static void time2str(char *r, curl_off_t seconds) @@ -120,7 +119,6 @@ static char *max5data(curl_off_t bytes, char *max5) return max5; } -#endif /* @@ -364,13 +362,17 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) } } -#ifndef CURL_DISABLE_PROGRESS_METER -static void progress_meter(struct connectdata *conn) +/* + * Curl_pgrsUpdate() returns 0 for success or the value returned by the + * progress callback! + */ +int Curl_pgrsUpdate(struct connectdata *conn) { struct curltime now; curl_off_t timespent; curl_off_t timespent_ms; /* milliseconds */ struct Curl_easy *data = conn->data; + int nowindex = data->progress.speeder_c% CURR_TIME; bool shownow = FALSE; curl_off_t dl = data->progress.downloaded; curl_off_t ul = data->progress.uploaded; @@ -397,9 +399,7 @@ static void progress_meter(struct connectdata *conn) /* Calculations done at most once a second, unless end is reached */ if(data->progress.lastshow != now.tv_sec) { int countindex; /* amount of seconds stored in the speeder array */ - int nowindex = data->progress.speeder_c% CURR_TIME; - if(!(data->progress.flags & PGRS_HIDE)) - shownow = TRUE; + shownow = TRUE; data->progress.lastshow = now.tv_sec; @@ -461,12 +461,8 @@ static void progress_meter(struct connectdata *conn) data->progress.ulspeed + data->progress.dlspeed; } /* Calculations end */ - if(!shownow) - /* only show the internal progress meter once per second */ - return; - else { - /* If there's no external callback set, use internal code to show - progress */ + + if(!(data->progress.flags & PGRS_HIDE)) { /* progress meter has not been shut off */ char max5[6][10]; curl_off_t dlpercen = 0; @@ -481,6 +477,42 @@ static void progress_meter(struct connectdata *conn) curl_off_t dlestimate = 0; curl_off_t total_estimate; + if(data->set.fxferinfo) { + int result; + /* There's a callback set, call that */ + Curl_set_in_callback(data, true); + result = data->set.fxferinfo(data->set.progress_client, + data->progress.size_dl, + data->progress.downloaded, + data->progress.size_ul, + data->progress.uploaded); + Curl_set_in_callback(data, false); + if(result) + failf(data, "Callback aborted"); + return result; + } + if(data->set.fprogress) { + int result; + /* The older deprecated callback is set, call that */ + Curl_set_in_callback(data, true); + result = data->set.fprogress(data->set.progress_client, + (double)data->progress.size_dl, + (double)data->progress.downloaded, + (double)data->progress.size_ul, + (double)data->progress.uploaded); + Curl_set_in_callback(data, false); + if(result) + failf(data, "Callback aborted"); + return result; + } + + if(!shownow) + /* only show the internal progress meter once per second */ + return 0; + + /* If there's no external callback set, use internal code to show + progress */ + if(!(data->progress.flags & PGRS_HEADERS_OUT)) { if(data->state.resume_from) { fprintf(data->set.err, @@ -563,57 +595,13 @@ static void progress_meter(struct connectdata *conn) time_total, /* 8 letters */ /* total time */ time_spent, /* 8 letters */ /* time spent */ time_left, /* 8 letters */ /* time left */ - max5data(data->progress.current_speed, max5[5]) - ); + max5data(data->progress.current_speed, max5[5]) /* current speed */ + ); /* we flush the output stream to make it appear as soon as possible */ fflush(data->set.err); - } /* don't show now */ -} -#else - /* progress bar disabled */ -#define progress_meter(x) -#endif - -/* - * Curl_pgrsUpdate() returns 0 for success or the value returned by the - * progress callback! - */ -int Curl_pgrsUpdate(struct connectdata *conn) -{ - struct Curl_easy *data = conn->data; - if(!(data->progress.flags & PGRS_HIDE)) { - if(data->set.fxferinfo) { - int result; - /* There's a callback set, call that */ - Curl_set_in_callback(data, true); - result = data->set.fxferinfo(data->set.progress_client, - data->progress.size_dl, - data->progress.downloaded, - data->progress.size_ul, - data->progress.uploaded); - Curl_set_in_callback(data, false); - if(result) - failf(data, "Callback aborted"); - return result; - } - if(data->set.fprogress) { - int result; - /* The older deprecated callback is set, call that */ - Curl_set_in_callback(data, true); - result = data->set.fprogress(data->set.progress_client, - (double)data->progress.size_dl, - (double)data->progress.downloaded, - (double)data->progress.size_ul, - (double)data->progress.uploaded); - Curl_set_in_callback(data, false); - if(result) - failf(data, "Callback aborted"); - return result; - } - } - progress_meter(conn); + } /* !(data->progress.flags & PGRS_HIDE) */ return 0; } @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -106,8 +106,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) * 'rndptr' points to. * * If libcurl is built without TLS support or with a TLS backend that lacks a - * proper random API (Gskit, PolarSSL or mbedTLS), this function will use - * "weak" random. + * proper random API (Gskit or mbedTLS), this function will use "weak" random. * * When built *with* TLS support and a backend that offers strong random, it * will return error if it cannot provide strong random values. @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,8 +27,7 @@ * 'rnd' points to. * * If libcurl is built without TLS support or with a TLS backend that lacks a - * proper random API (Gskit, PolarSSL or mbedTLS), this function will use - * "weak" random. + * proper random API (Gskit or mbedTLS), this function will use "weak" random. * * When built *with* TLS support and a backend that offers strong random, it * will return error if it cannot provide strong random values. diff --git a/lib/system_win32.c b/lib/system_win32.c index f7f817dd..1143fa6a 100644 --- a/lib/system_win32.c +++ b/lib/system_win32.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2016 - 2019, Steve Holme, <steve_holme@hotmail.com>. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -36,6 +36,12 @@ LARGE_INTEGER Curl_freq; bool Curl_isVistaOrGreater; +/* Handle of iphlpapp.dll */ +static HMODULE s_hIpHlpApiDll = NULL; + +/* Pointer to the if_nametoindex function */ +IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL; + /* Curl_win32_init() performs win32 global initialization */ CURLcode Curl_win32_init(long flags) { @@ -89,6 +95,17 @@ CURLcode Curl_win32_init(long flags) } #endif + s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll")); + if(s_hIpHlpApiDll) { + /* Get the address of the if_nametoindex function */ + IF_NAMETOINDEX_FN pIfNameToIndex = + CURLX_FUNCTION_CAST(IF_NAMETOINDEX_FN, + (GetProcAddress(s_hIpHlpApiDll, "if_nametoindex"))); + + if(pIfNameToIndex) + Curl_if_nametoindex = pIfNameToIndex; + } + if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, VERSION_GREATER_THAN_EQUAL)) { Curl_isVistaOrGreater = TRUE; @@ -103,6 +120,12 @@ CURLcode Curl_win32_init(long flags) /* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ void Curl_win32_cleanup(long init_flags) { + if(s_hIpHlpApiDll) { + FreeLibrary(s_hIpHlpApiDll); + s_hIpHlpApiDll = NULL; + Curl_if_nametoindex = NULL; + } + #ifdef USE_WINDOWS_SSPI Curl_sspi_global_cleanup(); #endif @@ -114,10 +137,6 @@ void Curl_win32_cleanup(long init_flags) } } -#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ - defined(USE_WINSOCK)) - - #if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 #endif @@ -140,8 +159,6 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); # define LOADLIBARYEX "LoadLibraryExA" #endif -#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ - /* * Curl_verify_windows_version() * @@ -334,9 +351,6 @@ bool Curl_verify_windows_version(const unsigned int majorVersion, return matched; } -#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ - defined(USE_WINSOCK)) - /* * Curl_load_library() * @@ -411,6 +425,4 @@ HMODULE Curl_load_library(LPCTSTR filename) return hModule; } -#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ - #endif /* WIN32 */ diff --git a/lib/system_win32.h b/lib/system_win32.h index 926328a9..c07cf1fb 100644 --- a/lib/system_win32.h +++ b/lib/system_win32.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2016, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2016 - 2019, Steve Holme, <steve_holme@hotmail.com>. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -48,20 +48,21 @@ typedef enum { PLATFORM_WINNT } PlatformIdentifier; +/* We use our own typedef here since some headers might lack this */ +typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *); + +/* This is used instread of if_nametoindex if available on Windows */ +IF_NAMETOINDEX_FN Curl_if_nametoindex; + /* This is used to verify if we are running on a specific windows version */ bool Curl_verify_windows_version(const unsigned int majorVersion, const unsigned int minorVersion, const PlatformIdentifier platform, const VersionCondition condition); -#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ - defined(USE_WINSOCK)) - /* This is used to dynamically load DLLs */ HMODULE Curl_load_library(LPCTSTR filename); -#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ - #endif /* WIN32 */ #endif /* HEADER_CURL_SYSTEM_WIN32_H */ @@ -34,10 +34,12 @@ #ifdef HAVE_NET_IF_H #include <net/if.h> #endif +#ifdef HAVE_IPHLPAPI_H +#include <Iphlpapi.h> +#endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif - #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif @@ -93,6 +95,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "inet_pton.h" #include "getinfo.h" #include "urlapi-int.h" +#include "system_win32.h" /* And now for the protocols */ #include "ftp.h" @@ -1004,6 +1007,7 @@ ConnectionExists(struct Curl_easy *data, bool canmultiplex = IsMultiplexingPossible(data, needle); struct connectbundle *bundle; struct curltime now = Curl_now(); + const char *hostbundle; #ifdef USE_NTLM bool wantNTLMhttp = ((data->state.authhost.want & @@ -1020,16 +1024,15 @@ ConnectionExists(struct Curl_easy *data, /* Look up the bundle with all the connections to this particular host. Locks the connection cache, beware of early returns! */ - bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache); + bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache, + &hostbundle); if(bundle) { /* Max pipe length is zero (unlimited) for multiplexed connections */ struct curl_llist_element *curr; infof(data, "Found bundle for host %s: %p [%s]\n", - (needle->bits.conn_to_host ? needle->conn_to_host.name : - needle->host.name), (void *)bundle, - (bundle->multiuse == BUNDLE_MULTIPLEX ? - "can multiplex" : "serially")); + hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? + "can multiplex" : "serially")); /* We can't multiplex if we don't know anything about the server */ if(canmultiplex) { @@ -1884,6 +1887,50 @@ CURLcode Curl_uc_to_curlcode(CURLUcode uc) } /* + * If the URL was set with an IPv6 numerical address with a zone id part, set + * the scope_id based on that! + */ + +static void zonefrom_url(CURLU *uh, struct connectdata *conn) +{ + char *zoneid; + CURLUcode uc; + + uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0); + + if(!uc && zoneid) { + char *endp; + unsigned long scope = strtoul(zoneid, &endp, 10); + if(!*endp && (scope < UINT_MAX)) + /* A plain number, use it directly as a scope id. */ + conn->scope_id = (unsigned int)scope; +#if defined(HAVE_IF_NAMETOINDEX) + else { +#elif defined(WIN32) + else if(Curl_if_nametoindex) { +#endif + +#if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32) + /* Zone identifier is not numeric */ + unsigned int scopeidx = 0; +#if defined(WIN32) + scopeidx = Curl_if_nametoindex(zoneid); +#else + scopeidx = if_nametoindex(zoneid); +#endif + if(!scopeidx) + infof(conn->data, "Invalid zoneid: %s; %s\n", zoneid, + strerror(errno)); + else + conn->scope_id = scopeidx; + } +#endif /* HAVE_IF_NAMETOINDEX || WIN32 */ + + free(zoneid); + } +} + +/* * Parse URL and fill in the relevant members of the connection struct. */ static CURLcode parseurlandfillconn(struct Curl_easy *data, @@ -1991,7 +2038,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, } else { unsigned long port = strtoul(data->state.up.port, NULL, 10); - conn->remote_port = curlx_ultous(port); + conn->port = conn->remote_port = curlx_ultous(port); } (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); @@ -2004,38 +2051,14 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if(hostname[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address scope. */ - char *zoneid; size_t hlen; - uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0); conn->bits.ipv6_ip = TRUE; - /* cut off the brackets! */ hostname++; hlen = strlen(hostname); hostname[hlen - 1] = 0; - if(!uc && zoneid) { - char *endp; - unsigned long scope; - scope = strtoul(zoneid, &endp, 10); - if(!*endp && (scope < UINT_MAX)) { - /* A plain number, use it direcly as a scope id. */ - conn->scope_id = (unsigned int)scope; - } -#ifdef HAVE_IF_NAMETOINDEX - else { - /* Zone identifier is not numeric */ - unsigned int scopeidx = 0; - scopeidx = if_nametoindex(zoneid); - if(!scopeidx) - infof(data, "Invalid zoneid id: %s; %s\n", zoneid, - strerror(errno)); - else - conn->scope_id = scopeidx; - } -#endif /* HAVE_IF_NAMETOINDEX */ - free(zoneid); - } + zonefrom_url(uh, conn); } /* make sure the connect struct gets its own copy of the host name */ @@ -2298,7 +2321,7 @@ static CURLcode parse_proxy(struct Curl_easy *data, struct connectdata *conn, char *proxy, curl_proxytype proxytype) { - char *portptr; + char *portptr = NULL; long port = -1; char *proxyuser = NULL; char *proxypasswd = NULL; @@ -2422,6 +2445,7 @@ static CURLcode parse_proxy(struct Curl_easy *data, size_t len = strlen(host); host[len-1] = 0; /* clear the trailing bracket */ host++; + zonefrom_url(uhp, conn); } proxyinfo->host.name = host; @@ -3749,8 +3773,9 @@ static CURLcode create_conn(struct Curl_easy *data, connections_available = FALSE; else { /* this gets a lock on the conncache */ + const char *bundlehost; struct connectbundle *bundle = - Curl_conncache_find_bundle(conn, data->state.conn_cache); + Curl_conncache_find_bundle(conn, data->state.conn_cache, &bundlehost); if(max_host_connections > 0 && bundle && (bundle->num_connections >= max_host_connections)) { @@ -3764,8 +3789,8 @@ static CURLcode create_conn(struct Curl_easy *data, (void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE); else { - infof(data, "No more connections allowed to host: %zu\n", - max_host_connections); + infof(data, "No more connections allowed to host %s: %zu\n", + bundlehost, max_host_connections); connections_available = FALSE; } } diff --git a/lib/urldata.h b/lib/urldata.h index d759592d..f8ba591d 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -617,8 +617,8 @@ struct SingleRequest { bit upload_done:1; /* set to TRUE when doing chunked transfer-encoding upload and we're uploading the last chunk */ bit ignorebody:1; /* we read a response-body but we ignore it! */ - bit ignorecl:1; /* This HTTP response has no body so we ignore the - Content-Length: header */ + bit http_bodyless:1; /* HTTP response status code is between 100 and 199, + 204 or 304 */ bit chunk:1; /* if set, this is a chunked transfer-encoding */ bit upload_chunky:1; /* set TRUE if we are doing chunked transfer-encoding on upload */ @@ -1081,8 +1081,9 @@ struct PureInfo { const char *conn_scheme; unsigned int conn_protocol; struct curl_certinfo certs; /* info about the certs, only populated in - OpenSSL builds. Asked for with - CURLOPT_CERTINFO / CURLINFO_CERTINFO */ + OpenSSL, GnuTLS, Schannel, NSS and GSKit + builds. Asked for with CURLOPT_CERTINFO + / CURLINFO_CERTINFO */ bit timecond:1; /* set to TRUE if the time condition didn't match, which thus made the document NOT get fetched */ @@ -1778,6 +1779,7 @@ struct Curl_easy { struct connectdata *conn; struct curl_llist_element connect_queue; struct curl_llist_element sh_queue; /* list per Curl_sh_entry */ + struct Curl_sh_entry *sh_entry; /* the socket hash this was added to */ struct curl_llist_element conn_queue; /* list per connectdata */ CURLMstate mstate; /* the handle's state */ diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index 491def10..3125f0b7 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -216,6 +216,11 @@ static const cipher_s cipherlist[] = { {"dhe_rsa_chacha20_poly1305_sha_256", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, #endif +#ifdef TLS_AES_256_GCM_SHA384 + {"aes_128_gcm_sha_256", TLS_AES_128_GCM_SHA256}, + {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, + {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, +#endif }; #ifdef WIN32 diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c index 2fdf662a..3fb125ab 100644 --- a/lib/vtls/sectransp.c +++ b/lib/vtls/sectransp.c @@ -2111,8 +2111,8 @@ static int append_cert_to_array(struct Curl_easy *data, return CURLE_OK; } -static int verify_cert(const char *cafile, struct Curl_easy *data, - SSLContextRef ctx) +static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, + SSLContextRef ctx) { int n = 0, rc; long res; @@ -2370,10 +2370,10 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) Leopard's headers */ case -9841: if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { - int res = verify_cert(SSL_CONN_CONFIG(CAfile), data, - BACKEND->ssl_ctx); - if(res != CURLE_OK) - return res; + CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + BACKEND->ssl_ctx); + if(result) + return result; } /* the documentation says we need to call SSLHandshake() again */ return sectransp_connect_step2(conn, sockindex); @@ -3186,7 +3186,10 @@ static ssize_t sectransp_recv(struct connectdata *conn, /*struct Curl_easy *data = conn->data;*/ struct ssl_connect_data *connssl = &conn->ssl[num]; size_t processed = 0UL; - OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed); + OSStatus err; + + again: + err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed); if(err != noErr) { switch(err) { @@ -3207,6 +3210,16 @@ static ssize_t sectransp_recv(struct connectdata *conn, return -1L; break; + /* The below is errSSLPeerAuthCompleted; it's not defined in + Leopard's headers */ + case -9841: + if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data, + BACKEND->ssl_ctx); + if(result) + return result; + } + goto again; default: failf(conn->data, "SSLRead() return error %d", err); *curlcode = CURLE_RECV_ERROR; |