From 487f6abca26f6b70d545d02e296ae6ca7e197882 Mon Sep 17 00:00:00 2001 From: dartraiden Date: Thu, 19 Sep 2024 19:35:43 +0300 Subject: libcurl: update to 8.10.1 --- libs/libcurl/src/cf-https-connect.c | 3 - libs/libcurl/src/cf-socket.c | 4 ++ libs/libcurl/src/cfilters.c | 1 + libs/libcurl/src/config-win32.h | 7 --- libs/libcurl/src/connect.c | 22 +++++-- libs/libcurl/src/curl_memrchr.c | 4 ++ libs/libcurl/src/curl_memrchr.h | 4 ++ libs/libcurl/src/curl_setup.h | 10 ++++ libs/libcurl/src/ftp.c | 27 +++++---- libs/libcurl/src/http.c | 18 +++--- libs/libcurl/src/http2.c | 9 ++- libs/libcurl/src/multi.c | 2 + libs/libcurl/src/rand.c | 6 +- libs/libcurl/src/rand.h | 5 -- libs/libcurl/src/request.c | 40 +++++++++---- libs/libcurl/src/request.h | 1 + libs/libcurl/src/sendf.c | 18 ++++-- libs/libcurl/src/setopt.c | 12 ++-- libs/libcurl/src/transfer.c | 34 +++-------- libs/libcurl/src/url.c | 15 +++++ libs/libcurl/src/urldata.h | 6 ++ libs/libcurl/src/vquic/curl_ngtcp2.c | 7 --- libs/libcurl/src/vquic/curl_osslq.c | 7 --- libs/libcurl/src/vquic/curl_quiche.c | 8 --- libs/libcurl/src/vtls/rustls.c | 108 ++++++++++++++++++++++++----------- libs/libcurl/src/vtls/vtls.h | 2 +- 26 files changed, 233 insertions(+), 147 deletions(-) (limited to 'libs/libcurl/src') diff --git a/libs/libcurl/src/cf-https-connect.c b/libs/libcurl/src/cf-https-connect.c index 2597c0eee5..31a0ac65e8 100644 --- a/libs/libcurl/src/cf-https-connect.c +++ b/libs/libcurl/src/cf-https-connect.c @@ -189,7 +189,6 @@ static CURLcode baller_connected(struct Curl_cfilter *cf, switch(cf->conn->alpn) { case CURL_HTTP_VERSION_3: - infof(data, "using HTTP/3"); break; case CURL_HTTP_VERSION_2: #ifdef USE_NGHTTP2 @@ -202,10 +201,8 @@ static CURLcode baller_connected(struct Curl_cfilter *cf, return result; } #endif - infof(data, "using HTTP/2"); break; default: - infof(data, "using HTTP/1.x"); break; } ctx->state = CF_HC_SUCCESS; diff --git a/libs/libcurl/src/cf-socket.c b/libs/libcurl/src/cf-socket.c index 50b5b51865..97e13903c5 100644 --- a/libs/libcurl/src/cf-socket.c +++ b/libs/libcurl/src/cf-socket.c @@ -1749,7 +1749,11 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf, return CURLE_OK; } case CF_QUERY_IP_INFO: +#ifdef USE_IPV6 *pres1 = (ctx->addr.family == AF_INET6)? TRUE : FALSE; +#else + *pres1 = FALSE; +#endif *(struct ip_quadruple *)pres2 = ctx->ip; return CURLE_OK; default: diff --git a/libs/libcurl/src/cfilters.c b/libs/libcurl/src/cfilters.c index 7ec8f3a79f..b93362aacb 100644 --- a/libs/libcurl/src/cfilters.c +++ b/libs/libcurl/src/cfilters.c @@ -437,6 +437,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data, cf_cntrl_update_info(data, data->conn); conn_report_connect_stats(data, data->conn); data->conn->keepalive = Curl_now(); + Curl_verboseconnect(data, data->conn, sockindex); } else if(result) { conn_report_connect_stats(data, data->conn); diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 2e6261c745..17924e3dec 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -149,10 +149,6 @@ /* Define if you have the select function. */ #define HAVE_SELECT 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the setlocale function. */ #define HAVE_SETLOCALE 1 @@ -478,9 +474,6 @@ Vista #define USE_WIN32_LDAP 1 #endif -/* if SSL is enabled */ -#define USE_OPENSSL 1 - /* Define to use the Windows crypto library. */ #if !defined(CURL_WINDOWS_APP) #define USE_WIN32_CRYPTO diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 651b7ff467..ac8d271d35 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -547,9 +547,11 @@ static CURLcode baller_start_next(struct Curl_cfilter *cf, { if(cf->sockindex == FIRSTSOCKET) { baller_next_addr(baller); - /* If we get inconclusive answers from the server(s), we make - * a second iteration over the address list */ - if(!baller->addr && baller->inconclusive && !baller->rewinded) + /* If we get inconclusive answers from the server(s), we start + * again until this whole thing times out. This allows us to + * connect to servers that are gracefully restarting and the + * packet routing to the new instance has not happened yet (e.g. QUIC). */ + if(!baller->addr && baller->inconclusive) baller_rewind(baller); baller_start(cf, data, baller, timeoutms); } @@ -800,8 +802,10 @@ static CURLcode start_connect(struct Curl_cfilter *cf, } else { /* no user preference, we try ipv6 always first when available */ +#ifdef USE_IPV6 ai_family0 = AF_INET6; addr0 = addr_first_match(remotehost->addr, ai_family0); +#endif /* next candidate is ipv4 */ ai_family1 = AF_INET; addr1 = addr_first_match(remotehost->addr, ai_family1); @@ -965,7 +969,17 @@ static CURLcode cf_he_connect(struct Curl_cfilter *cf, if(cf->conn->handler->protocol & PROTO_FAMILY_SSH) Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */ - Curl_verboseconnect(data, cf->conn, cf->sockindex); + if(Curl_trc_cf_is_verbose(cf, data)) { + struct ip_quadruple ipquad; + int is_ipv6; + if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) { + const char *host, *disphost; + int port; + cf->next->cft->get_host(cf->next, data, &host, &disphost, &port); + CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u", + disphost, ipquad.remote_ip, ipquad.remote_port); + } + } data->info.numconnects++; /* to track the # of connections made */ } break; diff --git a/libs/libcurl/src/curl_memrchr.c b/libs/libcurl/src/curl_memrchr.c index 4342b938b6..9b7ab8258b 100644 --- a/libs/libcurl/src/curl_memrchr.c +++ b/libs/libcurl/src/curl_memrchr.c @@ -33,6 +33,9 @@ #include "memdebug.h" #ifndef HAVE_MEMRCHR +#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \ + defined(USE_OPENSSL) || \ + defined(USE_SCHANNEL) /* * Curl_memrchr() @@ -61,4 +64,5 @@ Curl_memrchr(const void *s, int c, size_t n) return NULL; } +#endif #endif /* HAVE_MEMRCHR */ diff --git a/libs/libcurl/src/curl_memrchr.h b/libs/libcurl/src/curl_memrchr.h index 7e2de316b6..dbced53b38 100644 --- a/libs/libcurl/src/curl_memrchr.h +++ b/libs/libcurl/src/curl_memrchr.h @@ -34,11 +34,15 @@ #endif #else /* HAVE_MEMRCHR */ +#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \ + defined(USE_OPENSSL) || \ + defined(USE_SCHANNEL) void *Curl_memrchr(const void *s, int c, size_t n); #define memrchr(x,y,z) Curl_memrchr((x),(y),(z)) +#endif #endif /* HAVE_MEMRCHR */ #endif /* HEADER_CURL_MEMRCHR_H */ diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 7f63658cee..dc56ee9d0b 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -102,6 +102,16 @@ # ifndef NOGDI # define NOGDI # endif +/* Detect Windows App environment which has a restricted access + * to the Win32 APIs. */ +# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ + defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define CURL_WINDOWS_APP +# endif +# endif #endif /* Compatibility */ diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index dd3180e592..dd90f54090 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -327,6 +327,7 @@ static void freedirs(struct ftp_conn *ftpc) Curl_safefree(ftpc->newhost); } +#ifdef CURL_PREFER_LF_LINEENDS /*********************************************************************** * * Lineend Conversions @@ -415,6 +416,7 @@ static const struct Curl_cwtype ftp_cw_lc = { sizeof(struct ftp_cw_lc_ctx) }; +#endif /* CURL_PREFER_LF_LINEENDS */ /*********************************************************************** * * AcceptServerConnect() @@ -4138,22 +4140,27 @@ static CURLcode ftp_do(struct Curl_easy *data, bool *done) CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; struct ftp_conn *ftpc = &conn->proto.ftpc; - /* FTP data may need conversion. */ - struct Curl_cwriter *ftp_lc_writer; *done = FALSE; /* default to false */ ftpc->wait_data_conn = FALSE; /* default to no such wait */ - result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc, - CURL_CW_CONTENT_DECODE); - if(result) - return result; +#ifdef CURL_PREFER_LF_LINEENDS + { + /* FTP data may need conversion. */ + struct Curl_cwriter *ftp_lc_writer; - result = Curl_cwriter_add(data, ftp_lc_writer); - if(result) { - Curl_cwriter_free(data, ftp_lc_writer); - return result; + result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc, + CURL_CW_CONTENT_DECODE); + if(result) + return result; + + result = Curl_cwriter_add(data, ftp_lc_writer); + if(result) { + Curl_cwriter_free(data, ftp_lc_writer); + return result; + } } +#endif /* CURL_PREFER_LF_LINEENDS */ if(data->state.wildcardmatch) { result = wc_statemach(data); diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index cb585b4571..65189e9dee 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -3283,10 +3283,13 @@ CURLcode Curl_http_size(struct Curl_easy *data) } else if(k->size != -1) { if(data->set.max_filesize && - k->size > data->set.max_filesize) { + !k->ignorebody && + (k->size > data->set.max_filesize)) { failf(data, "Maximum file size exceeded"); return CURLE_FILESIZE_EXCEEDED; } + if(k->ignorebody) + infof(data, "setting size while ignoring"); Curl_pgrsSetDownloadSize(data, k->size); k->maxdownload = k->size; } @@ -3625,13 +3628,6 @@ static CURLcode http_on_response(struct Curl_easy *data, } - /* This is the last response that we will got for the current request. - * Check on the body size and determine if the response is complete. - */ - result = Curl_http_size(data); - if(result) - goto out; - /* If we requested a "no body", this is a good time to get * out and return home. */ @@ -3651,6 +3647,12 @@ static CURLcode http_on_response(struct Curl_easy *data, /* final response without error, prepare to receive the body */ result = Curl_http_firstwrite(data); + if(!result) + /* This is the last response that we get for the current request. + * Check on the body size and determine if the response is complete. + */ + result = Curl_http_size(data); + out: if(last_hd) { /* if not written yet, write it now */ diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index 7ec8ad6fcb..cd83e564b1 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -1679,12 +1679,11 @@ static ssize_t req_body_read_callback(nghttp2_session *session, CURL_TRC_CF(data_s, cf, "[%d] req_body_read(len=%zu) eos=%d -> %zd, %d", stream_id, length, stream->body_eos, nread, result); - if(nread == 0) - return NGHTTP2_ERR_DEFERRED; - if(stream->body_eos && Curl_bufq_is_empty(&stream->sendbuf)) + if(stream->body_eos && Curl_bufq_is_empty(&stream->sendbuf)) { *data_flags = NGHTTP2_DATA_FLAG_EOF; - - return nread; + return nread; + } + return (nread == 0)? NGHTTP2_ERR_DEFERRED : nread; } #if !defined(CURL_DISABLE_VERBOSE_STRINGS) diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 051bbd7efa..7aed3f5fc9 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -3688,6 +3688,8 @@ CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, void *hashp) { struct Curl_sh_entry *there = NULL; + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; there = sh_getentry(&multi->sockhash, s); diff --git a/libs/libcurl/src/rand.c b/libs/libcurl/src/rand.c index 8cfd7d4a7e..d44bde4014 100644 --- a/libs/libcurl/src/rand.c +++ b/libs/libcurl/src/rand.c @@ -100,9 +100,9 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length) } #endif -#if !defined(USE_SSL) || defined(USE_RUSTLS) +#if !defined(USE_SSL) /* ---- possibly non-cryptographic version following ---- */ -CURLcode Curl_weak_random(struct Curl_easy *data, +static CURLcode weak_random(struct Curl_easy *data, unsigned char *entropy, size_t length) /* always 4, size of int */ { @@ -151,7 +151,7 @@ CURLcode Curl_weak_random(struct Curl_easy *data, #ifdef USE_SSL #define _random(x,y,z) Curl_ssl_random(x,y,z) #else -#define _random(x,y,z) Curl_weak_random(x,y,z) +#define _random(x,y,z) weak_random(x,y,z) #endif static CURLcode randit(struct Curl_easy *data, unsigned int *rnd, diff --git a/libs/libcurl/src/rand.h b/libs/libcurl/src/rand.h index 8a0c754d64..9d0442bcaa 100644 --- a/libs/libcurl/src/rand.h +++ b/libs/libcurl/src/rand.h @@ -36,11 +36,6 @@ CURLcode Curl_rand_bytes(struct Curl_easy *data, #define Curl_rand(a,b,c) Curl_rand_bytes((a), (b), (c)) #endif -/* ---- non-cryptographic version following ---- */ -CURLcode Curl_weak_random(struct Curl_easy *data, - unsigned char *rnd, - size_t length); - /* * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random * hexadecimal digits PLUS a null-terminating byte. It must be an odd number diff --git a/libs/libcurl/src/request.c b/libs/libcurl/src/request.c index 011e8233c4..978d690e58 100644 --- a/libs/libcurl/src/request.c +++ b/libs/libcurl/src/request.c @@ -52,7 +52,11 @@ CURLcode Curl_req_soft_reset(struct SingleRequest *req, req->done = FALSE; req->upload_done = FALSE; + req->upload_aborted = FALSE; req->download_done = FALSE; + req->eos_written = FALSE; + req->eos_read = FALSE; + req->eos_sent = FALSE; req->ignorebody = FALSE; req->shutdown = FALSE; req->bytecount = 0; @@ -146,6 +150,7 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->download_done = FALSE; req->eos_written = FALSE; req->eos_read = FALSE; + req->eos_sent = FALSE; req->upload_done = FALSE; req->upload_aborted = FALSE; req->ignorebody = FALSE; @@ -214,15 +219,19 @@ static CURLcode xfer_send(struct Curl_easy *data, eos = TRUE; } result = Curl_xfer_send(data, buf, blen, eos, pnwritten); - if(!result && *pnwritten) { - if(hds_len) - Curl_debug(data, CURLINFO_HEADER_OUT, (char *)buf, - CURLMIN(hds_len, *pnwritten)); - if(*pnwritten > hds_len) { - size_t body_len = *pnwritten - hds_len; - Curl_debug(data, CURLINFO_DATA_OUT, (char *)buf + hds_len, body_len); - data->req.writebytecount += body_len; - Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + if(!result) { + if(eos && (blen == *pnwritten)) + data->req.eos_sent = TRUE; + if(*pnwritten) { + if(hds_len) + Curl_debug(data, CURLINFO_HEADER_OUT, (char *)buf, + CURLMIN(hds_len, *pnwritten)); + if(*pnwritten > hds_len) { + size_t body_len = *pnwritten - hds_len; + Curl_debug(data, CURLINFO_DATA_OUT, (char *)buf + hds_len, body_len); + data->req.writebytecount += body_len; + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + } } } return result; @@ -304,8 +313,17 @@ static CURLcode req_flush(struct Curl_easy *data) return Curl_xfer_flush(data); } - if(!data->req.upload_done && data->req.eos_read && - Curl_bufq_is_empty(&data->req.sendbuf)) { + if(data->req.eos_read && !data->req.eos_sent) { + char tmp; + size_t nwritten; + result = xfer_send(data, &tmp, 0, 0, &nwritten); + if(result) + return result; + DEBUGASSERT(data->req.eos_sent); + } + + if(!data->req.upload_done && data->req.eos_read && data->req.eos_sent) { + DEBUGASSERT(Curl_bufq_is_empty(&data->req.sendbuf)); if(data->req.shutdown) { bool done; result = Curl_xfer_send_shutdown(data, &done); diff --git a/libs/libcurl/src/request.h b/libs/libcurl/src/request.h index 4b40889f3c..ab695ecea0 100644 --- a/libs/libcurl/src/request.h +++ b/libs/libcurl/src/request.h @@ -130,6 +130,7 @@ struct SingleRequest { BIT(download_done); /* set to TRUE when download is complete */ BIT(eos_written); /* iff EOS has been written to client */ BIT(eos_read); /* iff EOS has been read from the client */ + BIT(eos_sent); /* iff EOS has been sent to the server */ BIT(rewind_read); /* iff reader needs rewind at next start */ BIT(upload_done); /* set to TRUE when all request data has been sent */ BIT(upload_aborted); /* set to TRUE when upload was aborted. Will also diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index 92b21dc7ea..bba9f5b499 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -336,7 +336,7 @@ static CURLcode cw_download_write(struct Curl_easy *data, connclose(data->conn, "excess found in a read"); } } - else if(nwrite < nbytes) { + else if((nwrite < nbytes) && !data->req.ignorebody) { failf(data, "Exceeded the maximum allowed file size " "(%" FMT_OFF_T ") with %" FMT_OFF_T " bytes", data->set.max_filesize, data->req.bytecount); @@ -949,6 +949,7 @@ struct cr_lc_ctx { struct bufq buf; BIT(read_eos); /* we read an EOS from the next reader */ BIT(eos); /* we have returned an EOS */ + BIT(prev_cr); /* the last byte was a CR */ }; static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader) @@ -1005,10 +1006,15 @@ static CURLcode cr_lc_read(struct Curl_easy *data, goto out; } - /* at least one \n needs conversion to '\r\n', place into ctx->buf */ + /* at least one \n might need conversion to '\r\n', place into ctx->buf */ for(i = start = 0; i < nread; ++i) { - if(buf[i] != '\n') + /* if this byte is not an LF character, or if the preceding character is + a CR (meaning this already is a CRLF pair), go to next */ + if((buf[i] != '\n') || ctx->prev_cr) { + ctx->prev_cr = (buf[i] == '\r'); continue; + } + ctx->prev_cr = false; /* on a soft limit bufq, we do not need to check length */ result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n); if(!result) @@ -1101,7 +1107,11 @@ static CURLcode do_init_reader_stack(struct Curl_easy *data, clen = r->crt->total_length(data, r); /* if we do not have 0 length init, and crlf conversion is wanted, * add the reader for it */ - if(clen && (data->set.crlf || data->state.prefer_ascii)) { + if(clen && (data->set.crlf +#ifdef CURL_PREFER_LF_LINEENDS + || data->state.prefer_ascii +#endif + )) { result = cr_lc_add(data); if(result) return result; diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 488266e9b5..f9902ad80a 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -1977,7 +1977,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Enable peer SSL verifying for proxy. */ data->set.proxy_ssl.primary.verifypeer = - (0 != va_arg(param, long))?TRUE:FALSE; + (0 != va_arg(param, long)); /* Update the current connection proxy_ssl_config. */ Curl_ssl_conn_config_update(data, TRUE); @@ -2016,7 +2016,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); /* Treat both 1 and 2 as TRUE */ - data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE); + data->set.proxy_ssl.primary.verifyhost = !!(arg & 3); /* Update the current connection proxy_ssl_config. */ Curl_ssl_conn_config_update(data, TRUE); break; @@ -2622,7 +2622,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_SSH_COMPRESSION: - data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE; + data->set.ssh_compression = (0 != va_arg(param, long)); break; #endif /* USE_SSH */ @@ -2986,7 +2986,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_TCP_FASTOPEN: #if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \ defined(TCP_FASTOPEN_CONNECT) - data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE; + data->set.tcp_fastopen = (0 != va_arg(param, long)); #else result = CURLE_NOT_BUILT_IN; #endif @@ -3038,7 +3038,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.connect_to = va_arg(param, struct curl_slist *); break; case CURLOPT_SUPPRESS_CONNECT_HEADERS: - data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE; + data->set.suppress_connect_headers = (0 != va_arg(param, long)); break; case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: uarg = va_arg(param, unsigned long); @@ -3058,7 +3058,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_DOH_URL: result = Curl_setstropt(&data->set.str[STRING_DOH], va_arg(param, char *)); - data->set.doh = data->set.str[STRING_DOH]?TRUE:FALSE; + data->set.doh = !!(data->set.str[STRING_DOH]); break; #endif case CURLOPT_UPKEEP_INTERVAL_MS: diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 22e3151245..55f868a8ec 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -424,53 +424,37 @@ CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp) struct SingleRequest *k = &data->req; CURLcode result = CURLE_OK; int didwhat = 0; - int select_bits = 0; DEBUGASSERT(nowp); if(data->state.select_bits) { if(select_bits_paused(data, data->state.select_bits)) { /* leave the bits unchanged, so they'll tell us what to do when * this transfer gets unpaused. */ - /* DEBUGF(infof(data, "sendrecv, select_bits, early return on PAUSED")); - */ result = CURLE_OK; goto out; } data->state.select_bits = 0; - /* DEBUGF(infof(data, "sendrecv, select_bits %x, RUN", select_bits)); */ - select_bits = (CURL_CSELECT_OUT|CURL_CSELECT_IN); - } - else if(data->last_poll.num) { - /* The transfer wanted something polled. Let's run all available - * send/receives. Worst case we EAGAIN on some. */ - /* DEBUGF(infof(data, "sendrecv, had poll sockets, RUN")); */ - select_bits = (CURL_CSELECT_OUT|CURL_CSELECT_IN); - } - else if(data->req.keepon & KEEP_SEND_TIMED) { - /* DEBUGF(infof(data, "sendrecv, KEEP_SEND_TIMED, RUN ul")); */ - select_bits = CURL_CSELECT_OUT; } #ifdef USE_HYPER if(data->conn->datastream) { - result = data->conn->datastream(data, data->conn, &didwhat, select_bits); + result = data->conn->datastream(data, data->conn, &didwhat, + CURL_CSELECT_OUT|CURL_CSELECT_IN); if(result || data->req.done) goto out; } else { #endif - /* We go ahead and do a read if we have a readable socket or if - the stream was rewound (in which case we have data in a - buffer) */ - if((k->keepon & KEEP_RECV) && (select_bits & CURL_CSELECT_IN)) { + /* We go ahead and do a read if we have a readable socket or if the stream + was rewound (in which case we have data in a buffer) */ + if(k->keepon & KEEP_RECV) { result = sendrecv_dl(data, k, &didwhat); if(result || data->req.done) goto out; } /* If we still have writing to do, we check if we have a writable socket. */ - if((Curl_req_want_send(data) || (data->req.keepon & KEEP_SEND_TIMED)) && - (select_bits & CURL_CSELECT_OUT)) { + if(Curl_req_want_send(data) || (data->req.keepon & KEEP_SEND_TIMED)) { result = sendrecv_ul(data, &didwhat); if(result) goto out; @@ -479,7 +463,7 @@ CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp) } #endif - if(select_bits && !didwhat) { + if(!didwhat) { /* Transfer wanted to send/recv, but nothing was possible. */ result = Curl_conn_ev_data_idle(data); if(result) @@ -1253,8 +1237,8 @@ CURLcode Curl_xfer_send(struct Curl_easy *data, else if(!result && *pnwritten) data->info.request_size += *pnwritten; - DEBUGF(infof(data, "Curl_xfer_send(len=%zu) -> %d, %zu", - blen, result, *pnwritten)); + DEBUGF(infof(data, "Curl_xfer_send(len=%zu, eos=%d) -> %d, %zu", + blen, eos, result, *pnwritten)); return result; } diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 5977a41071..336afcdb7d 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -1274,6 +1274,21 @@ void Curl_verboseconnect(struct Curl_easy *data, infof(data, "Connected to %s (%s) port %u", CURL_CONN_HOST_DISPNAME(conn), conn->primary.remote_ip, conn->primary.remote_port); +#if !defined(CURL_DISABLE_HTTP) + if(conn->handler->protocol & PROTO_FAMILY_HTTP) { + switch(conn->alpn) { + case CURL_HTTP_VERSION_3: + infof(data, "using HTTP/3"); + break; + case CURL_HTTP_VERSION_2: + infof(data, "using HTTP/2"); + break; + default: + infof(data, "using HTTP/1.x"); + break; + } + } +#endif } #endif diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index 009bbb6232..0ff53676b3 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -105,6 +105,12 @@ typedef unsigned int curl_prot_t; #define CURL_DEFAULT_USER "anonymous" #define CURL_DEFAULT_PASSWORD "ftp@example.com" +#if !defined(_WIN32) && !defined(MSDOS) && !defined(__EMX__) +/* do FTP line-end CRLF => LF conversions on platforms that prefer LF-only. It + also means: keep CRLF line endings on the CRLF platforms */ +#define CURL_PREFER_LF_LINEENDS +#endif + /* Convenience defines for checking protocols or their SSL based version. Each protocol handler should only ever have a single CURLPROTO_ in its protocol field. */ diff --git a/libs/libcurl/src/vquic/curl_ngtcp2.c b/libs/libcurl/src/vquic/curl_ngtcp2.c index 54f3ce6929..bee8689af6 100644 --- a/libs/libcurl/src/vquic/curl_ngtcp2.c +++ b/libs/libcurl/src/vquic/curl_ngtcp2.c @@ -129,7 +129,6 @@ struct cf_ngtcp2_ctx { nghttp3_settings h3settings; struct curltime started_at; /* time the current attempt started */ struct curltime handshake_at; /* time connect handshake finished */ - struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ struct dynbuf scratch; /* temp buffer for header construction */ struct Curl_hash streams; /* hash `data->mid` to `h3_stream_ctx` */ @@ -2311,12 +2310,6 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf, CF_DATA_SAVE(save, cf, data); - if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) { - /* Not time yet to attempt the next connect */ - CURL_TRC_CF(data, cf, "waiting for reconnect time"); - goto out; - } - if(!ctx->qconn) { ctx->started_at = now; result = cf_connect_start(cf, data, &pktx); diff --git a/libs/libcurl/src/vquic/curl_osslq.c b/libs/libcurl/src/vquic/curl_osslq.c index 1f83726e93..4ceceb5ad0 100644 --- a/libs/libcurl/src/vquic/curl_osslq.c +++ b/libs/libcurl/src/vquic/curl_osslq.c @@ -288,7 +288,6 @@ struct cf_osslq_ctx { struct curltime started_at; /* time the current attempt started */ struct curltime handshake_at; /* time connect handshake finished */ struct curltime first_byte_at; /* when first byte was recvd */ - struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ struct Curl_hash streams; /* hash `data->mid` to `h3_stream_ctx` */ size_t max_stream_window; /* max flow window for one stream */ @@ -1686,12 +1685,6 @@ static CURLcode cf_osslq_connect(struct Curl_cfilter *cf, now = Curl_now(); CF_DATA_SAVE(save, cf, data); - if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) { - /* Not time yet to attempt the next connect */ - CURL_TRC_CF(data, cf, "waiting for reconnect time"); - goto out; - } - if(!ctx->tls.ossl.ssl) { ctx->started_at = now; result = cf_osslq_ctx_start(cf, data); diff --git a/libs/libcurl/src/vquic/curl_quiche.c b/libs/libcurl/src/vquic/curl_quiche.c index 61b97e2119..fb84f9d709 100644 --- a/libs/libcurl/src/vquic/curl_quiche.c +++ b/libs/libcurl/src/vquic/curl_quiche.c @@ -96,7 +96,6 @@ struct cf_quiche_ctx { uint8_t scid[QUICHE_MAX_CONN_ID_LEN]; struct curltime started_at; /* time the current attempt started */ struct curltime handshake_at; /* time connect handshake finished */ - struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ struct Curl_hash streams; /* hash `data->mid` to `stream_ctx` */ curl_off_t data_recvd; @@ -1406,13 +1405,6 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, *done = FALSE; vquic_ctx_update_time(&ctx->q); - if(ctx->reconnect_at.tv_sec && - Curl_timediff(ctx->q.last_op, ctx->reconnect_at) < 0) { - /* Not time yet to attempt the next connect */ - CURL_TRC_CF(data, cf, "waiting for reconnect time"); - goto out; - } - if(!ctx->qconn) { result = cf_quiche_ctx_open(cf, data); if(result) diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c index 668c24dd43..18284eeffd 100644 --- a/libs/libcurl/src/vtls/rustls.c +++ b/libs/libcurl/src/vtls/rustls.c @@ -216,15 +216,15 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, } rresult = rustls_connection_read(rconn, - (uint8_t *)plainbuf + plain_bytes_copied, - plainlen - plain_bytes_copied, - &n); + (uint8_t *)plainbuf + plain_bytes_copied, + plainlen - plain_bytes_copied, + &n); if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) { backend->data_in_pending = FALSE; } else if(rresult == RUSTLS_RESULT_UNEXPECTED_EOF) { failf(data, "rustls: peer closed TCP connection " - "without first closing TLS connection"); + "without first closing TLS connection"); *err = CURLE_RECV_ERROR; nread = -1; goto out; @@ -436,7 +436,7 @@ cr_get_selected_ciphers(struct Curl_easy *data, size_t *selected_size) { size_t supported_len = *selected_size; - size_t default_len = rustls_default_ciphersuites_len(); + size_t default_len = rustls_default_crypto_provider_ciphersuites_len(); const struct rustls_supported_ciphersuite *entry; const char *ciphers = ciphers12; size_t count = 0, default13_count = 0, i, j; @@ -447,10 +447,9 @@ cr_get_selected_ciphers(struct Curl_easy *data, if(!ciphers13) { /* Add default TLSv1.3 ciphers to selection */ for(j = 0; j < default_len; j++) { - struct rustls_str s; - entry = rustls_default_ciphersuites_get_entry(j); - s = rustls_supported_ciphersuite_get_name(entry); - if(s.len < 5 || strncmp(s.data, "TLS13", 5) != 0) + entry = rustls_default_crypto_provider_ciphersuites_get(j); + if(rustls_supported_ciphersuite_protocol_version(entry) != + RUSTLS_TLS_VERSION_TLSV1_3) continue; selected[count++] = entry; @@ -471,7 +470,7 @@ add_ciphers: /* Check if cipher is supported */ if(id) { for(i = 0; i < supported_len; i++) { - entry = rustls_all_ciphersuites_get_entry(i); + entry = rustls_default_crypto_provider_ciphersuites_get(i); if(rustls_supported_ciphersuite_get_suite(entry) == id) break; } @@ -505,10 +504,9 @@ add_ciphers: if(!ciphers12) { /* Add default TLSv1.2 ciphers to selection */ for(j = 0; j < default_len; j++) { - struct rustls_str s; - entry = rustls_default_ciphersuites_get_entry(j); - s = rustls_supported_ciphersuite_get_name(entry); - if(s.len < 5 || strncmp(s.data, "TLS13", 5) == 0) + entry = rustls_default_crypto_provider_ciphersuites_get(j); + if(rustls_supported_ciphersuite_protocol_version(entry) == + RUSTLS_TLS_VERSION_TLSV1_3) continue; /* No duplicates allowed (so selected cannot overflow) */ @@ -529,6 +527,8 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, { struct ssl_connect_data *connssl = cf->ctx; struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); + struct rustls_crypto_provider_builder *custom_provider_builder = NULL; + const struct rustls_crypto_provider *custom_provider = NULL; struct rustls_connection *rconn = NULL; struct rustls_client_config_builder *config_builder = NULL; const struct rustls_root_cert_store *roots = NULL; @@ -554,7 +554,8 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, }; size_t tls_versions_len = 2; const struct rustls_supported_ciphersuite **cipher_suites; - size_t cipher_suites_len = rustls_default_ciphersuites_len(); + size_t cipher_suites_len = + rustls_default_crypto_provider_ciphersuites_len(); switch(conn_config->version) { case CURL_SSLVERSION_DEFAULT: @@ -604,8 +605,35 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, return CURLE_SSL_CIPHER; } - result = rustls_client_config_builder_new_custom(cipher_suites, - cipher_suites_len, + result = rustls_crypto_provider_builder_new_from_default( + &custom_provider_builder); + if(result != RUSTLS_RESULT_OK) { + failf(data, + "rustls: failed to create crypto provider builder from default"); + return CURLE_SSL_ENGINE_INITFAILED; + } + + result = + rustls_crypto_provider_builder_set_cipher_suites( + custom_provider_builder, + cipher_suites, + cipher_suites_len); + if(result != RUSTLS_RESULT_OK) { + failf(data, + "rustls: failed to set ciphersuites for crypto provider builder"); + rustls_crypto_provider_builder_free(custom_provider_builder); + return CURLE_SSL_ENGINE_INITFAILED; + } + + result = rustls_crypto_provider_builder_build( + custom_provider_builder, &custom_provider); + if(result != RUSTLS_RESULT_OK) { + failf(data, "rustls: failed to build custom crypto provider"); + rustls_crypto_provider_builder_free(custom_provider_builder); + return CURLE_SSL_ENGINE_INITFAILED; + } + + result = rustls_client_config_builder_new_custom(custom_provider, tls_versions, tls_versions_len, &config_builder); @@ -616,6 +644,9 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, } } + rustls_crypto_provider_builder_free(custom_provider_builder); + rustls_crypto_provider_free(custom_provider); + if(connssl->alpn) { struct alpn_proto_buf proto; rustls_slice_bytes alpn[ALPN_ENTRIES_MAX]; @@ -646,8 +677,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, if(result != RUSTLS_RESULT_OK) { failf(data, "rustls: failed to parse trusted certificates from blob"); rustls_root_cert_store_builder_free(roots_builder); - rustls_client_config_free( - rustls_client_config_builder_build(config_builder)); + rustls_client_config_builder_free(config_builder); return CURLE_SSL_CACERT_BADFILE; } } @@ -658,8 +688,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, if(result != RUSTLS_RESULT_OK) { failf(data, "rustls: failed to load trusted certificates"); rustls_root_cert_store_builder_free(roots_builder); - rustls_client_config_free( - rustls_client_config_builder_build(config_builder)); + rustls_client_config_builder_free(config_builder); return CURLE_SSL_CACERT_BADFILE; } } @@ -667,9 +696,8 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, result = rustls_root_cert_store_builder_build(roots_builder, &roots); rustls_root_cert_store_builder_free(roots_builder); if(result != RUSTLS_RESULT_OK) { - failf(data, "rustls: failed to load trusted certificates"); - rustls_client_config_free( - rustls_client_config_builder_build(config_builder)); + failf(data, "rustls: failed to build trusted root certificate store"); + rustls_client_config_builder_free(config_builder); return CURLE_SSL_CACERT_BADFILE; } @@ -702,10 +730,9 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, verifier_builder, &server_cert_verifier); rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); if(result != RUSTLS_RESULT_OK) { - failf(data, "rustls: failed to load trusted certificates"); + failf(data, "rustls: failed to build certificate verifier"); rustls_server_cert_verifier_free(server_cert_verifier); - rustls_client_config_free( - rustls_client_config_builder_build(config_builder)); + rustls_client_config_builder_free(config_builder); return CURLE_SSL_CACERT_BADFILE; } @@ -714,7 +741,15 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, rustls_server_cert_verifier_free(server_cert_verifier); } - backend->config = rustls_client_config_builder_build(config_builder); + result = rustls_client_config_builder_build( + config_builder, + &backend->config); + if(result != RUSTLS_RESULT_OK) { + failf(data, "rustls: failed to build client config"); + rustls_client_config_free(backend->config); + return CURLE_SSL_ENGINE_INITFAILED; + } + DEBUGASSERT(rconn == NULL); result = rustls_client_connection_new(backend->config, connssl->peer.hostname, &rconn); @@ -810,10 +845,7 @@ cr_connect_common(struct Curl_cfilter *cf, /* REALLY Done with the handshake. */ { uint16_t proto = rustls_connection_get_protocol_version(rconn); - const rustls_supported_ciphersuite *rcipher = - rustls_connection_get_negotiated_ciphersuite(rconn); - uint16_t cipher = rcipher ? - rustls_supported_ciphersuite_get_suite(rcipher) : 0; + uint16_t cipher = rustls_connection_get_negotiated_ciphersuite(rconn); char buf[64] = ""; const char *ver = "TLS version unknown"; if(proto == RUSTLS_TLS_VERSION_TLSV1_3) @@ -1024,6 +1056,16 @@ static size_t cr_version(char *buffer, size_t size) return msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data); } +static CURLcode +cr_random(struct Curl_easy *data, unsigned char *entropy, size_t length) +{ + rustls_result rresult = 0; + (void)data; + rresult = + rustls_default_crypto_provider_random(entropy, length); + return map_error(rresult); +} + const struct Curl_ssl Curl_ssl_rustls = { { CURLSSLBACKEND_RUSTLS, "rustls" }, SSLSUPP_CAINFO_BLOB | /* supports */ @@ -1038,7 +1080,7 @@ const struct Curl_ssl Curl_ssl_rustls = { Curl_none_check_cxn, /* check_cxn */ cr_shutdown, /* shutdown */ cr_data_pending, /* data_pending */ - Curl_weak_random, /* random */ + cr_random, /* random */ Curl_none_cert_status_request, /* cert_status_request */ cr_connect_blocking, /* connect */ cr_connect_nonblocking, /* connect_nonblocking */ diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index 10c78c386e..c716b2c6f8 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -93,7 +93,7 @@ CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, void Curl_ssl_conn_config_cleanup(struct connectdata *conn); /** - * Return TRUE iff SSL configuration from `conn` is functionally the + * Return TRUE iff SSL configuration from `data` is functionally the * same as the one on `candidate`. * @param proxy match the proxy SSL config or the main one */ -- cgit v1.2.3