summaryrefslogtreecommitdiff
path: root/libs/libcurl
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2023-07-20 15:51:36 +0300
committerdartraiden <wowemuh@gmail.com>2023-07-20 16:02:00 +0300
commit1bec902c5a0b0161158aff935761dcb5754697d4 (patch)
treed97807c76c8a32b1dc9653655a34c8480d17fedb /libs/libcurl
parentf7e76bcda435d7ca6f6c8f9d78ceba5ad2066d16 (diff)
libcurl: update to 8.2.0
Diffstat (limited to 'libs/libcurl')
-rw-r--r--libs/libcurl/docs/CHANGES3396
-rw-r--r--libs/libcurl/docs/THANKS32
-rw-r--r--libs/libcurl/include/curl/curl.h16
-rw-r--r--libs/libcurl/include/curl/curlver.h10
-rw-r--r--libs/libcurl/include/curl/system.h47
-rw-r--r--libs/libcurl/include/curl/typecheck-gcc.h1
-rw-r--r--libs/libcurl/include/curl/websockets.h4
-rw-r--r--libs/libcurl/libcurl.vcxproj4
-rw-r--r--libs/libcurl/libcurl.vcxproj.filters6
-rw-r--r--libs/libcurl/src/CMakeLists.txt6
-rw-r--r--libs/libcurl/src/Makefile.in62
-rw-r--r--libs/libcurl/src/Makefile.inc3
-rw-r--r--libs/libcurl/src/altsvc.c5
-rw-r--r--libs/libcurl/src/base64.c6
-rw-r--r--libs/libcurl/src/bufq.c29
-rw-r--r--libs/libcurl/src/c-hyper.c11
-rw-r--r--libs/libcurl/src/cf-h1-proxy.c120
-rw-r--r--libs/libcurl/src/cf-h2-proxy.c531
-rw-r--r--libs/libcurl/src/cf-haproxy.c7
-rw-r--r--libs/libcurl/src/cf-https-connect.c10
-rw-r--r--libs/libcurl/src/cf-socket.c77
-rw-r--r--libs/libcurl/src/cfilters.c4
-rw-r--r--libs/libcurl/src/config-win32.h7
-rw-r--r--libs/libcurl/src/conncache.h3
-rw-r--r--libs/libcurl/src/connect.c2
-rw-r--r--libs/libcurl/src/cookie.c9
-rw-r--r--libs/libcurl/src/curl_config.h.cmake6
-rw-r--r--libs/libcurl/src/curl_config.h.in14
-rw-r--r--libs/libcurl/src/curl_log.c6
-rw-r--r--libs/libcurl/src/curl_log.h31
-rw-r--r--libs/libcurl/src/curl_memory.h58
-rw-r--r--libs/libcurl/src/curl_printf.h1
-rw-r--r--libs/libcurl/src/curl_sasl.c18
-rw-r--r--libs/libcurl/src/curl_setup.h12
-rw-r--r--libs/libcurl/src/curl_setup_once.h6
-rw-r--r--libs/libcurl/src/easy.c18
-rw-r--r--libs/libcurl/src/easy_lock.h4
-rw-r--r--libs/libcurl/src/easyoptions.c7
-rw-r--r--libs/libcurl/src/fopen.c14
-rw-r--r--libs/libcurl/src/ftp.c130
-rw-r--r--libs/libcurl/src/getinfo.c7
-rw-r--r--libs/libcurl/src/hostip.c21
-rw-r--r--libs/libcurl/src/hsts.c5
-rw-r--r--libs/libcurl/src/http.c15
-rw-r--r--libs/libcurl/src/http1.c129
-rw-r--r--libs/libcurl/src/http1.h4
-rw-r--r--libs/libcurl/src/http2.c324
-rw-r--r--libs/libcurl/src/imap.c96
-rw-r--r--libs/libcurl/src/krb5.c2
-rw-r--r--libs/libcurl/src/ldap.c8
-rw-r--r--libs/libcurl/src/libcurl.plist6
-rw-r--r--libs/libcurl/src/macos.c62
-rw-r--r--libs/libcurl/src/macos.h38
-rw-r--r--libs/libcurl/src/mime.c16
-rw-r--r--libs/libcurl/src/mqtt.c2
-rw-r--r--libs/libcurl/src/multi.c57
-rw-r--r--libs/libcurl/src/pop3.c44
-rw-r--r--libs/libcurl/src/sendf.c2
-rw-r--r--libs/libcurl/src/setopt.c11
-rw-r--r--libs/libcurl/src/smb.c195
-rw-r--r--libs/libcurl/src/smb.h197
-rw-r--r--libs/libcurl/src/smtp.c44
-rw-r--r--libs/libcurl/src/socks.c4
-rw-r--r--libs/libcurl/src/telnet.c5
-rw-r--r--libs/libcurl/src/timeval.c16
-rw-r--r--libs/libcurl/src/transfer.c20
-rw-r--r--libs/libcurl/src/url.c38
-rw-r--r--libs/libcurl/src/urlapi.c93
-rw-r--r--libs/libcurl/src/urldata.h16
-rw-r--r--libs/libcurl/src/version.c4
-rw-r--r--libs/libcurl/src/vquic/curl_msh3.c5
-rw-r--r--libs/libcurl/src/vquic/curl_ngtcp2.c427
-rw-r--r--libs/libcurl/src/vquic/curl_quiche.c26
-rw-r--r--libs/libcurl/src/vquic/vquic.c6
-rw-r--r--libs/libcurl/src/vssh/libssh2.c26
-rw-r--r--libs/libcurl/src/vssh/wolfssh.c2
-rw-r--r--libs/libcurl/src/vtls/bearssl.c32
-rw-r--r--libs/libcurl/src/vtls/gskit.c14
-rw-r--r--libs/libcurl/src/vtls/gtls.c42
-rw-r--r--libs/libcurl/src/vtls/mbedtls.c32
-rw-r--r--libs/libcurl/src/vtls/nss.c81
-rw-r--r--libs/libcurl/src/vtls/openssl.c81
-rw-r--r--libs/libcurl/src/vtls/rustls.c34
-rw-r--r--libs/libcurl/src/vtls/schannel.c64
-rw-r--r--libs/libcurl/src/vtls/schannel.h116
-rw-r--r--libs/libcurl/src/vtls/schannel_int.h142
-rw-r--r--libs/libcurl/src/vtls/schannel_verify.c4
-rw-r--r--libs/libcurl/src/vtls/sectransp.c43
-rw-r--r--libs/libcurl/src/vtls/vtls.c23
-rw-r--r--libs/libcurl/src/vtls/vtls_int.h3
-rw-r--r--libs/libcurl/src/vtls/wolfssl.c73
-rw-r--r--libs/libcurl/src/warnless.c10
-rw-r--r--libs/libcurl/src/warnless.h10
-rw-r--r--libs/libcurl/src/ws.c30
94 files changed, 4061 insertions, 3479 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES
index 3fe822bc9e..93b451ed04 100644
--- a/libs/libcurl/docs/CHANGES
+++ b/libs/libcurl/docs/CHANGES
@@ -6,6 +6,1590 @@
Changelog
+Version 8.2.0 (19 Jul 2023)
+
+Daniel Stenberg (19 Jul 2023)
+
+- RELEASE-NOTES: synced
+
+ 8.2.0 release
+
+- THANKS-filter: strip out "GitHub"
+
+- THANKS: add contributors from 8.2.0
+
+- RELEASE-PROCEDURE.md: adjust the release dates
+
+Stefan Eissing (17 Jul 2023)
+
+- quiche: fix defects found in latest coverity report
+
+ Closes #11455
+
+Daniel Stenberg (17 Jul 2023)
+
+- quiche: avoid NULL deref in debug logging
+
+ Coverity reported "Dereference after null check"
+
+ If stream is NULL and the function exits, the logging must not deref it.
+
+ Closes #11454
+
+Stefan Eissing (17 Jul 2023)
+
+- http2: treat initial SETTINGS as a WINDOW_UPDATE
+
+ - refs #11426 where spurious stalls on large POST requests
+ are reported
+ - the issue seems to involve the following
+ * first stream on connection adds up to 64KB of POST
+ data, which is the max default HTTP/2 stream window size
+ transfer is set to HOLD
+ * initial SETTINGS from server arrive, enlarging the stream
+ window. But no WINDOW_UPDATE is received.
+ * curl stalls
+ - the fix un-HOLDs a stream on receiving SETTINGS, not
+ relying on a WINDOW_UPDATE from lazy servers
+
+ Closes #11450
+
+Daniel Stenberg (17 Jul 2023)
+
+- ngtcp2: assigning timeout, but value is overwritten before used
+
+ Reported by Coverity
+
+ Closes #11453
+
+- krb5: add typecast to please Coverity
+
+Derzsi Dániel (16 Jul 2023)
+
+- wolfssl: support setting CA certificates as blob
+
+ Closes #11445
+
+- wolfssl: detect when TLS 1.2 support is not built into wolfssl
+
+ Closes #11444
+
+Graham Campbell (15 Jul 2023)
+
+- CI: bump nghttp2 from 1.55.0 to 1.55.1
+
+ Closes #11442
+
+Daniel Stenberg (15 Jul 2023)
+
+- curl: return error when asked to use an unsupported HTTP version
+
+ When one of the following options are used but the libcurl in use does
+ not support it:
+
+ --http2
+ --http2-prior-knowledge
+ --proxy-http2
+
+ Closes #11440
+
+Chris Paulson-Ellis (14 Jul 2023)
+
+- cf-socket: don't bypass fclosesocket callback if cancelled before connect
+
+ After upgrading to 8.1.2 from 7.84.0, I found that sockets were being
+ closed without calling the fclosesocket callback if a request was
+ cancelled after the associated socket was created, but before the socket
+ was connected. This lead to an imbalance of fopensocket & fclosesocket
+ callbacks, causing problems with a custom event loop integration using
+ the multi-API.
+
+ This was caused by cf_socket_close() calling sclose() directly instead
+ of calling socket_close() if the socket was not active. For regular TCP
+ client connections, the socket is activated by cf_socket_active(), which
+ is only called when the socket completes the connect.
+
+ As far as I can tell, this issue has existed since 7.88.0. That is,
+ since the code in question was introduced by:
+ commit 71b7e0161032927cdfb4e75ea40f65b8898b3956
+ Author: Stefan Eissing <stefan@eissing.org>
+ Date: Fri Dec 30 09:14:55 2022 +0100
+
+ lib: connect/h2/h3 refactor
+
+ Closes #11439
+
+Daniel Stenberg (13 Jul 2023)
+
+- tool_parsecfg: accept line lengths up to 10M
+
+ Bumped from 100K set in 47dd957daff9
+
+ Reported-by: Antoine du Hamel
+ Fixes #11431
+ Closes #11435
+
+Stefan Eissing (13 Jul 2023)
+
+- CI: brew fix for openssl in default path
+
+ If brew install/update links openssl into /usr/local, it will be found
+ before anything we add with `-isystem path` to CPP/LDLFAGS. Get rid of
+ that by unlinking the keg.
+
+ Fixes #11413
+ Closes #11436
+
+Daniel Stenberg (13 Jul 2023)
+
+- RELEASE-NOTES: synced
+
+Ondřej Koláček (13 Jul 2023)
+
+- sectransp: fix EOF handling
+
+ Regression since the large refactor from 2022
+
+ Closes #11427
+
+Daniel Stenberg (13 Jul 2023)
+
+- checksrc: quote the file name to work with "funny" letters
+
+ Closes #11437
+
+Karthikdasari0423 (13 Jul 2023)
+
+- HTTP3.md: ngtcp2 updated to v0.17.0 and nghttp3 to v0.13.0
+
+ Follow-up to e0093b4b732f6
+
+ Closes #11433
+
+Daniel Stenberg (13 Jul 2023)
+
+- CURLOPT_MIMEPOST.3: clarify what setting to NULL means
+
+ Follow-up to e08382a208d4e480
+
+ Closes #11430
+
+Tatsuhiro Tsujikawa (12 Jul 2023)
+
+- ngtcp2: build with 0.17.0 and nghttp3 0.13.0
+
+ - ngtcp2_crypto_openssl was renamed to ngtcp2_crypto_quictls.
+
+ Closes #11428
+
+- CI: Bump ngtcp2, nghttp3, and nghttp2
+
+ Closes #11428
+
+James Fuller (11 Jul 2023)
+
+- example/maxconnects: set maxconnect example
+
+ Closes #11343
+
+Pontakorn Prasertsuk (11 Jul 2023)
+
+- http2: send HEADER & DATA together if possible
+
+ Closes #11420
+
+Daniel Stenberg (11 Jul 2023)
+
+- CI: use wolfSSL 5.6.3 in builds
+
+ No using master anymore
+
+ Closes #11424
+
+SaltyMilk (11 Jul 2023)
+
+- fopen: optimize
+
+ Closes #11419
+
+Daniel Stenberg (11 Jul 2023)
+
+- cmake: make use of snprintf
+
+ Follow-up to 935b1bd4544a23a91d68
+
+ Closes #11423
+
+Stefan Eissing (11 Jul 2023)
+
+- macOS: fix taget detection
+
+ - TARGET_OS_OSX is not always defined on macOS
+ - this leads to missing symbol Curl_macos_init()
+ - TargetConditionals.h seems to define these only when
+ dynamic targets are enabled (somewhere?)
+ - this PR fixes that on my macOS 13.4.1
+ - I have no clue why CI builds worked without it
+
+ Follow-up to c7308592fb8ba213fc2c1
+ Closes #11417
+
+Stan Hu (9 Jul 2023)
+
+- hostip.c: Move macOS-specific calls into global init call
+
+ https://github.com/curl/curl/pull/7121 introduced a macOS system call
+ to `SCDynamicStoreCopyProxies`, which is invoked every time an IP
+ address needs to be resolved.
+
+ However, this system call is not thread-safe, and macOS will kill the
+ process if the system call is run first in a fork. To make it possible
+ for the parent process to call this once and prevent the crash, only
+ invoke this system call in the global initialization routine.
+
+ In addition, this change is beneficial because it:
+
+ 1. Avoids extra macOS system calls for every IP lookup.
+ 2. Consolidates macOS-specific initialization in a separate file.
+
+ Fixes #11252
+ Closes #11254
+
+Daniel Stenberg (9 Jul 2023)
+
+- docs: use a space after RFC when spelling out RFC numbers
+
+ Closes #11382
+
+Margu (9 Jul 2023)
+
+- imap-append.c: update to make it more likely to work
+
+ Fixes #10300
+ Closes #11397
+
+Emanuele Torre (9 Jul 2023)
+
+- tool_writeout_json: fix encoding of control characters
+
+ Control characters without a special escape sequence e.g. %00 or %06
+ were being encoded as "u0006" instead of "\u0006".
+
+ Ref: https://github.com/curl/trurl/pull/214#discussion_r1257487858
+ Closes #11414
+
+Stefan Eissing (9 Jul 2023)
+
+- http3/ngtcp2: upload EAGAIN handling
+
+ - refs #11389 where IDLE timeouts on upload are reported
+ - reword ngtcp2 expiry handling to apply to both send+recv
+ calls into the filter
+ - EAGAIN uploads similar to the recent changes in HTTP/2, e.g.
+ report success only when send data was ACKed.
+ - HOLD sending of EAGAINed uploads to avoid cpu busy loops
+ - rename internal function for consistency with HTTP/2
+ implementation
+
+ Fixes #11389
+ Closes #11390
+
+Brian Nixon (9 Jul 2023)
+
+- tool_easysrc.h: correct `easysrc_perform` for `CURL_DISABLE_LIBCURL_OPTION`
+
+ Closes #11398
+
+Daniel Stenberg (9 Jul 2023)
+
+- RELEASE-NOTES: synced
+
+- transfer: clear credentials when redirecting to absolute URL
+
+ Make sure the user and password for the second request is taken from the
+ redirected-to URL.
+
+ Add test case 899 to verify.
+
+ Reported-by: James Lucas
+ Fixes #11410
+ Closes #11412
+
+Stefan Eissing (8 Jul 2023)
+
+- hyper: fix EOF handling on input
+
+ We ran out of disc space due to an infinite loop with debug logging
+
+ Fixes #11377
+ Closes #11385
+ Reported-by: Dan Fandrich
+
+- http2: raise header limitations above and beyond
+
+ - not quite to infinity
+ - rewrote the implementation of our internal HTTP/1.x request
+ parsing to work with very large lines using dynbufs.
+ - new default limit is `DYN_HTTP_REQUEST`, aka 1MB, which
+ is also the limit of curl's general HTTP request processing.
+
+ Fixes #11405
+ Closes #11407
+
+Juan Cruz Viotti (8 Jul 2023)
+
+- curl_easy_nextheader.3: add missing open parenthesis examples
+
+ Closes #11409
+ Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
+
+Dan Fandrich (7 Jul 2023)
+
+- CI: enable verbose test output on pytest
+
+ This shows individual pass/fail status on tests and makes this output
+ consistent with other jobs' pytest invocations.
+
+Stefan Eissing (28 Jun 2023)
+
+- http2: fix crash in handling stream weights
+
+ - Delay the priority handling until the stream has been opened.
+
+ - Add test2404 to reproduce and verify.
+
+ Weights may change "on the run", which is why there are checks in
+ general egress handling. These must not trigger when the stream has not
+ been opened yet.
+
+ Reported-by: jbgoog@users.noreply.github.com
+
+ Fixes https://github.com/curl/curl/issues/11379
+ Closes https://github.com/curl/curl/pull/11384
+
+- tests/http: Add mod_h2 directive `H2ProxyRequests`
+
+ master of mod_h2 now requires H2ProxyRequests directives for forward
+ proxying with HTTP/2 to work.
+
+ Ref: https://github.com/icing/mod_h2/commit/3897a7086
+
+ Closes https://github.com/curl/curl/pull/11392
+
+Dan Fandrich (28 Jun 2023)
+
+- CI: make Appveyor job names unique
+
+ Two otherwise identical mingw-w64 jobs now have their differing compiler
+ versions mentioned in their names.
+
+Sheshadri.V (25 Jun 2023)
+
+- curl.h: include <sys/select.h> for vxworks
+
+ Closes #11356
+
+Dan Fandrich (24 Jun 2023)
+
+- CI: enable parallel make in more builds
+
+ Most CI services provide at least two cores, so enable parallel make
+ jobs to take advantage of that for builds. Some dependencies aren't safe
+ to build in parallel so leave those as-is. Also, rename a few
+ workflows to eliminate duplicate names and provide a better idea what
+ they're about.
+
+- CI: don't install impacket if tests are not run
+
+ It just wastes time and bandwidth and isn't even used.
+
+divinity76 (24 Jun 2023)
+
+- configure: the --without forms of the options are also gone
+
+ --without-darwin-ssl and --without-metalink
+
+ Closes #11378
+
+Daniel Stenberg (23 Jun 2023)
+
+- configure: add check for ldap_init_fd
+
+ ... as otherwise the configure script will say it is OpenLDAP in the
+ summary, but not set the USE_OPENLDAP define, therefor not using the
+ intended OpenLDAP code paths.
+
+ Regression since 4d7385446 (7.85.0)
+ Fixes #11372
+ Closes #11374
+ Reported-by: vlkl-sap on github
+
+Michał Petryka (23 Jun 2023)
+
+- cmake: stop CMake from quietly ignoring missing Brotli
+
+ The CMake project was set to `QUIET` for Brotli instead of
+ `REQUIRED`. This makes builds unexpectedly ignore missing Brotli even
+ when `CURL_BROTLI` is enabled.
+
+ Closes #11376
+
+Emanuele Torre (22 Jun 2023)
+
+- docs: add more .IP after .RE to fix indentation of generate paragraphs
+
+ follow-up from 099f41e097c030077b8ec078f2c2d4038d31353b
+
+ I just thought of checking all the other files with .RE, and I found 6
+ other files that were missing .IP at the end.
+
+ Closes #11375
+
+Stefan Eissing (22 Jun 2023)
+
+- http2: h2 and h2-PROXY connection alive check fixes
+
+ - fix HTTP/2 check to not declare a connection dead when
+ the read attempt results in EAGAIN
+ - add H2-PROXY alive check as for HTTP/2 that was missing
+ and is needed
+ - add attach/detach around Curl_conn_is_alive() and remove
+ these in filter methods
+ - add checks for number of connections used in some test_10
+ proxy tunneling tests
+
+ Closes #11368
+
+- http2: error stream resets with code CURLE_HTTP2_STREAM
+
+ - refs #11357, where it was reported that HTTP/1.1 downgrades
+ no longer works
+ - fixed with suggested change
+ - added test_05_03 and a new handler in the curltest module
+ to reproduce that downgrades work
+
+ Fixes #11357
+ Closes #11362
+ Reported-by: Jay Satiro
+
+Daniel Stenberg (22 Jun 2023)
+
+- connect-timeout.d: mention that the DNS lookup is included
+
+ Closes #11370
+
+Emanuele Torre (22 Jun 2023)
+
+- quote.d: fix indentation of generated paragraphs
+
+ quote.d was missing a .IP at the end which caused the paragraphs
+ generated for See-also, Multi, and Example to not be indented correctly.
+
+ I also remove a redundant "This option can be used multiple times.", and
+ replaced .IP "item" with .TP .B "item" to make more clear which lines
+ are part of the list of commands and which aren't.
+
+ Closes #11371
+
+Paul Wise (22 Jun 2023)
+
+- checksrc: modernise perl file open
+
+ Use regular variables and separate file open modes from filenames.
+
+ Suggested by perlcritic
+
+ Copied from https://github.com/curl/trurl/commit/f2784a9240f47ee28a845
+
+ Closes #11358
+
+Dan Fandrich (21 Jun 2023)
+
+- runtests: work around a perl without SIGUSR1
+
+ At least msys2 perl v5.32.1 doesn't seem to define this signal. Since
+ this signal is only used for debugging, just ignore if setting it fails.
+
+ Reported-by: Marcel Raad
+ Fixes #11350
+ Closes #11366
+
+- runtests: include missing valgrind package
+
+ use valgrind was missing which caused torture tests with valgrind
+ enabled to fail.
+
+ Reported-by: Daniel Stenberg
+ Fixes #11364
+ Closes #11365
+
+- runtests: use more consistent failure lines
+
+ After a test failure log a consistent log message to make it easier to
+ parse the log file. Also, log a consistent message with "ignored" for
+ failures that cause the test to be not considered at all. These should
+ perhaps be counted in the skipped category, but this commit does not
+ change that behaviour.
+
+- runtests: consistently write the test check summary block
+
+ The memory check character was erroneously omitted if the memory
+ checking file was not available for some reason, making the block of
+ characters an inconsistent length.
+
+- test2600: fix the description
+
+ It looks like it was cut-and-pasted.
+
+ Closes #11354
+
+Daniel Stenberg (21 Jun 2023)
+
+- TODO: "Support HTTP/2 for HTTP(S) proxies" *done*
+
+humbleacolyte (21 Jun 2023)
+
+- cf-socket: move ctx declaration under HAVE_GETPEERNAME
+
+ Closes #11352
+
+Daniel Stenberg (20 Jun 2023)
+
+- RELEASE-NOTES: synced
+
+- example/connect-to: show CURLOPT_CONNECT_TO
+
+ Closes #11340
+
+Stefan Eissing (20 Jun 2023)
+
+- hyper: unslow
+
+ - refs #11203 where hyper was reported as being slow
+ - fixes hyper_executor_poll to loop until it is out of
+ tasks as advised by @seanmonstar in https://github.com/hyperium/hyper/issue
+ s/3237
+ - added a fix in hyper io handling for detecting EAGAIN
+ - added some debug logs to see IO results
+ - pytest http/1.1 test cases pass
+ - pytest h2 test cases fail on connection reuse. HTTP/2
+ connection reuse does not seem to work. Hyper submits
+ a request on a reused connection, curl's IO works and
+ thereafter hyper declares `Hyper: [1] operation was canceled: connection cl
+ osed`
+ on stderr without any error being logged before.
+
+ Fixes #11203
+ Reported-by: Gisle Vanem
+ Advised-by: Sean McArthur
+ Closes #11344
+
+- HTTP/2: upload handling fixes
+
+ - fixes #11242 where 100% CPU on uploads was reported
+ - fixes possible stalls on last part of a request body when
+ that information could not be fully send on the connection
+ due to an EAGAIN
+ - applies the same EGAIN handling to HTTP/2 proxying
+
+ Reported-by: Sergey Alirzaev
+ Fixed #11242
+ Closes #11342
+
+Daniel Stenberg (20 Jun 2023)
+
+- example/opensslthreadlock: remove
+
+ This shows how to setup OpenSSL mutex callbacks, but this is not
+ necessary since OpenSSL 1.1.0 - meaning that no currently supported
+ OpenSSL version requires this anymore
+
+ Closes #11341
+
+Dan Fandrich (19 Jun 2023)
+
+- libtest: display the times after a test timeout error
+
+ This is to help with test failure debugging.
+
+ Ref: #11328
+ Closes #11329
+
+- test2600: bump a test timeout
+
+ Case 1 failed at least once on GHA by going 30 msec too long.
+
+ Ref: #11328
+
+- runtests: better detect and handle pipe errors in the controller
+
+ Errors reading and writing to the pipes are now better detected and
+ propagated up to the main test loop so it can be cleanly shut down. Such
+ errors are usually due to a runner dying so it doesn't make much sense
+ to try to continue the test run.
+
+- runtests: cleanly abort the runner if the controller dies
+
+ If the controller dies unexpectedly, have the runner stop its servers
+ and exit cleanly. Otherwise, the orphaned servers will stay running in
+ the background.
+
+- runtests: improve error logging
+
+ Give more information about test harness error conditions to help figure
+ out what might be wrong. Print some internal test state when SIGUSR1 is
+ sent to runtests.pl.
+
+ Ref: #11328
+
+- runtests: better handle ^C during slow tests
+
+ Since the SIGINT handler now just sets a flag that must be checked in the
+ main controller loop, make sure that runs periodically. Rather than
+ blocking on a response from a test runner near the end of the test run,
+ add a short timeout to allow it.
+
+- runtests: rename server command file
+
+ The name ftpserver.cmd was historical and has been used for more than
+ ftp for many years now. Rename it to plain server.cmd to reduce
+ confusion.
+
+- tests: improve reliability of TFTP tests
+
+ Stop checking the timeout used by the client under test (for most
+ tests). The timeout will change if the TFTP test server is slow (such as
+ happens on an overprovisioned CI server) because the client will retry
+ and reduce its timeout, and the actual value is not important for most
+ tests.
+
+ test285 is changed a different way, by increasing the connect timeout.
+ This improves test coverage by allowing the changed timeout value to be
+ checked, but improves reliability with a carefully-chosen timeout that
+ not only allows twice the time to respond as before, but also allows
+ several retries before the client will change its timeout value.
+
+ Ref: #11328
+
+Daniel Stenberg (19 Jun 2023)
+
+- cf-socket: skip getpeername()/getsockname for TFTP
+
+ Since the socket is not connected then the call fails. When the call
+ fails, failf() is called to write an error message that is then
+ surviving and is returned when the *real* error occurs later. The
+ earlier, incorrect, error therefore hides the actual error message.
+
+ This could be seen in stderr for test 1007
+
+ Test 1007 has now been extended to verify the stderr message.
+
+ Closes #11332
+
+- example/crawler: make it use a few more options
+
+ For show, but reasonable
+
+- libcurl-ws.3: mention raw mode
+
+ Closes #11339
+
+- example/default-scheme: set the default scheme for schemeless URLs
+
+ Closes #11338
+
+- example/hsts-preload: show one way to HSTS preload
+
+ Closes #11337
+
+- examples/http-options: show how to send "OPTIONS *"
+
+ With CURLOPT_REQUEST_TARGET.
+
+ Also add use of CURLOPT_QUICK_EXIT to show.
+
+ Closes #11333
+
+- examples: make use of CURLOPT_(REDIR_|)PROTOCOLS_STR
+
+ To show how to use them
+
+ Closes #11334
+
+- examples/smtp-mime: use CURLOPT_MAIL_RCPT_ALLOWFAILS
+
+ For show
+
+ Closes #11335
+
+- http: rectify the outgoing Cookie: header field size check
+
+ Previously it would count the size of the entire outgoing request and
+ not just the size of only the Cookie: header field - which was the
+ intention.
+
+ This could make the check be off by several hundred bytes in some cases.
+
+ Closes #11331
+
+Jay Satiro (17 Jun 2023)
+
+- lib: fix some format specifiers
+
+ - Use CURL_FORMAT_CURL_OFF_T where %zd was erroneously used for some
+ curl_off_t variables.
+
+ - Use %zu where %zd was erroneously used for some size_t variables.
+
+ Prior to this change some of the Windows CI tests were failing because
+ in Windows 32-bit targets have a 32-bit size_t and a 64-bit curl_off_t.
+ When %zd was used for some curl_off_t variables then only the lower
+ 32-bits was read and the upper 32-bits would be read for part or all of
+ the next specifier.
+
+ Fixes https://github.com/curl/curl/issues/11327
+ Closes https://github.com/curl/curl/pull/11321
+
+Marcel Raad (16 Jun 2023)
+
+- test427: add `cookies` feature and keyword
+
+ This test doesn't work with `--disable-cookies`.
+
+ Closes https://github.com/curl/curl/pull/11320
+
+Chris Talbot (15 Jun 2023)
+
+- imap: Provide method to disable SASL if it is advertised
+
+ - Implement AUTH=+LOGIN for CURLOPT_LOGIN_OPTIONS to prefer plaintext
+ LOGIN over SASL auth.
+
+ Prior to this change there was no method to be able to fall back to
+ LOGIN if an IMAP server advertises SASL capabilities. However, this may
+ be desirable for e.g. a misconfigured server.
+
+ Per: https://www.ietf.org/rfc/rfc5092.html#section-3.2
+
+ ";AUTH=<enc-auth-type>" looks to be the correct way to specify what
+ authenication method to use, regardless of SASL or not.
+
+ Closes https://github.com/curl/curl/pull/10041
+
+Daniel Stenberg (15 Jun 2023)
+
+- RELEASE-NOTES: synced
+
+- examples/multi-debugcallback.c: avoid the bool typedef
+
+ Apparently this cannot be done in c23
+
+ Reported-by: Cristian Rodríguez
+ Fixes #11299
+ Closes #11319
+
+- docs/libcurl/libcurl.3: cleanups and improvements
+
+ Closes #11317
+
+- libcurl-ws.3: fix typo
+
+- curl_ws_*.3: enhance
+
+ - all: SEE ALSO the libcurl-ws man page
+ - send: add example and return value information
+ - meta: mention that the returned data is read-only
+
+ Closes #11318
+
+- docs/libcurl/libcurl-ws.3: see also CURLOPT_WS_OPTIONS
+
+- docs/libcurl/libcurl-ws.3: minor polish
+
+- libcurl-ws.3. WebSocket API overview
+
+ Closes #11314
+
+- libcurl-url.3: also mention CURLUPART_ZONEID
+
+ ... and sort the two part-using lists alphabetically
+
+Marcel Raad (14 Jun 2023)
+
+- fopen: fix conversion warning on 32-bit Android
+
+ When building for 32-bit ARM or x86 Android, `st_mode` is defined as
+ `unsigned int` instead of `mode_t`, resulting in a
+ -Wimplicit-int-conversion clang warning because `mode_t` is
+ `unsigned short`. Add a cast to silence the warning.
+
+ Ref: https://android.googlesource.com/platform/bionic/+/refs/tags/ndk-r25c/li
+ bc/include/sys/stat.h#86
+ Closes https://github.com/curl/curl/pull/11313
+
+- http2: fix variable type
+
+ `max_recv_speed` is `curl_off_t`, so using `size_t` might result in
+ -Wconversion GCC warnings for 32-bit `size_t`. Visible in the NetBSD
+ ARM autobuilds.
+
+ Closes https://github.com/curl/curl/pull/11312
+
+Daniel Stenberg (13 Jun 2023)
+
+- vtls: fix potentially uninitialized local variable warnings
+
+ Follow-up from a4a5e438ae533c
+
+ Closes #11310
+
+- timeval: use CLOCK_MONOTONIC_RAW if available
+
+ Reported-by: Harry Sintonen
+ Ref: #11288
+ Closes #11291
+
+Stefan Eissing (12 Jun 2023)
+
+- tool: add curl command line option `--trace-ids`
+
+ - added and documented --trace-ids to prepend (after the timestamp)
+ the transfer and connection identifiers to each verbose log line
+ - format is [n-m] with `n` being the transfer id and `m` being the
+ connection id. In case there is not valid connection id, print 'x'.
+ - Log calls with a handle that has no transfer id yet, are written
+ without any ids.
+
+ Closes #11185
+
+- lib: add CURLINFO_CONN_ID and CURLINFO_XFER_ID
+
+ - add an `id` long to Curl_easy, -1 on init
+ - once added to a multi (or its own multi), it gets
+ a non-negative number assigned by the connection cache
+ - `id` is unique among all transfers using the same
+ cache until reaching LONG_MAX where it will wrap
+ around. So, not unique eternally.
+ - CURLINFO_CONN_ID returns the connection id attached to
+ data or, if none present, data->state.lastconnect_id
+ - variables and type declared in tool for write out
+
+ Closes #11185
+
+Daniel Stenberg (12 Jun 2023)
+
+- CURLOPT_INFILESIZE.3: mention -1 triggers chunked
+
+ Ref: #11300
+ Closes #11304
+
+Philip Heiduck (12 Jun 2023)
+
+- CI: openssl-3.0.9+quic
+
+ Closes #11296
+
+Karthikdasari0423 (12 Jun 2023)
+
+- HTTP3.md: update openssl version
+
+ Closes #11297
+
+Daniel Stenberg (12 Jun 2023)
+
+- vtls: avoid memory leak if sha256 call fails
+
+ ... in the pinned public key handling function.
+
+ Reported-by: lizhuang0630 on github
+ Fixes #11306
+ Closes #11307
+
+- examples/ipv6: disable on win32
+
+ I can't make if_nametoindex() work there
+
+ Follow-up to c23dc42f3997acf23
+
+ Closes #11305
+
+- tool_operate: allow cookie lines up to 8200 bytes
+
+ Since this option might set multiple cookies in the same line, it does
+ not make total sense to cap this at 4096 bytes, which is the limit for a
+ single cookie name or value.
+
+ Closes #11303
+
+- test427: verify sending more cookies than fit in a 8190 bytes line
+
+ curl will then only populate the header with cookies that fit, dropping
+ ones that otherwise would have been sent
+
+ Ref: https://curl.se/mail/lib-2023-06/0020.html
+
+ Closes #11303
+
+- testutil: allow multiple %-operators on the same line
+
+ Closes #11303
+
+Oleg Jukovec (12 Jun 2023)
+
+- docs: update CURLOPT_UPLOAD.3
+
+ The behavior of CURLOPT_UPLOAD differs from what is described in the
+ documentation. The option automatically adds the 'Transfer-Encoding:
+ chunked' header if the upload size is unknown.
+
+ Closes #11300
+
+Daniel Stenberg (12 Jun 2023)
+
+- RELEASE-NOTES: synced
+
+- CURLOPT_AWS_SIGV4.3: remove unused variable from example
+
+ Closes #11302
+
+- examples/https.c: use CURLOPT_CA_CACHE_TIMEOUT
+
+ for demonstration purposes
+
+ Closes #11290
+
+- example/ipv6: feature CURLOPT_ADDRESS_SCOPE in use
+
+ Closes #11282
+
+Karthikdasari0423 (10 Jun 2023)
+
+- docs: Update HTTP3.md for newer ngtcp2 and nghttp3
+
+ Follow-up to fb9b9b58
+
+ Ref: #11184
+ Closes #11295
+
+Dan Fandrich (10 Jun 2023)
+
+- docs: update the supported ngtcp2 and nghttp3 versions
+
+ Follow-up to cae9d10b
+
+ Ref: #11184
+ Closes #11294
+
+- tests: fix error messages & handling around sockets
+
+ The wrong error code was checked on Windows on UNIX socket failures,
+ which could have caused all UNIX sockets to be reported as having
+ errored and the tests therefore skipped. Also, a useless error message
+ was displayed on socket errors in many test servers on Windows because
+ strerror() doesn't work on WinSock error codes; perror() is overridden
+ there to work on all errors and is used instead.
+
+ Ref #11258
+ Closes #11265
+
+Daniel Stenberg (9 Jun 2023)
+
+- CURLOPT_SSH_PRIVATE_KEYFILE.3: expand on the file search
+
+ Reported-by: atjg on github
+ Ref: #11287
+ Closes #11289
+
+Stefan Eissing (9 Jun 2023)
+
+- ngtcp2: use ever increasing timestamp in io
+
+ - ngtcp2 v0.16.0 asserts that timestamps passed to its function
+ will only ever increase.
+ - Use a context shared between ingress/egress operations that
+ uses a shared timestamp, regularly updated during calls.
+
+ Closes #11288
+
+Daniel Stenberg (9 Jun 2023)
+
+- GHA: use nghttp2 1.54.0 for the ngtcp2 jobs
+
+Philip Heiduck (9 Jun 2023)
+
+- GHA: ngtcp2: use 0.16.0 and nghttp3 0.12.0
+
+Daniel Stenberg (9 Jun 2023)
+
+- ngtcp2: build with 0.16.0 and nghttp3 0.12.0
+
+ - moved to qlog_write
+ - crypto => encryption
+ - CRYPTO => ENCRYPTION
+ - removed "_is_"
+ - ngtcp2_conn_shutdown_stream_read and
+ ngtcp2_conn_shutdown_stream_write got flag arguments
+ - the nghttp3_callbacks struct got a recv_settings callback
+
+ Closes #11184
+
+- example/http2-download: set CURLOPT_BUFFERSIZE
+
+ Primarily because no other example sets it, and remove the disabling of
+ the certificate check because we should not recommend that.
+
+ Closes #11284
+
+- example/crawler: also set CURLOPT_AUTOREFERER
+
+ Could make sense, and it was not used in any example before.
+
+ Closes #11283
+
+Wyatt OʼDay (9 Jun 2023)
+
+- tls13-ciphers.d: include Schannel
+
+ Closes #11271
+
+Daniel Stenberg (9 Jun 2023)
+
+- curl_pushheader_byname/bynum.3: document in their own man pages
+
+ These two functions were added in 7.44.0 when CURLMOPT_PUSHFUNCTION was
+ introduced but always lived a life in the shadows, embedded in the
+ CURLMOPT_PUSHFUNCTION man page. Until now.
+
+ It makes better sense and gives more visibility to document them in
+ their own stand-alone man pages.
+
+ Closes #11286
+
+- curl_mprintf.3: minor fix of the example
+
+- curl_url_set: enforce the max string length check for all parts
+
+ Update the docs and test 1559 accordingly
+
+ Closes #11273
+
+- examples/ftpuploadresume.c: add use of CURLOPT_ACCEPTTIMEOUT_MS
+
+ For show
+
+ Closes #11277
+
+- examples/unixsocket.c: example using CURLOPT_UNIX_SOCKET_PATH
+
+ and alternatively CURLOPT_ABSTRACT_UNIX_SOCKET
+
+ Closes #11276
+
+Anssi Kolehmainen (8 Jun 2023)
+
+- docs: fix missing parameter names in examples
+
+ Closes #11278
+
+Daniel Stenberg (8 Jun 2023)
+
+- urlapi: have *set(PATH) prepend a slash if one is missing
+
+ Previously the code would just do that for the path when extracting the
+ full URL, which made a subsequent curl_url_get() of the path to
+ (unexpectedly) still return it without the leading path.
+
+ Amend lib1560 to verify this. Clarify the curl_url_set() docs about it.
+
+ Bug: https://curl.se/mail/lib-2023-06/0015.html
+ Closes #11272
+ Reported-by: Pedro Henrique
+
+Dan Fandrich (7 Jun 2023)
+
+- runtests; give each server a unique log lock file
+
+ Logs are written by several servers and all of them must be finished
+ writing before the test results can be determined. This means each
+ server must have its own lock file rather than sharing a single one,
+ which is how it was done up to now. Previously, the first server to
+ complete a test would clear the lock before the other server was done,
+ which caused flaky tests.
+
+ Lock files are now all found in their own directory, so counting locks
+ equals counting the files in that directory. The result is that the
+ proxy logs are now reliably written which actually changes the expected
+ output for two tests.
+
+ Fixes #11231
+ Closes #11259
+
+- runtests: make test file directories in log/N
+
+ Test files in subdirectories were not created after parallel test log
+ directories were moved down a level due to a now-bad comparison.
+
+ Follow-up to 92d7dd39
+
+ Ref #11264
+ Closes #11267
+
+Daniel Stenberg (7 Jun 2023)
+
+- ws: make the curl_ws_meta() return pointer a const
+
+ The returned info is read-only for the user.
+
+ Closes #11261
+
+- RELEASE-NOTES: synced
+
+- runtests: move parallel log dirs from logN to log/N
+
+ Having several hundreds of them in there gets annoying.
+
+ Closes #11264
+
+Dan Fandrich (7 Jun 2023)
+
+- test447: move the test file into %LOGDIR
+
+Viktor Szakats (7 Jun 2023)
+
+- cmake: add support for "unity" builds
+
+ Aka "jumbo" or "amalgamation" builds. It means to compile all sources
+ per target as a single C source. This is experimental.
+
+ You can enable it by passing `-DCMAKE_UNITY_BUILD=ON` to cmake.
+ It requires CMake 3.16 or newer.
+
+ It makes builds (much) faster, allows for better optimizations and tends
+ to promote less ambiguous code.
+
+ Also add a new AppVeyor CI job and convert an existing one to use
+ "unity" mode (one MSVC, one MinGW), and enable it for one macOS CI job.
+
+ Fix related issues:
+ - add missing include guard to `easy_lock.h`.
+ - rename static variables and functions (and a macro) with names reused
+ across sources, or shadowed by local variables.
+ - add an `#undef` after use.
+ - add a missing `#undef` before use.
+ - move internal definitions from `ftp.h` to `ftp.c`.
+ - `curl_memory.h` fixes to make it work when included repeatedly.
+ - stop building/linking curlx bits twice for a static-mode curl tool.
+ These caused doubly defined symbols in unity builds.
+ - silence missing extern declarations compiler warning for ` _CRT_glob`.
+ - fix extern declarations for `tool_freq` and `tool_isVistaOrGreater`.
+ - fix colliding static symbols in debug mode: `debugtime()` and
+ `statename`.
+ - rename `ssl_backend_data` structure to unique names for each
+ TLS-backend, along with the `ssl_connect_data` struct member
+ referencing them. This required adding casts for each access.
+ - add workaround for missing `[P]UNICODE_STRING` types in certain Windows
+ builds when compiling `lib/ldap.c`. To support "unity" builds, we had
+ to enable `SCHANNEL_USE_BLACKLISTS` for Schannel (a Windows
+ `schannel.h` option) _globally_. This caused an indirect inclusion of
+ Windows `schannel.h` from `ldap.c` via `winldap.h` to have it enabled
+ as well. This requires `[P]UNICODE_STRING` types, which is apperantly
+ not defined automatically (as seen with both MSVS and mingw-w64).
+ This patch includes `<subauth.h>` to fix it.
+ Ref: https://github.com/curl/curl/runs/13987772013
+ Ref: https://dev.azure.com/daniel0244/curl/_build/results?buildId=15827&vie
+ w=logs&jobId=2c9f582d-e278-56b6-4354-f38a4d851906&j=2c9f582d-e278-56b6-4354-f
+ 38a4d851906&t=90509b00-34fa-5a81-35d7-5ed9569d331c
+ - tweak unity builds to compile `lib/memdebug.c` separately in memory
+ trace builds to avoid PP confusion.
+ - force-disable unity for test programs.
+ - do not compile and link libcurl sources to libtests _twice_ when libcurl
+ is built in static mode.
+
+ KNOWN ISSUES:
+ - running tests with unity builds may fail in cases.
+ - some build configurations/env may not compile in unity mode. E.g.:
+ https://ci.appveyor.com/project/curlorg/curl/builds/47230972/job/51wfesgnfu
+ auwl8q#L250
+
+ Ref: https://github.com/libssh2/libssh2/issues/1034
+ Ref: https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.html
+ Ref: https://en.wikipedia.org/wiki/Unity_build
+
+ Closes #11095
+
+Daniel Stenberg (7 Jun 2023)
+
+- examples/websocket.c: websocket example using CONNECT_ONLY
+
+ Closes #11262
+
+- websocket-cb: example doing WebSocket download using callback
+
+ Very basic
+
+ Closes #11260
+
+- test/.gitignore: ignore log*
+
+Dan Fandrich (5 Jun 2023)
+
+- runtests: document the -j parallel testing option
+
+ Reported-by: Daniel Stenberg
+ Ref: #10818
+ Closes #11255
+
+- runtests: create multiple test runners when requested
+
+ Parallel testing is enabled by using a nonzero value for the -j option
+ to runtests.pl. Performant values seem to be about 7*num CPU cores, or
+ 1.3*num CPU cores if Valgrind is in use.
+
+ Flaky tests due to improper log locking (bug #11231) are exacerbated
+ while parallel testing, so it is not enabled by default yet.
+
+ Fixes #10818
+ Closes #11246
+
+- runtests: handle repeating tests in multiprocess mode
+
+ Such as what happens with the --repeat option. Some functions are
+ changed to pass the runner ID instead of relying on the non-unique test
+ number.
+
+ Ref: #10818
+
+- runtests: buffer logmsg while running singletest()
+
+ This allows all messages relating to a single test case to be displayed
+ together at the end of the test.
+
+ Ref: #10818
+
+- runtests: call initserverconfig() in the runner
+
+ This must be done so variables pick up the runner's unique $LOGDIR.
+
+ Ref: #10818
+
+- runtests: use a per-runner random seed
+
+ Each runner needs a unique random seed to reduce the chance of port
+ number collisions. The new scheme uses a consistent per-runner source of
+ randomness which results in deterministic behaviour, as it did before.
+
+ Ref: #10818
+
+- runtests: complete main test loop refactor for multiple runners
+
+ The main test loop is now able to handle multiple runners, or no
+ additional runner processes at all. At most one process is still
+ created, however.
+
+ Ref: #10818
+
+- runtests: prepare main test loop for multiple runners
+
+ Some variables are expanded to arrays and hashes so that multiple
+ runners can be used for running tests.
+
+ Ref: #10818
+
+Stefan Eissing (5 Jun 2023)
+
+- bufq: make write/pass methods more robust
+
+ - related to #11242 where curl enters busy loop when
+ sending http2 data to the server
+
+ Closes #11247
+
+Boris Verkhovskiy (5 Jun 2023)
+
+- tool_getparam: fix comment
+
+ Closes #11253
+
+Raito Bezarius (5 Jun 2023)
+
+- haproxy: add --haproxy-clientip flag to spoof client IPs
+
+ CURLOPT_HAPROXY_CLIENT_IP in the library
+
+ Closes #10779
+
+Daniel Stenberg (5 Jun 2023)
+
+- curl: add --ca-native and --proxy-ca-native
+
+ These are two boolean options to ask curl to use the native OS's CA
+ store when verifying TLS servers. For peers and for proxies
+ respectively.
+
+ They currently only have an effect for curl on Windows when built to use
+ OpenSSL for TLS.
+
+ Closes #11049
+
+Viktor Szakats (5 Jun 2023)
+
+- build: drop unused/redundant `HAVE_WINLDAP_H`
+
+ Sources did not use it. Autotools used it when checking for the
+ `winldap` library, which is redundant.
+
+ With CMake, detection was broken:
+ ```
+ Run Build Command(s):/usr/local/Cellar/cmake/3.26.3/bin/cmake -E env VERBOSE=
+ 1 /usr/bin/make -f Makefile cmTC_2d8fe/fast && /Library/Developer/CommandLine
+ Tools/usr/bin/make -f CMakeFiles/cmTC_2d8fe.dir/build.make CMakeFiles/cmTC_2
+ d8fe.dir/build
+ Building C object CMakeFiles/cmTC_2d8fe.dir/HAVE_WINLDAP_H.c.obj
+ /usr/local/opt/llvm/bin/clang --target=x86_64-w64-mingw32 --sysroot=/usr/loca
+ l/opt/mingw-w64/toolchain-x86_64 -D_WINSOCKAPI_="" -I/my/quictls/x64-ucrt/usr
+ /include -I/my/zlib/x64-ucrt/usr/include -I/my/brotli/x64-ucrt/usr/include -W
+ no-unused-command-line-argument -D_UCRT -DCURL_HIDDEN_SYMBOLS -DHAVE_SSL_SE
+ T0_WBIO -DHAS_ALPN -DNGHTTP2_STATICLIB -DNGHTTP3_STATICLIB -DNGTCP2_STATICLIB
+ -DUSE_MANUAL=1 -fuse-ld=lld -Wl,-s -static-libgcc -lucrt -Wextra -Wall -p
+ edantic -Wbad-function-cast -Wconversion -Winline -Wmissing-declarations -Wmi
+ ssing-prototypes -Wnested-externs -Wno-long-long -Wno-multichar -Wpointer-ari
+ th -Wshadow -Wsign-compare -Wundef -Wunused -Wwrite-strings -Wcast-align -Wde
+ claration-after-statement -Wempty-body -Wendif-labels -Wfloat-equal -Wignored
+ -qualifiers -Wno-format-nonliteral -Wno-sign-conversion -Wno-system-headers -
+ Wstrict-prototypes -Wtype-limits -Wvla -Wshift-sign-overflow -Wshorten-64-to-
+ 32 -Wdouble-promotion -Wenum-conversion -Wunused-const-variable -Wcomma -Wmis
+ sing-variable-declarations -Wassign-enum -Wextra-semi-stmt -MD -MT CMakeFile
+ s/cmTC_2d8fe.dir/HAVE_WINLDAP_H.c.obj -MF CMakeFiles/cmTC_2d8fe.dir/HAVE_WINL
+ DAP_H.c.obj.d -o CMakeFiles/cmTC_2d8fe.dir/HAVE_WINLDAP_H.c.obj -c /my/curl/b
+ ld-cmake-llvm-x64-shared/CMakeFiles/CMakeScratch/TryCompile-3JP6dR/HAVE_WINLD
+ AP_H.c
+ In file included from /my/curl/bld-cmake-llvm-x64-shared/CMakeFiles/CMakeScra
+ tch/TryCompile-3JP6dR/HAVE_WINLDAP_H.c:2:
+ In file included from /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mi
+ ngw32/include/winldap.h:17:
+ In file included from /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mi
+ ngw32/include/schnlsp.h:9:
+ In file included from /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mi
+ ngw32/include/schannel.h:10:
+ /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32/include/wincrypt
+ .h:5041:254: error: unknown type name 'PSYSTEMTIME'
+ WINIMPM PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate (HCRYPTPROV_OR_
+ NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, PCERT_NAME_BLOB pSubjectIssuerBlob,
+ DWORD dwFlags, PCRYPT_KEY_PROV_INFO pKeyProvInfo, PCRYPT_ALGORITHM_IDENTIFIER
+ pSignatureAlgorithm, PSYSTEMTIME pStartTime, PSYSTEMTIME pEndTime, PCERT_EXT
+ ENSIONS pExtensions);
+
+
+
+ ^
+ /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32/include/wincrypt
+ .h:5041:278: error: unknown type name 'PSYSTEMTIME'
+ WINIMPM PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate (HCRYPTPROV_OR_
+ NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, PCERT_NAME_BLOB pSubjectIssuerBlob,
+ DWORD dwFlags, PCRYPT_KEY_PROV_INFO pKeyProvInfo, PCRYPT_ALGORITHM_IDENTIFIER
+ pSignatureAlgorithm, PSYSTEMTIME pStartTime, PSYSTEMTIME pEndTime, PCERT_EXT
+ ENSIONS pExtensions);
+
+
+
+ ^
+ 2 errors generated.
+ make[1]: *** [CMakeFiles/cmTC_2d8fe.dir/HAVE_WINLDAP_H.c.obj] Error 1
+ make: *** [cmTC_2d8fe/fast] Error 2
+ exitCode: 2
+ ```
+
+ Cherry-picked from #11095 88e4a21ff70ccef391cf99c8165281ff81374503
+ Reviewed-by: Daniel Stenberg
+ Closes #11245
+
+Daniel Stenberg (5 Jun 2023)
+
+- urlapi: scheme starts with alpha
+
+ Add multiple tests to lib1560 to verify
+
+ Fixes #11249
+ Reported-by: ad0p on github
+ Closes #11250
+
+- RELEASE-NOTES: synced
+
+- CURLOPT_MAIL_RCPT_ALLOWFAILS: replace CURLOPT_MAIL_RCPT_ALLLOWFAILS
+
+ Deprecate the name using three Ls and prefer the name with two.
+
+ Replaces #10047
+ Closes #11218
+
+- tests/servers: generate temp names in /tmp for unix domain sockets
+
+ ... instead of putting them in the regular pid directories because
+ systems generally have strict length requirements for the path name to
+ be shorter than 107 bytes and we easily hit that boundary otherwise.
+
+ The new concept generates two random names: one for the socks daemon and
+ one for http.
+
+ Reported-by: Andy Fiddaman
+ Fixes #11152
+ Closes #11166
+
+Stefan Eissing (2 Jun 2023)
+
+- http2: better support for --limit-rate
+
+ - leave transfer loop when --limit-rate is in effect and has
+ been received
+ - adjust stream window size to --limit-rate plus some slack
+ to make the server observe the pacing we want
+ - add test case to confirm behaviour
+
+ Closes #11115
+
+- curl_log: evaluate log statement only when transfer is verbose
+
+ Closes #11238
+
+Daniel Stenberg (2 Jun 2023)
+
+- libssh2: provide error message when setting host key type fails
+
+ Ref: https://curl.se/mail/archive-2023-06/0001.html
+
+ Closes #11240
+
+Igor Todorovski (2 Jun 2023)
+
+- system.h: remove __IBMC__/__IBMCPP__ guards and apply to all z/OS compiles
+
+ Closes #11241
+
+Daniel Stenberg (2 Jun 2023)
+
+- docs/SECURITY-PROCESS.md: link to example of previous critical flaw
+
+Mark Seuffert (2 Jun 2023)
+
+- README.md: updated link to opencollective
+
+ Closes #11232
+
+Daniel Stenberg (1 Jun 2023)
+
+- libssh2: use custom memory functions
+
+ Because of how libssh2_userauth_keyboard_interactive_ex() works: the
+ libcurl callback allocates memory that is later free()d by libssh2, we
+ must set the custom memory functions.
+
+ Reverts 8b5f100db388ee60118c08aa28
+
+ Ref: https://github.com/libssh2/libssh2/issues/1078
+ Closes #11235
+
+- test447: test PUTting a file that grows
+
+ ... and have curl trim the end when it reaches the expected total amount
+ of bytes instead of over-sending.
+
+ Reported-by: JustAnotherArchivist on github
+ Closes #11223
+
+- curl: count uploaded data to stop at the originally given size
+
+ Closes #11223
+ Fixes #11222
+ Reported-by: JustAnotherArchivist on github
+
+- tool: remove exclamation marks from error/warning messages
+
+- tool: use errorf() for error output
+
+ Convert a number of fprintf() calls.
+
+- tool: remove newlines from all helpf/notef/warnf/errorf calls
+
+ Make voutf() always add one.
+
+ Closes #11226
+
+- tests/servers.pm: pick unused port number with a server socket
+
+ This change replaces the previous method of picking a port number at
+ random to try to start servers on, then retrying up to ten times with
+ new random numbers each time, with a function that creates a server
+ socket on port zero, thereby getting a suitable random port set by the
+ kernel. That server socket is then closed and that port number is used
+ to setup the actual test server on.
+
+ There is a risk that *another* server can be started on the machine in
+ the time gap, but the server verification feature will detect that.
+
+ Closes #11220
+
+- RELEASE-NOTES: synced
+
+ bump to 8.2.0
+
+Alejandro R. Sedeño (31 May 2023)
+
+- configure: fix run-compiler for old /bin/sh
+
+ If you try to assign and export on the same line on some older /bin/sh
+ implementations, it complains:
+
+ ```
+ $ export "NAME=value"
+ NAME=value: is not an identifier
+ ```
+
+ This commit rewrites run-compiler's assignments and exports to work with
+ old /bin/sh, splitting assignment and export into two separate
+ statements, and only quote the value. So now we have:
+
+ ```
+ NAME="value"
+ export NAME
+ ```
+
+ While we're here, make the same change to the two supporting
+ assign+export lines preceeding the script to be consistent with how
+ exports work throughout the rest of configure.ac.
+
+ Closes #11228
+
+Philip Heiduck (31 May 2023)
+
+- circleci: install impacket & wolfssl 5.6.0
+
+ Closes #11221
+
+Daniel Stenberg (31 May 2023)
+
+- tool_urlglob: use curl_off_t instead of longs
+
+ To handle more globs better (especially on Windows)
+
+ Closes #11224
+
+Dan Fandrich (30 May 2023)
+
+- scripts: Fix GHA matrix job detection in cijobs.pl
+
+ The parsing is pretty brittle and it broke detecting some jobs at some
+ point. Also, detect if Windows is used in GHA.
+
+- runtests: abort test run after failure without -a
+
+ This was broken in a recent refactor and test runs would not stop.
+
+ Follow-up to d4a1b5b6
+
+ Reported-by: Daniel Stenberg
+ Fixes #11225
+ Closes #11227
+
Version 8.1.2 (30 May 2023)
Daniel Stenberg (30 May 2023)
@@ -7431,1815 +9015,3 @@ Daniel Stenberg (28 Dec 2022)
- HTTP3: mention what needs to be in place to remove EXPERIMENTAL label
Closes #10168
-
-Andy Alt (28 Dec 2022)
-
-- MANUAL.md: add pipe to apt-key example
-
- Closes #10170
-
-Daniel Stenberg (27 Dec 2022)
-
-- test417: verify %{certs} output
-
-- runtests: make 'mbedtls' a testable feature
-
- Also add to FILEFORMAT.md
-
-- writeout: add %{certs} and %{num_certs}
-
- Let users get the server certificate chain using the command line
-
- Closes #10019
-
-Stefan Eissing (27 Dec 2022)
-
-- haxproxy: send before TLS handhshake
-
- - reverse order of haproxy and final ssl cfilter
-
- - make haproxy avaiable on PROXY builds, independent of HTTP support as
- it can be used with any protocol.
-
- Reported-by: Sergio-IME on github
- Fixes #10165
- Closes #10167
-
-Daniel Stenberg (27 Dec 2022)
-
-- RELEASE-NOTES: synced
-
-- test446: verify hsts with two URLs
-
-- runtests: support crlf="yes" for verify/proxy
-
-- hsts: handle adding the same host name again
-
- It will then use the largest expire time of the two entries.
-
-- tool_operate: share HSTS between handles
-
-- share: add sharing of HSTS cache among handles
-
- Closes #10138
-
-Viktor Szakats (27 Dec 2022)
-
-- Makefile.mk: fix wolfssl and mbedtls default paths
-
- Fix the defaults for `WOLFSSL_PATH` and `MBEDTLS_PATH` to have
- meaningful values instead of the copy-pasted wrong ones.
-
- Ref: https://github.com/curl/curl/commit/66e68ca47f7fd00dff2cb7c45ba6725d4009
- 9585#r94275172
-
- Reported-by: Ryan Schmidt
- Closes #10164
-
-Daniel Stenberg (27 Dec 2022)
-
-- INTERNALS: cleanup
-
- - remove "operating systems" (mostly outdated)
-
- - upodate the "build tools"
-
- Closes #10162
-
-- cmake: bump requirement to 3.7
-
- Because this is the cmake version (released in November 2016) that
- introduced GREATER_EQUAL, which is used already.
-
- Reported-by: nick-telia on github
- Fixes #10128
- Closes #10161
-
-- cfilters:Curl_conn_get_select_socks: use the first non-connected filter
-
- When there are filters addded for both socket and SSL, the code
- previously checked the SSL sockets during connect when it *should* first
- check the socket layer until that has connected.
-
- Fixes #10157
- Fixes #10146
- Closes #10160
-
- Reviewed-by: Stefan Eissing
-
-- urlapi: add CURLU_PUNYCODE
-
- Allows curl_url_get() get the punycode version of host names for the
- host name and URL parts.
-
- Extend test 1560 to verify.
-
- Closes #10109
-
-- RELEASE-NOTES: synced
-
-- libssh2: try sha2 algos for hostkey methods
-
- As is supported by recent libssh2, but should just be ignored by older
- versions.
-
- Reported-by: norbertmm on github
- Assisted-by: norbertmm on github
- Fixes #10143
- Closes #10145
-
-Patrick Monnerat (26 Dec 2022)
-
-- typecheck: accept expressions for option/info parameters
-
- As expressions can have side effects, evaluate only once.
-
- To enable deprecation reporting only once, get rid of the __typeof__
- use to define the local temporary variable and use the target type
- (CURLoption/CURLINFO). This also avoids multiple reports on type
- conflicts (if some) by the curlcheck_* macros.
-
- Note that CURLOPT_* and CURLINFO_* symbols may be deprecated, but not
- their values: a curl_easy_setopt call with an integer constant as option
- will never report a deprecation.
-
- Reported-by: Thomas Klausner
- Fixes #10148
- Closes #10149
-
-Paul Howarth (26 Dec 2022)
-
-- tests: avoid use of sha1 in certificates
-
- The SHA-1 algorithm is deprecated (particularly for security-sensitive
- applications) in a variety of OS environments. This already affects
- RHEL-9 and derivatives, which are not willing to use certificates using
- that algorithm. The fix is to use sha256 instead, which is already used
- for most of the other certificates in the test suite.
-
- Fixes #10135
-
- This gets rid of issues related to sha1 signatures.
-
- Manual steps after "make clean-certs" and "make build-certs":
-
- - Copy tests/certs/stunnel-sv.pem to tests/stunnel.pem
- (make clean-certs does not remove the original tests/stunnel.pem)
-
- - Copy tests/certs/Server-localhost-sv.pubkey-pinned into --pinnedpubkey
- options of tests/data/test2041 and tests/data/test2087
-
- Closes #10153
-
-Yurii Rashkovskii (26 Dec 2022)
-
-- cmake: fix the snprintf detection
-
- I haven't had the time to check other configurations, but on my macOS
- Ventura 13.1 with XCode 14.2 cmake does not find `snprintf`.
-
- Solution: ensure stdio.h is checked for definitions
-
- Closes #10155
-
-Radu Hociung (26 Dec 2022)
-
-- http: remove the trace message "Mark bundle... multiuse"
-
- The message "Mark bundle as not supporting multiuse" was added at commit
- 29364d93 when an http/2-related bug was fixed, and it appears to be a
- leftover trace message.
-
- This message should be removed because:
- * it conveys no information to the user
- * it is enabled in the default build (--enable-verbose)
- * it reads like a warning/unexpected condition
- * it is equivalent to "Detected http proto < 2", which is
- not a useful message.
- * it is a time-wasting red-herring for anyone who encounters
- it for the first time while investigating some other, real
- problem.
-
- This commit removes the trace message "Mark bundle as not
- supporting multiuse"
-
- Closes #10159
-
-Hannah Schierling (26 Dec 2022)
-
-- url: fix build with `--disable-cookies`
-
- Struct `UserDefined` has no member `cookielist` if
- `CURL_DISABLE_COOKIES` is defined.
-
- Follow-up to af5999a
-
- Closes #10158
-
-Stefan Eissing (23 Dec 2022)
-
-- runtests: also tear down http2/http3 servers when https server is stopped
-
- Closes #10114
-
-- tests: add 3 new HTTP/2 test cases, plus https: support for nghttpx
-
- - a simple https get
- - a simple https post
- - a multi get of 4 requests and check that same connection was used
-
- Closes #10114
-
-Daniel Stenberg (23 Dec 2022)
-
-- urldata: remove unused struct fields, made more conditional
-
- - source_quote, source_prequote and source_postquote have not been used since
- 5e0d9aea3; September 2006
-
- - make several fields conditional on proxy support
-
- - make three quote struct fields conditional on FTP || SSH
-
- - make 'mime_options' depend on MIME
-
- - make trailer_* fields depend on HTTP
-
- - change 'gssapi_delegation' from long to unsigned char
-
- - make 'localportrange' unsigned short instead of int
-
- - conn->trailer now depends on HTTP
-
- Closes #10147
-
-- urldata: make set.http200aliases conditional on HTTP being present
-
- And make a few SSH-only fields depend on SSH
-
- Closes #10140
-
-- md4: fix build with GnuTLS + OpenSSL v1
-
- Reported-by: Esdras de Morais da Silva
-
- Fixes #10110
- Closes #10142
-
-- urldata: make 'ftp_create_missing_dirs' depend on FTP || SFTP
-
- Closes #10139
-
-John Bampton (22 Dec 2022)
-
-- misc: fix grammar and spelling
-
- Closes #10137
-
-Daniel Stenberg (22 Dec 2022)
-
-- urldata: move the cookefilelist to the 'set' struct
-
- The cookiefile entries are set into the handle and should remain set for
- the lifetime of the handle so that duplicating it also duplicates the
- list. Therefore, the struct field is moved from 'state' to 'set'.
-
- Fixes #10133
- Closes #10134
-
-- strdup: name it Curl_strdup
-
- It does not belong in the curlx_ name space as it is never used
- externally.
-
- Closes #10132
-
-Nick Banks (22 Dec 2022)
-
-- msh3: update to v0.5 Release
-
- Closes #10125
-
-Andy Alt (22 Dec 2022)
-
-- workflows/linux.yml: merge 3 common packages
-
- Closes #10071
-
-Daniel Stenberg (21 Dec 2022)
-
-- docs: mention indirect effects of --insecure
-
- Warn users that disabling certficate verification allows servers to
- "pollute" curl with data it trusts.
-
- Reported-by: Harry Sintonen
- Closes #10126
-
-- SECURITY-PROCESS.md: document severity levels
-
- Closes #10118
-
-- RELEASE_NOTES: synced
-
- bumped version for new cycle
-
-Marcel Raad (21 Dec 2022)
-
-- tool_operate: fix `CURLOPT_SOCKS5_GSSAPI_NEC` type
-
- `CURLOPT_SOCKS5_GSSAPI_NEC` is a long, while `socks5_gssapi_nec` was
- made a bool in commit 4ac64eadf60.
-
- Closes https://github.com/curl/curl/pull/10124
-
-Version 7.87.0 (21 Dec 2022)
-
-Daniel Stenberg (21 Dec 2022)
-
-- RELEASE-NOTES: synced
-
- The curl 7.87.0 release
-
-- THANKS: 40 new contributors from 7.87.0
-
-- http: fix the ::1 comparison for IPv6 localhost for cookies
-
- When checking if there is a "secure context", which it is if the
- connection is to localhost even if the protocol is HTTP, the comparison
- for ::1 was done incorrectly and included brackets.
-
- Reported-by: BratSinot on github
-
- Fixes #10120
- Closes #10121
-
-Philip Heiduck (19 Dec 2022)
-
-- CI/spell: actions/checkout@v2 > actions/checkout@v3
-
-Daniel Stenberg (19 Dec 2022)
-
-- smb/telnet: do not free the protocol struct in *_done()
-
- It is managed by the generic layer.
-
- Reported-by: Trail of Bits
-
- Closes #10112
-
-- http: use the IDN decoded name in HSTS checks
-
- Otherwise it stores the info HSTS into the persistent cache for the IDN
- name which will not match when the HSTS status is later checked for
- using the decoded name.
-
- Reported-by: Hiroki Kurosawa
-
- Closes #10111
-
-- CURLOPT_DEBUGFUNCTION.3: emphasize that incoming data is "raw"
-
- Closes #10106
-
-Xì Gà (16 Dec 2022)
-
-- socks: fix username max size is 255 (0xFF)
-
- Closes #10105
-
- Reviewed-by: Daniel Gustafsson
-
-Daniel Stenberg (16 Dec 2022)
-
-- limit-rate.d: see also --rate
-
-- lib1560: add some basic IDN host name tests
-
- Closes #10094
-
-- idn: rename the files to idn.[ch] and hold all IDN functions
-
- Closes #10094
-
-- idn: remove Curl_win32_ascii_to_idn
-
- It was not used. Introduce a new IDN header for the prototype(s).
-
- Closes #10094
-
-- RELEASE-NOTES: synced
-
-- curl_url_get.3: remove spurious backtick
-
- Put there by mistake.
-
- Follow-up from 9a8564a92
-
- Closes #10101
-
-- socks: fix infof() flag for outputing a char
-
- It used to be a 'long', %lu is no longer correct.
-
- Follow-up to 57d2d9b6bed33d
- Detected by Coverity CID 1517663
-
- Closes #10100
-
-- ssl-reqd.d: clarify that this is for upgrading connections only
-
- Closes #10093
-
-- curl_url_set.3: document CURLU_DISALLOW_USER
-
- Closes #10099
-
-- cmake: set the soname on the shared library
-
- Set SONAME and VERSION for platforms we think this works on. Remove
- issue from KNOWN_BUGS.
-
- Assisted-by: Jakub Zakrzewski
-
- Closes #10023
-
-- tool_paramhlp: free the proto strings on exit
-
- And also make sure that repeated use of the options free the previous
- string before it stores a new.
-
- Follow-up from e6f8445edef8e7996d
-
- Closes #10098
-
-- tool_cfgable: free the ssl_ec_curves on exit
-
- Follow-up to ede125b7b
-
- Closes #10097
-
-- urlapi: reject more bad letters from the host name: &+()
-
- Follow-up from eb0167ff7d31d3a5
-
- Extend test 1560 to verify
-
- Closes #10096
-
-- altsvc: fix rejection of negative port numbers
-
- Follow-up to ac612dfeee95
-
- strtoul() accepts a leading minus so better make sure there is none
-
- Extended test 356 somewhat to use a huge negative 64 bit number that
- otherwise becomes a low positive number.
-
- Closes #10095
-
-- lib: use size_t or int etc instead of longs
-
- Since long is not using a consistent data size in curl builds, making it
- often "waste" 32 bits.
-
- Closes #10088
-
-- azure: use "unversioned" clang and clang-tools for scanbuild job
-
- To make it less fragile
-
- Closes #10092
-
-Daniel Gustafsson (14 Dec 2022)
-
-- x509asn1: avoid freeing unallocated pointers
-
- When utf8asn1str fails there is no allocation returned, so freeing
- the return pointer in **to is at best a no-op and at worst a double-
- free bug waiting to happen. The current coding isn't hiding any such
- bugs but to future proof, avoid freeing the return value pointer iff
- the function failed.
-
- Closes: #10087
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Emil Engler (13 Dec 2022)
-
-- curl_url_set.3: fix typo
-
- Closes: #10089
- Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-
-Daniel Stenberg (13 Dec 2022)
-
-- test2304: verify websocket handling when connection is closed
-
-- server/sws: if asked to close connection, skip the websocket handling
-
-- ws: if no connection is around, return error
-
- - curl_ws_send returns CURLE_SEND_ERROR if data->conn is gone
-
- - curl_ws_recv returns CURLE_GOT_NOTHING on connection close
-
- - curl_ws_recv.3: mention new return code for connection close + example
- embryo
-
- Closes #10084
-
-Emil Engler (13 Dec 2022)
-
-- docs: extend the dump-header documentation
-
- This commit extends the documentation of the --dump-header command-line
- option to reflect the behavior introduced in 8b1e5df7.
-
- See #10079
- Closes #10085
-
-Daniel Stenberg (12 Dec 2022)
-
-- RELEASE-NOTES: synced
-
-- styled-output.d: this option does not work on Windows
-
- Reported-by: u20221022 on github
-
- Fixes #10082
- Closes #10083
-
-Emil Engler (12 Dec 2022)
-
-- tool: determine the correct fopen option for -D
-
- This commit fixes a bug in the dump-header feature regarding the
- determination of the second fopen(3) option.
-
- Reported-by: u20221022 on github
-
- See #4753
- See #4762
- Fixes #10074
- Closes #10079
-
-Christian Schmitz (11 Dec 2022)
-
-- docs/curl_ws_send: Fixed typo in websocket docs
-
- Replace as with is in relevant sentences.
-
- Closes: #10081
- Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-
-Prithvi MK (11 Dec 2022)
-
-- c-hyper: fix multi-request mechanism
-
- It makes test 565 run fine.
-
- Fixes #8896
- Closes #10080
- Assisted-by: Daniel Stenberg
-
-Andy Alt (11 Dec 2022)
-
-- page-header: grammar improvement (display transfer rate)
-
- Closes #10068
-
-- docs/DEPRECATE.md: grammar improvement and sp correction
-
- The main thing I wanted to do was fix the spelling of "spent", but I
- think this rewording improves the flow of the paragraph.
-
- Closes #10067
-
-Boris Verkhovskiy (11 Dec 2022)
-
-- tool_cfgable: make socks5_gssapi_nec a boolean
-
- Closes #10078
-
-Frank Gevaerts (9 Dec 2022)
-
-- contributors.sh: actually use $CURLWWW instead of just setting it.
-
- The script was all set up for flexibility where curl-www is elsewhere in
- the filesystem, but then hard-coded ../curl-www anyway...
-
- Closes #10064
-
-Daniel Stenberg (9 Dec 2022)
-
-- KNOWN_BUGS: remove items not considered bugs any more
-
- - CURL_GLOBAL_SSL
-
- This option was changed in libcurl 7.57.0 and clearly it has not caused
- too many issues and a lot of time has passed.
-
- - Store TLS context per transfer instead of per connection
-
- This is a possible future optimization. One that is much less important
- and interesting since the added support for CA caching.
-
- - Microsoft telnet server
-
- This bug was filed in May 2007 against curl 7.16.1 and we have not
- received further reports.
-
- - active FTP over a SOCKS
-
- Actually, proxies in general is not working with active FTP mode. This
- is now added in proxy documentation.
-
- - DICT responses show the underlying protocol
-
- curl still does this, but since this is now an established behavior
- since forever we cannot change it easily and adding an option for it
- seems crazy as this protocol is not so little its not worth it. Let's
- just live with it.
-
- - Secure Transport disabling hostname validation also disables SNI
-
- This is an already documented restriction in Secure Transport.
-
- - CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
-
- The curl_formadd() function is marked and documented as deprecated. No
- point in collecting bugs for it. It should not be used further.
-
- - STARTTRANSFER time is wrong for HTTP POSTs
-
- After close source code inspection I cannot see how this is true or that
- there is any special treatment for different HTTP methods. We also have
- not received many further reports on this, making me strongly suspect
- that this is no (longer an) issue.
-
- - multipart formposts file name encoding
-
- The once proposed RFC 5987-encoding is since RFC 7578 documented as MUST
- NOT be used. The since then implemented MIME API allows the user to set
- the name on their own and can thus provide it encoded as it wants.
-
- - DoH is not used for all name resolves when enabled
-
- It is questionable if users actually want to use DoH for interface and
- FTP port name resolving. This restriction is now documented and we
- advice users against using name resolving at all for these functions.
-
- Closes #10043
-
-- CURLOPT_COOKIEFILE.3: advice => advise
-
- Closes #10063
-
- Reviewed-by: Daniel Gustafsson
-
-Daniel Gustafsson (9 Dec 2022)
-
-- curl.h: reword comment to not use deprecated option
-
- CURLOPT_INFILE was replaced by CURLOPT_READDATA in 7.9.7, reword the
- comment mentioning it to make code grepping easier as well as improve
- the documentation.
-
- Closes: #10062
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Ryan Schmidt (9 Dec 2022)
-
-- system.h: fix socklen_t, curl_off_t, long long for Classic Mac OS
-
- Change "__MWERKS__" to "macintosh". When this block was originally added
- in 3ac6929 it was probably intended to handle classic Mac OS since the
- previous classic Mac OS build procedure for curl (which was removed in
- bf327a9) used Metrowerks CodeWarrior.
-
- But there are other classic Mac OS compilers, such as the MPW compilers,
- that were not handled by this case. For classic Mac OS,
- CURL_TYPEOF_CURL_SOCKLEN_T needs to match what's provided by the
- third-party GUSI library, which does not vary by compiler.
-
- Meanwhile CodeWarrior works on platforms other than classic Mac OS, and
- they may need different definitions. Separate blocks could be added
- later for any of those platforms that curl doesn't already support.
-
- Closes #10049
-
-- vms: remove SIZEOF_SHORT
-
- The rest of SIZEOF_SHORT was removed in d48dd15.
-
- See #9291
- Closes #10061
-
-Daniel Gustafsson (8 Dec 2022)
-
-- tool_formparse: avoid clobbering on function params
-
- While perfectly legal to do, clobbering function parameters and using
- them as local variables is confusing at best and rarely improves code
- readability. Fix by using a local variable instead, no functionality
- is changed.
-
- This also renames the parameter from data to mime_data since the term
- data is (soft) reserved for the easy handle struct.
-
- Closes: #10046
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-- noproxy: guard against empty hostnames in noproxy check
-
- When checking for a noproxy setting we need to ensure that we get
- a hostname passed in. If there is no hostname then there cannot be
- a matching noproxy rule for it by definition.
-
- Closes: #10057
- Reported-by: Geeknik Labs
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Daniel Stenberg (8 Dec 2022)
-
-- c-hyper: CONNECT respones are not server responses
-
- Together with d31915a8dbbd it makes test 265 run fine.
-
- Fixes #8853
- Assisted-by: Prithvi MK
- Assisted-by: Sean McArthur
- Closes #10060
-
-- test265: Use "connection: keep-alive" response header
-
- When it answers as HTTP/1.0, so that clients (hyper) knows properly that
- the connection remains intact.
-
-- RELEASE-NOTES: synced
-
-Stefan Eissing (8 Dec 2022)
-
-- cfilter: improve SSL connection checks
-
- - fixes `Curl_ssl_cf_get_ssl()` to detect also the first filter instance
- as ssl (refs #10053)
-
- - replaces `Curl_ssl_use()` with the correct `Curl_conn_is_ssl()`
-
- Closes #10054
- Fixes #10053
-
- Reported-by: Patrick Monnerat
-
-Daniel Stenberg (8 Dec 2022)
-
-- runtests: silence nghttpx errors
-
- Also, move the output of the nghttpx_h3 info to the general "Env:" line
- in the test output header.
-
- Reported-by: Marcel Raad
- Ref: https://github.com/curl/curl/commit/ca15b7512e8d1199e55fbaa206ef01e64b8f
- 147d#commitcomment-92015094
- Closes #10044
-
-Ryan Schmidt (7 Dec 2022)
-
-- config-mac: define HAVE_SYS_IOCTL_H
-
- This is needed to compile nonblock.c on classic Mac OS with Grand
- Unified Socket Interface (GUSI) because nonblock.c uses FIONBIO which is
- defined in <sys/filio.h> which is included by <sys/ioctl.h>.
-
- Ref: https://sourceforge.net/projects/gusi/
-
- Closes https://github.com/curl/curl/pull/10042
-
-Philip Heiduck (7 Dec 2022)
-
-- CI: Change FreeBSD image from 12.3 to 12.4
-
- Ref: https://www.phoronix.com/news/FreeBSD-12.4-Released
-
- Closes https://github.com/curl/curl/pull/10051
-
-Ryan Schmidt (7 Dec 2022)
-
-- test1421: fix typo
-
- Closes https://github.com/curl/curl/pull/10055
-
-Jay Satiro (7 Dec 2022)
-
-- build: assume errno.h is always available
-
- - Remove errno.h detection from all build configurations.
-
- errno.h is a standard header according to C89.
-
- Closes https://github.com/curl/curl/pull/9986
-
-- build: assume assert.h is always available
-
- - Remove assert.h detection from all build configurations.
-
- assert.h is a standard header according to C89.
-
- I had proposed this several years ago as part of a larger change that
- was abandoned.
-
- Ref: https://github.com/curl/curl/issues/1237#issuecomment-277500720
-
- Closes https://github.com/curl/curl/pull/9985
-
-Philip Heiduck (7 Dec 2022)
-
-- CI: LGTM.com will be shut down in December 2022
-
- Closes #10052
-
-Daniel Stenberg (6 Dec 2022)
-
-- mailmap: Andy Alt
-
-Andy Alt (6 Dec 2022)
-
-- misc: Fix incorrect spelling
-
- Fix various uses of connnect by replacing them with connect.
-
- Closes: #10045
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
- Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-
-Stefan Eissing (6 Dec 2022)
-
-- wolfssl: remove special BIO return code handling
-
- - rely solely on the retry flag in BIO, similar to OpenSSL vtls
- implementation.
-
- Ref: https://github.com/curl/curl/pull/10021#issuecomment-1336147053
-
- Closes #10033
-
-Daniel Stenberg (6 Dec 2022)
-
-- openssl: return -1 on error in the BIO callbacks
-
- BIO_read and BIO_write return negative numbers on error, including
- retryable ones. A regression from 55807e6. Both branches should be
- returning -1.
-
- The APIs are patterned after POSIX read and write which, similarly,
- return -1 on errors, not zero, with EAGAIN treated as an error.
-
- Bug: https://github.com/curl/curl/issues/10013#issuecomment-1335308146
- Reported-by: David Benjamin
- Closes #10021
-
-Ryan Schmidt (6 Dec 2022)
-
-- config-mac: remove HAVE_SYS_SELECT_H
-
- When compiling for classic Mac OS with GUSI, there is no sys/select.h.
- GUSI provides the "select" function prototype in sys/time.h.
-
- Closes #10039
-
-- setup: do not require __MRC__ defined for Mac OS 9 builds
-
- Partially reverts "somewhat protect Mac OS X users from using Mac OS 9
- config file", commit 62519bfe059251af2914199f284c736553ff0489.
-
- Do things that are specific to classic Mac OS (i.e. include config-mac.h
- in curl_setup.h and rename "main" to "curl_main" in tool_setup.h) when
- only "macintosh" is defined. Remove the additional condition that
- "__MRC__" should be defined since that would only be true with the MPW
- MrC compiler which prevents the use of other reasonable compilers like
- the MPW SC compiler and especially the Metrowerks CodeWarrior compilers.
- "macintosh" is only defined by classic Mac OS compilers so this change
- should not affect users of Mac OS X / OS X / macOS / any other OS.
-
- Closes #10037
-
-- curl.h: name all public function parameters
-
- Most public function parameters already have names; this adds those
- that were missing.
-
- Closes #10036
-
-Andy Alt (6 Dec 2022)
-
-- docs/examples: spell correction ('Retrieve')
-
- Closes #10040
-
-Daniel Stenberg (6 Dec 2022)
-
-- unit1302: slightly extended
-
- To test more base64 decoding
-
-- base64: faster base64 decoding
-
- - by using a lookup table instead of strchr()
- - by doing full quantums first, then padding
-
- Closes #10032
-
-Michael Musset (6 Dec 2022)
-
-- libssh2: return error when ssh_hostkeyfunc returns error
-
- return CURLE_PEER_FAILED_VERIFICATION if verification with the callback
- return a result different than CURLKHMATCH_OK
-
- Closes #10034
-
-Viktor Szakats (5 Dec 2022)
-
-- Makefile.mk: improve a GNU Make hack [ci skip]
-
- Replace the hack of using `$() ` to represent a single space. The new
- method silences the `--warn-undefined-variables` debug warning and it's
- also a better-known form of solving this problem.
-
- Reviewed-by: Jay Satiro
- Closes #10031
-
-Daniel Stenberg (5 Dec 2022)
-
-- tests/unit/.gitignore: ignore all unit + 4 digits files
-
-- base64: encode without using snprintf
-
- For speed. In some tests, this approch is 29 times faster!
-
- Closes #10026
-
-- base64: better alloc size
-
- The previous algorithm allocated more bytes than necessary.
-
- Suggested-by: xtonik on github
- Fixes #10024
- Closes #10025
-
-Ryan Schmidt (5 Dec 2022)
-
-- config-mac: fix typo: size_T -> size_t
-
- Both MPW and CodeWarrior compilers complained about this.
-
- Closes #10029
-
-Daniel Stenberg (3 Dec 2022)
-
-- RELEASE-NOTES: synced
-
-Jakub Zakrzewski (2 Dec 2022)
-
-- CMake: fix build with `CURL_USE_GSSAPI`
-
- CMAKE_*_LINKER_FLAGS must be a string but GSS_LINKER_FLAGS is a list, so
- we need to replace semicolons with spaces when setting those.
-
- Fixes #9017
- Closes #1022
-
-Max Dymond (2 Dec 2022)
-
-- ci: Reuse fuzzing snippet from curl-fuzzer project
-
-Diogo Teles Sant'Anna (2 Dec 2022)
-
-- GHA: clarify workflows permissions, set least possible privilege
-
- Set top-level permissions to None on all workflows, setting per-job
- permissions. This avoids that new jobs inherit unwanted permissions.
-
- Discussion: https://curl.se/mail/lib-2022-11/0028.html
-
- Signed-off-by: Diogo Teles Sant'Anna <diogoteles@google.com>
-
- Closes #9928
-
-Viktor Szakats (2 Dec 2022)
-
-- Makefile.mk: address minor issues
-
- - Fix `NROFF` auto-detection with certain shell/make-build combinations:
-
- When a non-MSYS2 GNU Make runs inside an MSYS2 shell, Make executes
- the detection command as-is via `CreateProcess()`. It fails because
- `command` is an `sh` built-in. Ensure to explicitly invoke the shell.
-
- - Initialize user-customizable variables:
-
- Silences a list of warnings when running GNU Make with the option
- `--warn-undefined-variables`. Another benefit is that it's now easy
- to look up all user-customizable `Makefile.mk` variables by grepping
- for ` ?=` in the curl source tree.
-
- Suggested-by: Gisle Vanem
- Ref: https://github.com/curl/curl/pull/9764#issuecomment-1330674433
-
- - Fix `MKDIR` invocation:
-
- Avoid a warning and potential issue in envs without forward-slash
- support.
-
- Closes #10000
-
-Rob de Wit (2 Dec 2022)
-
-- curl_get_line: allow last line without newline char
-
- improve backwards compatibility
-
- Test 3200 verifies
-
- Closes #9973
-
-Daniel Stenberg (2 Dec 2022)
-
-- cookie: open cookie jar as a binary file
-
- On Windows there is a difference and for text files, ^Z means end of
- file which is not desirable.
-
- Ref: #9973
- Closes #10017
-
-- runtests: only do CRLF replacements for hyper if it is HTTP
-
- Closes #10016
-
-Stefan Eissing (1 Dec 2022)
-
-- openssl: fix for BoringSSL BIO result interpretation mixups
-
- Reported-by: Robin Marx
- Fixes #10013
- Closes #10015
-
-Max Dymond (1 Dec 2022)
-
-- ci: Remove zuul fuzzing job as it's superseded by CIFuzz
-
-Daniel Stenberg (1 Dec 2022)
-
-- runtests: do CRLF replacements per section only
-
- The `crlf="yes"` attribute and "hyper mode" are now only applied on a
- subset of dedicated sections: data, datacheck, stdout and protocol.
-
- Updated test 2500 accordingly.
-
- Also made test1 use crlf="yes" for <protocol>, mostly because it is
- often used as a template test case. Going forward, using this attribute
- we should be able to write test cases using linefeeds only and avoid
- mixed line ending encodings.
-
- Follow-up to ca15b7512e8d11
-
- Fixes #10009
- Closes #10010
-
-Stefan Eissing (1 Dec 2022)
-
-- gnutls: use common gnutls init and verify code for ngtcp2
-
- Closes #10007
-
-Baitinq on github (1 Dec 2022)
-
-- aws_sigv4: fix typos in aws_sigv4.c
-
- Closes #10008
-
-Kenneth Myhra (30 Nov 2022)
-
-- curl.h: include <sys/select.h> on SerenityOS
-
- Closes #10006
-
-Daniel Stenberg (30 Nov 2022)
-
-- openssl: prefix errors with '[lib]/[version]: '
-
- To help users understand where this (cryptic) error message comes from.
-
- Suggested-by: Philip Sanetra
- Ref: #10002
- Closes #10004
-
-Stefan Eissing (30 Nov 2022)
-
-- tests: add HTTP/3 test case, custom location for proper nghttpx
-
- - adding support for HTTP/3 test cases via a nghttpx server that is
- build with ngtcp2 and nghttp3.
- - test2500 is the first test case, performing a simple GET.
- - nghttpx is checked for support and the 'feature' nghttpx-h3
- is set accordingly. test2500 will only run, when supported.
- - a specific nghttpx location can be given in the environment
- variable NGHTTPX or via the configure option
- --with-test-nghttpx=<path>
-
- Extend NGHTTPX config to H2 tests as well
-
- * use $ENV{NGHTTPX} and the configured default also in http2 server starts
- * always provide the empty test/nghttpx.conf to nghttpx. as it defaults to
- reading /etc/nghttpx/nghttpx.conf otherwise.
-
- Added nghttpx to CI ngtcp2 jobs to run h3 tests.
-
- Closes #9031
-
-Daniel Stenberg (30 Nov 2022)
-
-- RELEASE-NOTES: synced
-
- Removed duplicate after contributors.sh fix: 9967c10b6daa1
-
-- scripts/contributors.sh: strip one OR MORE leading spaces
-
- From names found credited in commit logs
-
-- RELEASE-NOTES: synced
-
-- openssl/mbedtls: use %d for outputing port with failf (int)
-
- Coverity CID 1517100
-
- Also, remove some int typecasts in vtls.c for the port number
-
- Closes #10001
-
-- KNOWN_BUGS: remove "Multi perform hangs waiting for threaded resolver"
-
- We now offer a way to avoid that hang, using CURLOPT_QUICK_EXIT.
-
- Follow-up to 49798cac832ab1 fixed via #9147
-
- Closes #9999
-
-- KNOWN_BUGS: remove "--interface for ipv6 binds to unusable IP address"
-
- Since years back the "if2ip" function verifies that it binds to a local IPv6
- address that uses the same scope as the remote address.
-
- This is not a bug.
-
- Fixes #686
- Closes #9998
-
-- test1276: verify lib/optiontable.pl
-
- Checks that it generates an output identical to the file.
-
-- lib/optiontable.pl: adapt to CURLOPTDEPRECATED()
-
- Follow-up from 6967571bf20624bc
-
- Reported-by: Gisle Vanem
-
- Fixes #9992
- Closes #9993
-
-- docs/INSTALL.md: list OSes and CPUs quoted
-
- to make them skip spellcheck. Also added a new CPU.
-
- Follow-up to 4506cbf7f24a2a
-
- Closes #9997
-
-Ikko Ashimine (28 Nov 2022)
-
-- vtls: fix typo in vtls_int.h
-
- paramter -> parameter
-
- Closes: #9996
- Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-
-Daniel Stenberg (28 Nov 2022)
-
-- curl-openssl.m4: do not add $prefix/include/openssl to CPPFLAGS
-
- As OpenSSL's include files are all included using <openssl/*.h> in curl
- source code, we just risk that existing openssl files will "shadow"
- include files without path if that path is provided.
-
- Fixes #9989
- Closes #9988
-
-- INSTALL: update operating systems and CPU archs
-
- Update after recent runs on Twitter/Mastodon and my blog
-
- Closes #9994
-
-Stefan Eissing (28 Nov 2022)
-
-- tls: backends use connection filters for IO, enabling HTTPS-proxy
-
- - OpenSSL (and compatible)
- - BearSSL
- - gnutls
- - mbedtls
- - rustls
- - schannel
- - secure-transport
- - wolfSSL (v5.0.0 and newer)
-
- This leaves only the following without HTTPS-proxy support:
- - gskit
- - nss
- - wolfSSL (versions earlier than v5.0.0)
-
- Closes #9962
-
-Daniel Stenberg (28 Nov 2022)
-
-- include/curl/curl.h: bump the deprecated requirements to gcc 6.1
-
- Reported-by: Michael Kaufmann
- Fixes #9917
- Closes #9987
-
-Patrick Monnerat (28 Nov 2022)
-
-- mime: relax easy/mime structures binding
-
- Deprecation and removal of codeset conversion support from the library
- have released the strict need for an early binding of mime structures to
- an easy handle (https://github.com/curl/curl/commit/2610142).
-
- This constraint currently forces to create the handle before the mime
- structure and the latter cannot be attached to another handle once
- created (see https://curl.se/mail/lib-2022-08/0027.html).
-
- This commit removes the handle pointers from the mime structures
- allowing more flexibility on their use.
-
- When an easy handle is duplicated, bound mime structures must however
- still be duplicated too as their components hold send-time dynamic
- information.
-
- Closes #9927
-
-fractal-access (26 Nov 2022)
-
-- test416: verify growing FTP file support
-
- Added setting: RETRSIZE [size] in the <servercmd> section. When set this
- will cause the test FTP server to return the size set (rather than the
- actual size) in the acknowledgement from a RETR request.
-
- Closes #9772
-
-- ftp: support growing files with CURLOPT_IGNORE_CONTENT_LENGTH
-
- When using the option CURLOPT_IGNORE_CONTENT_LENGTH (set.ignorecl in
- code) to support growing files in FTP, the code should ignore the
- initial size it gets from the server as this will not be the final size
- of the file. This is done in ftp_state_quote() to prevent a size request
- being issued in the initial sequence. However, in a later call to
- ftp_state_get_resp() the code attempts to get the size of the content
- again if it doesn't already have it, by parsing the response from the
- RETR request. This fix prevents this parsing of the response to get the
- size when the set.ignorecl option is set. This should maintain the size
- value as -1, unknown, in this situation.
-
- Closes #9772
-
-Stefan Eissing (26 Nov 2022)
-
-- cfilter: re-add `conn` as parameter to cfilter setup methods
-
- - `Curl_ssl_get_config()` now returns the first config if no SSL proxy
- filter is active
-
- - socket filter starts connection only on first invocation of its
- connect method
-
- Fixes #9982
- Closes #9983
-
-Daniel Stenberg (26 Nov 2022)
-
-- KNOWN_BUGS: remove five FTP related issues
-
- - "FTP with CONNECT and slow server"
-
- I believe this is not a problem these days.
-
- - "FTP with NULs in URL parts"
-
- The FTP protocol does not support them properly anyway.
-
- - remove "FTP and empty path parts in the URL"
-
- I don't think this has ever been reported as a real problem but was only
- a hypothetical one.
-
- - "Premature transfer end but healthy control channel"
-
- This is not a bug, this is an optimization that *could* be performed but is
- not an actual problem.
-
- - "FTP without or slow 220 response"
-
- Instead add to the documentation of the connect timeout that the
- connection is considered complete at TCP/TLS/QUIC layer.
-
- Closes #9979
-
-Stefan Eissing (26 Nov 2022)
-
-- tests: add authorityInfoAccess to generated certs
-
- Generate stunnel.pem as well
-
- Closes #9980
-
-Daniel Stenberg (25 Nov 2022)
-
-- runtests: --no-debuginfod now disables DEBUGINFOD_URLS
-
- Prior to this change, DEBUGINFOD_URLS was always disabled by runtests
- due to a report of it slowing down tests. However, some setups need it
- to fetch debug symbols, and if it is disabled on those systems then curl
- tests with valgrind will fail.
-
- Reported-by: Mark Gaiser
-
- Ref: #8805
- Closes #9950
-
-Casey Bodley (25 Nov 2022)
-
-- test/aws_sigv4: test cases for content-sha256
-
- 1956 adds the sha256 value corresponding to an empty buffer
- 1957 adds an arbitrary value and confirms that the signature differs from 195
- 6
- 1958 adds whitespace to 1957 and confirms that the signature matches 1957
- 1959 adds a value longer than 'char sha_hex[65]' in Curl_output_aws_sigv4()
-
- Signed-off-by: Casey Bodley <cbodley@redhat.com>
-
- Closes #9804
-
-- aws_sigv4: consult x-%s-content-sha256 for payload hash
-
- `Curl_output_aws_sigv4()` doesn't always have the whole payload in
- memory to generate a real payload hash. this commit allows the user to
- pass in a header like `x-amz-content-sha256` to provide their desired
- payload hash
-
- some services like s3 require this header, and may support other values
- like s3's `UNSIGNED-PAYLOAD` and `STREAMING-AWS4-HMAC-SHA256-PAYLOAD`
- with special semantics. servers use this header's value as the payload
- hash during signature validation, so it must match what the client uses
- to generate the signature
-
- CURLOPT_AWS_SIGV4.3 now describes the content-sha256 interaction
-
- Signed-off-by: Casey Bodley <cbodley@redhat.com>
-
- Closes #9804
-
-Philip Heiduck (25 Nov 2022)
-
-- GHA: NSS use clang instead of clang-9
-
- Closes #9978
-
-Daniel Stenberg (25 Nov 2022)
-
-- RELEASE-NOTES: synced
-
-- tool_operate: override the numeric locale and set "C" by force
-
- Makes curl always use dot as decimal separator for options,
- independently of what the locale says. Makes scripts and command lines
- portable.
-
- Updated docs accordingly.
-
- Reported-by: Daniel Faust
-
- Fixes #9969
- Closes #9972
-
-- test1662: verify formpost, 301 redirect, no rewind possible
-
- Reproduces #9735 and verifies the subsequent fix. The original issue
- uses a pipe that cannot be rewound, but this test case instead sets a
- callback without rewind ability to get roughly the same properties but
- being a much more portable test.
-
-- lib: rewind BEFORE request instead of AFTER previous
-
- This makes a big difference for cases when the rewind is not actually
- necessary to perofm (for example HTTP response code 301 converts to GET)
- and therefore the rewind can be avoided. In particular for situations
- when that rewind fails, for example when reading from a pipe or similar.
-
- Reported-by: Ali Utku Selen
-
- Fixes #9735
- Closes #9958
-
-- vtls: repair build with disabled proxy
-
- Closes #9974
-
-Daniel Gustafsson (23 Nov 2022)
-
-- packaging: remove traces of deleted files
-
- Commit a8861b6cc removed packages/DOS but left a few traces of it
- which broke the distcheck CI. Remove all traces.
-
- Closes: #9971
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-- openssl: silence compiler warning when not using IPv6
-
- In non-IPv6 builds the conn parameter is unused, and compilers which
- run with "-Werror=unused-parameter" (or similar) warnings turned on
- fails to build. Below is an excerpt from a CI job:
-
- vtls/openssl.c: In function ‘Curl_ossl_verifyhost’:
- vtls/openssl.c:2016:75: error: unused parameter ‘conn’ [-Werror=unused-
- parameter]
- 2016 | CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connec
- tdata *conn,
- | ~~~~~~~~~~~~~
- ~~~~~~~^~~~
-
- Closes: #9970
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-- netware: remove leftover traces
-
- Commit 3b16575ae938dec2a29454631a12aa52b6ab9c67 removed support for
- building on Novell Netware, but a few leftover traces remained. This
- removes the last bits.
-
- Closes: #9966
- Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Ryan Schmidt (23 Nov 2022)
-
-- curl_endian: remove Curl_write64_le from header
-
- The actual function was already removed in 4331c6dc.
-
- See #7280
- Closes #9968
-
-Daniel Stenberg (22 Nov 2022)
-
-- docs: add more "SEE ALSO" links to CA related pages
-
- Closes #9959
-
-- examples: update descriptions
-
- Make them not say "this is an example showing..." and instead just say
- what the example shows.
-
- Closes #9960
-
-Stefan Eissing (22 Nov 2022)
-
-- vtls: localization of state data in filters
-
- - almost all backend calls pass the Curl_cfilter intance instead of
- connectdata+sockindex
- - ssl_connect_data is remove from struct connectdata and made internal
- to vtls
- - ssl_connect_data is allocated in the added filter, kept at cf->ctx
-
- - added function to let a ssl filter access its ssl_primary_config and
- ssl_config_data this selects the propert subfields in conn and data,
- for filters added as plain or proxy
- - adjusted all backends to use the changed api
- - adjusted all backends to access config data via the exposed
- functions, no longer using conn or data directly
-
- cfilter renames for clear purpose:
-
- - methods `Curl_conn_*(data, conn, sockindex)` work on the complete
- filter chain at `sockindex` and connection `conn`.
- - methods `Curl_cf_*(cf, ...)` work on a specific Curl_cfilter
- instance.
- - methods `Curl_conn_cf()` work on/with filter instances at a
- connection.
- - rebased and resolved some naming conflicts
- - hostname validation (und session lookup) on SECONDARY use the same
- name as on FIRST (again).
-
- new debug macros and removing connectdata from function signatures where not
- needed.
-
- adapting schannel for new Curl_read_plain paramter.
-
- Closes #9919
-
-Daniel Stenberg (22 Nov 2022)
-
-- examples/10-at-a-time: fix possible skipped final transfers
-
- Prior to this change if curl_multi_perform returned 0 running handles
- and then all remaining transfers were added, then the perform loop would
- end immediately without performing those transfers.
-
- Reported-by: Mikhail Kuznetsov
-
- Fixes https://github.com/curl/curl/issues/9953
- Closes https://github.com/curl/curl/pull/9954
-
-Viktor Szakats (22 Nov 2022)
-
-- Makefile.mk: portable Makefile.m32
-
- Update bare GNU Make `Makefile.m32` to:
-
- - Move objects into a subdirectory.
- - Add support for MS-DOS. Tested with DJGPP.
- - Add support for Watt-32 (on MS-DOS).
- - Add support for AmigaOS.
- - Rename `Makefile.m32` to `Makefile.mk`
- - Replace `ARCH` with `TRIPLET`.
- - Build `tool_hugehelp.c` proper (when tools are available).
- - Drop MS-DOS compatibility macro `USE_ZLIB` (replaced by `HAVE_LIBZ`)
- - Add support for `ZLIB_LIBS` to override `-lz`.
- - Omit object files when building examples.
- - Default `CC` to `gcc` once again, for convenience. (Caveat: compiler
- name `cc` cannot be set now.)
- - Set `-DCURL_NO_OLDIES` for examples, like autotools does.
- - Delete `makefile.dj` files. Notice the configuration details and
- defaults are not retained with the new method.
- - Delete `makefile.amiga` files. A successful build needs a few custom
- options. We're also not retaining all build details from the existing
- Amiga make files.
- - Rename `Makefile.m32` to `Makefile.mk` to reflect that they are not
- Windows/MinGW32-specific anymore.
- - Add support for new `CFG` options: `-map`, `-debug`, `-trackmem`
- - Set `-DNDEBUG` by default.
- - Allow using `-DOS=...` in all `lib/config-*.h` headers, syncing this
- with `config-win32.h`.
- - Look for zlib parts in `ZLIB_PATH/include` and `ZLIB_PATH/lib`
- instead of bare `ZLIB_PATH`.
-
- Note that existing build configurations for MS-DOS and AmigaOS likely
- become incompatible with this change.
-
- Example AmigaOS configuration:
- ```
- export CROSSPREFIX=/opt/amiga/bin/m68k-amigaos-
- export CC=gcc
- export CPPFLAGS='-DHAVE_PROTO_BSDSOCKET_H'
- export CFLAGS='-mcrt=clib2'
- export LDFLAGS="${CFLAGS}"
- export LIBS='-lnet -lm'
- make -C lib -f Makefile.mk
- make -C src -f Makefile.mk
- ```
-
- Example MS-DOS configuration:
- ```
- export CROSSPREFIX=/opt/djgpp/bin/i586-pc-msdosdjgpp-
- export WATT_PATH=/opt/djgpp/net/watt
- export ZLIB_PATH=/opt/djgpp
- export OPENSSL_PATH=/opt/djgpp
- export OPENSSL_LIBS='-lssl -lcrypt'
- export CFG=-zlib-ssl
- make -C lib -f Makefile.mk
- make -C src -f Makefile.mk
- ```
-
- Closes #9764
-
-Stefan Eissing (22 Nov 2022)
-
-- cfiler: filter types have flags indicating what they do
-
- - Adding Curl_conn_is_ip_connected() to check if network connectivity
- has been reached
-
- - having ftp wait for network connectivity before proceeding with
- transfers.
-
- Fixes test failures 1631 and 1632 with hyper.
-
- Closes #9952
-
-Daniel Stenberg (21 Nov 2022)
-
-- RELEASE-NOTES: synced
-
-Jay Satiro (20 Nov 2022)
-
-- sendf: change Curl_read_plain to wrap Curl_recv_plain (take 2)
-
- Prior to this change Curl_read_plain would attempt to read the
- socket directly. On Windows that's a problem because recv data may be
- cached by libcurl and that data is only drained using Curl_recv_plain.
-
- Rather than rewrite Curl_read_plain to handle cached recv data, I
- changed it to wrap Curl_recv_plain, in much the same way that
- Curl_write_plain already wraps Curl_send_plain.
-
- Curl_read_plain -> Curl_recv_plain
- Curl_write_plain -> Curl_send_plain
-
- This fixes a bug in the schannel backend where decryption of arbitrary
- TLS records fails because cached recv data is never drained. We send
- data (TLS records formed by Schannel) using Curl_write_plain, which
- calls Curl_send_plain, and that may do a recv-before-send
- ("pre-receive") to cache received data. The code calls Curl_read_plain
- to read data (TLS records from the server), which prior to this change
- did not call Curl_recv_plain and therefore cached recv data wasn't
- retrieved, resulting in malformed TLS records and decryption failure
- (SEC_E_DECRYPT_FAILURE).
-
- The bug has only been observed during Schannel TLS 1.3 handshakes. Refer
- to the issue and PR for more information.
-
- --
-
- This is take 2 of the original fix. It preserves the original behavior
- of Curl_read_plain to write 0 to the bytes read parameter on error,
- since apparently some callers expect that (SOCKS tests were hanging).
- The original fix which landed in 12e1def5 and was later reverted in
- 18383fbf failed to work properly because it did not do that.
-
- Also, it changes Curl_write_plain the same way to complement
- Curl_read_plain, and it changes Curl_send_plain to return -1 instead of
- 0 on CURLE_AGAIN to complement Curl_recv_plain.
-
- Behavior on error with these changes:
-
- Curl_recv_plain returns -1 and *code receives error code.
- Curl_send_plain returns -1 and *code receives error code.
- Curl_read_plain returns error code and *n (bytes read) receives 0.
- Curl_write_plain returns error code and *written receives 0.
-
- --
-
- Ref: https://github.com/curl/curl/issues/9431#issuecomment-1312420361
-
- Assisted-by: Joel Depooter
- Reported-by: Egor Pugin
-
- Fixes https://github.com/curl/curl/issues/9431
- Closes https://github.com/curl/curl/pull/9949
-
-Sean McArthur (19 Nov 2022)
-
-- hyper: classify headers as CONNECT and 1XX
-
- Closes #9947
-
-Stefan Eissing (19 Nov 2022)
-
-- ftp: fix "AUTH TLS" on primary conn and for SSL in PASV second conn
-
- Follow-up to dafdb20a26d0c89
-
- Reported-by: Anthony Hu
- Closes #9948
-
-Jay Satiro (19 Nov 2022)
-
-- CURLOPT_POST.3: Explain setting to 0 changes request type
-
- Bug: https://github.com/curl/curl/issues/9849
- Reported-by: MonkeybreadSoftware@users.noreply.github.com
-
- Closes https://github.com/curl/curl/pull/9942
-
-Daniel Stenberg (19 Nov 2022)
-
-- docs/INSTALL.md: expand on static builds
-
- Remove from KNOWN_BUGS
-
- Closes #9944
-
-Stefan Eissing (19 Nov 2022)
-
-- http: restore h3 to working condition after connection filter introduction
-
- Follow-up to dafdb20a26d0c
-
- HTTP/3 needs a special filter chain, since it does the TLS handling
- itself. This PR adds special setup handling in the HTTP protocol handler
- that takes are of it.
-
- When a handler, in its setup method, installs filters, the default
- behaviour for managing the filter chain is overridden.
-
- Reported-by: Karthikdasari0423 on github
-
- Fixes #9931
- Closes #9945
-
-Daniel Stenberg (18 Nov 2022)
-
-- urldata: change port num storage to int and unsigned short
-
- Instead of long.
-
- Closes #9946
-
-- Revert "sendf: change Curl_read_plain to wrap Curl_recv_plain"
-
- This reverts commit 12e1def51a75392df62e65490416007d7e68dab9.
-
- It introduced SOCKS proxy fails, like test 700 never ending.
-
- Reopens #9431
-
-- HTTP-COOKIES.md: update the 6265bis link to draft-11
-
- Closes #9940
-
-- docs/WEBSOCKET.md: explain the URL use
-
- Fixes #9936
- Closes #9941
-
-Jay Satiro (18 Nov 2022)
-
-- sendf: change Curl_read_plain to wrap Curl_recv_plain
-
- Prior to this change Curl_read_plain would attempt to read the
- socket directly. On Windows that's a problem because recv data may be
- cached by libcurl and that data is only drained using Curl_recv_plain.
-
- Rather than rewrite Curl_read_plain to handle cached recv data, I
- changed it to wrap Curl_recv_plain, in much the same way that
- Curl_write_plain already wraps Curl_send_plain.
-
- Curl_read_plain -> Curl_recv_plain
- Curl_write_plain -> Curl_send_plain
-
- This fixes a bug in the schannel backend where decryption of arbitrary
- TLS records fails because cached recv data is never drained. We send
- data (TLS records formed by Schannel) using Curl_write_plain, which
- calls Curl_send_plain, and that may do a recv-before-send
- ("pre-receive") to cache received data. The code calls Curl_read_plain
- to read data (TLS records from the server), which prior to this change
- did not call Curl_recv_plain and therefore cached recv data wasn't
- retrieved, resulting in malformed TLS records and decryption failure
- (SEC_E_DECRYPT_FAILURE).
-
- The bug has only been observed during Schannel TLS 1.3 handshakes. Refer
- to the issue and PR for more information.
-
- Ref: https://github.com/curl/curl/issues/9431#issuecomment-1312420361
-
- Assisted-by: Joel Depooter
- Reported-by: Egor Pugin
-
- Fixes https://github.com/curl/curl/issues/9431
- Closes https://github.com/curl/curl/pull/9904
-
-- test3026: reduce runtime in legacy mingw builds
-
- - Load Windows system libraries secur32 and iphlpapi beforehand, so
- that libcurl's repeated global init/cleanup only increases/decreases
- the library's refcount rather than causing it to load/unload.
-
- Assisted-by: Marc Hoersken
-
- Closes https://github.com/curl/curl/pull/9412
-
-Daniel Stenberg (18 Nov 2022)
-
-- url: move back the IDN conversion of proxy names
-
- Regression: in commit 53bcf55 we moved the IDN conversion calls to
- happen before the HSTS checks. But the HSTS checks are only done on the
- server host name, not the proxy names. By moving the proxy name IDN
- conversions, we accidentally broke the verbose output showing the proxy
- name.
-
- This change moves back the IDN conversions for the proxy names to the
- place in the code path they were before 53bcf55.
-
- Reported-by: Andy Stamp
- Fixes #9937
- Closes #9939
diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS
index 0536b26a5a..9a0ea00fae 100644
--- a/libs/libcurl/docs/THANKS
+++ b/libs/libcurl/docs/THANKS
@@ -22,6 +22,7 @@ Abhinav Singh
Abram Pousada
accountantM on github
AceCrow on Github
+ad0p on github
Adam Averay
Adam Barclay
Adam Brown
@@ -201,6 +202,7 @@ Angus Mackay
anio on github
anon00000000 on github
anshnd on github
+Anssi Kolehmainen
Antarpreet Singh
Anthon Pang
Anthony Avina
@@ -211,6 +213,7 @@ Anthony Ramine
Anthony Shaw
Antoine Aubert
Antoine Calando
+Antoine du Hamel
Antoine Pietri
Antoine Pitrou
Anton Bychkov
@@ -246,6 +249,7 @@ Ask Bjørn Hansen
Askar Safin
AtariDreams on github
Ates Goral
+atjg on github
Augustus Saunders
Austin Green
Avery Fay
@@ -370,6 +374,7 @@ Brian Green
Brian Inglis
Brian J. Murrell
Brian Lund
+Brian Nixon
Brian Prodoehl
Brian R Duffy
Brian Ulm
@@ -445,6 +450,7 @@ Chris Mumford
Chris Paulson-Ellis
Chris Roberts
Chris Smowton
+Chris Talbot
Chris Young
Christian Fillion
Christian Grothoff
@@ -655,6 +661,7 @@ Denis Ollier
Dennis Clarke
Dennis Felsing
Derek Higgins
+Derzsi Dániel
Desmond O. Chang
destman on github
Detlef Schmier
@@ -674,6 +681,7 @@ Dimitrios Siganos
Dimitris Sarris
Dinar
Diogo Teles Sant'Anna
+Dion Williams
Dirk Eddelbuettel
Dirk Feytons
Dirk Manske
@@ -963,6 +971,7 @@ Google Inc.
Gordon Marler
Gorilla Maguila
Gou Lingfeng
+Graham Campbell
Grant Erickson
Grant Pannell
Greg Hewgill
@@ -1055,6 +1064,7 @@ htasta on github
Hubert Kario
Hugh Macdonald
Hugo van Kemenade
+humbleacolyte
Huzaifa Sidhpurwala
huzunhao on github
hydra3333 on github
@@ -1075,6 +1085,7 @@ Igor Khristophorov
Igor Makarov
Igor Novoseltsev
Igor Polyakov
+Igor Todorovski
Ihor Karpenko
ihsinme on github
Iida Yosiaki
@@ -1140,6 +1151,7 @@ James Housley
James Keast
James Knight
James Le Cuirot
+James Lucas
James MacMillan
James Slaughter
Jamie Lokier
@@ -1182,6 +1194,7 @@ Jay Austin
Jay Dommaschk
Jayesh A Shah
Jaz Fresh
+jbgoog on github
Jean Fabrice
Jean Gressmann
Jean Jacques Drouin
@@ -1363,6 +1376,7 @@ Josue Andrade Gomes
José Joaquín Atria
Jozef Kralik
Juan Barreto
+Juan Cruz Viotti
Juan F. Codagnone
Juan Ignacio Hervás
Juan RP
@@ -1387,6 +1401,7 @@ Junho Choi
Jurij Smakov
jurisuk on github
Juro Bystricky
+JustAnotherArchivist on github
justchen1369 on github
Justin Clift
Justin Ehlert
@@ -1421,6 +1436,7 @@ Kari Pahula
Karl Chen
Karl Moerder
Karol Pietrzak
+Karthikdasari0423
Karthikdasari0423 on github
Kartik Mahajan
Kaspar Brand
@@ -1561,6 +1577,7 @@ Lisa Xu
Litter White
Liviu Chircu
Liza Alenchery
+lizhuang0630 on github
lllaffer on github
Lloyd Fournier
Lluís Batlle i Rossell
@@ -1604,6 +1621,7 @@ Maciej Karpiuk
Maciej Puzio
Maciej W. Rozycki
madblobfish on github
+MaeIsBad on github
Mahmoud Samir Fayed
Maks Naumov
Maksim Kuzevanov
@@ -1644,6 +1662,7 @@ Marcus Klein
Marcus Sundberg
Marcus T
Marcus Webster
+Margu
Marian Klymov
Mario Schroeder
Mark Brand
@@ -1659,6 +1678,7 @@ Mark Lentczner
Mark Nottingham
Mark Roszko
Mark Salisbury
+Mark Seuffert
Mark Snelling
Mark Swaanenburg
Mark Tully
@@ -1820,6 +1840,7 @@ Michał Fita
Michał Górny
Michał Janiszewski
Michał Kowalczyk
+Michał Petryka
Michał Piechowski
Michel Promonet
Michele Bini
@@ -1968,6 +1989,7 @@ Ola Mork
Olaf Flebbe
Olaf Hering
Olaf Stüben
+Oleg Jukovec
Oleg Pudeyev
Oleguer Llopart
Olen Andoni
@@ -1984,6 +2006,7 @@ Olivier Berger
Olivier Brunel
Omar Ramadan
omau on github
+Ondřej Koláček
opensignature on github
opensslonzos-github on github
Orange Tsai
@@ -2047,6 +2070,7 @@ Paul Querna
Paul Saab
Paul Seligman
Paul Vixie
+Paul Wise
Paulo Roberto Tomasi
Pavel Cenek
Pavel Gushchin
@@ -2063,6 +2087,7 @@ Pawel A. Gajda
Pawel Kierski
Paweł Kowalski
Paweł Wegner
+Pedro Henrique
Pedro Larroy
Pedro Monreal
Pedro Neves
@@ -2137,6 +2162,7 @@ Pierrick Charron
Piotr Dobrogost
Piotr Komborski
Po-Chuan Hsieh
+Pontakorn Prasertsuk
Pontus Lundkvist
Pooyan McSporran
Poul T Lomholt
@@ -2174,6 +2200,7 @@ Rainer Canavan
Rainer Jung
Rainer Koenig
Rainer Müller
+Raito Bezarius
Rajesh Naganathan
Rajkumar Mandal
Ralf S. Engelschall
@@ -2354,6 +2381,7 @@ S. Moonesamy
Sai Ram Kunala
Salah-Eddin Shaban
Saleem Abdulrasool
+SaltyMilk
Salvador Dávila
Salvatore Sorrentino
Sam Deane
@@ -2402,10 +2430,12 @@ Sebastian Mundry
Sebastian Pohlschmidt
Sebastian Rasmussen
Sebastian Sterk
+selmelc on hackerone
SendSonS on github
Senthil Raja Velu
Sergei Kuzmin
Sergei Nikulov
+Sergey Alirzaev
Sergey Bronnikov
Sergey Fionov
Sergey Markelov
@@ -2440,6 +2470,7 @@ Shaun Jackman
Shaun Mirani
Shawn Landden
Shawn Poulson
+Sheshadri.V
Shikha Sharma
Shine Fan
Shiraz Kanga
@@ -2767,6 +2798,7 @@ Vladimir Lazarenko
Vladimir Panteleev
Vladimir Varlamov
Vlastimil Ovčáčík
+vlkl-sap on github
vlubart on github
Vojtech Janota
Vojtech Minarik
diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h
index 608ff6efc5..b6cc8e8795 100644
--- a/libs/libcurl/include/curl/curl.h
+++ b/libs/libcurl/include/curl/curl.h
@@ -93,7 +93,7 @@
defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
(defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \
- defined(__sun__) || defined(__serenity__)
+ defined(__sun__) || defined(__serenity__) || defined(__vxworks__)
#include <sys/select.h>
#endif
@@ -781,7 +781,7 @@ typedef enum {
CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
HTTP/1.0 */
CURLPROXY_HTTPS = 2, /* HTTPS but stick to HTTP/1 added in 7.52.0 */
- CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.1.0 */
+ CURLPROXY_HTTPS2 = 3, /* HTTPS and attempt HTTP/2 added in 8.2.0 */
CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
in 7.10 */
CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
@@ -2113,7 +2113,7 @@ typedef enum {
CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289),
/* allow RCPT TO command to fail for some recipients */
- CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290),
+ CURLOPT(CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOPTTYPE_LONG, 290),
/* the private SSL-certificate as a "blob" */
CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
@@ -2207,6 +2207,9 @@ typedef enum {
/* Can leak things, gonna exit() soon */
CURLOPT(CURLOPT_QUICK_EXIT, CURLOPTTYPE_LONG, 322),
+ /* set a specific client IP for HAProxy PROXY protocol header? */
+ CURLOPT(CURLOPT_HAPROXY_CLIENT_IP, CURLOPTTYPE_STRINGPOINT, 323),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2235,6 +2238,9 @@ typedef enum {
/* */
#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT
+/* Added in 8.2.0 */
+#define CURLOPT_MAIL_RCPT_ALLLOWFAILS CURLOPT_MAIL_RCPT_ALLOWFAILS
+
#else
/* This is set if CURL_NO_OLDIES is defined at compile-time */
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
@@ -2918,7 +2924,9 @@ typedef enum {
CURLINFO_REFERER = CURLINFO_STRING + 60,
CURLINFO_CAINFO = CURLINFO_STRING + 61,
CURLINFO_CAPATH = CURLINFO_STRING + 62,
- CURLINFO_LASTONE = 62
+ CURLINFO_XFER_ID = CURLINFO_OFF_T + 63,
+ CURLINFO_CONN_ID = CURLINFO_OFF_T + 64,
+ CURLINFO_LASTONE = 64
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h
index 8b2d773a6c..a71880e44e 100644
--- a/libs/libcurl/include/curl/curlver.h
+++ b/libs/libcurl/include/curl/curlver.h
@@ -32,13 +32,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "8.1.2"
+#define LIBCURL_VERSION "8.2.0"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 8
-#define LIBCURL_VERSION_MINOR 1
-#define LIBCURL_VERSION_PATCH 2
+#define LIBCURL_VERSION_MINOR 2
+#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
@@ -59,7 +59,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x080102
+#define LIBCURL_VERSION_NUM 0x080200
/*
* This is the date and time when the full source package was created. The
@@ -70,7 +70,7 @@
*
* "2007-11-23"
*/
-#define LIBCURL_TIMESTAMP "2023-05-30"
+#define LIBCURL_TIMESTAMP "2023-07-19"
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
#define CURL_AT_LEAST_VERSION(x,y,z) \
diff --git a/libs/libcurl/include/curl/system.h b/libs/libcurl/include/curl/system.h
index 990cd9ff1f..556ffa9c9b 100644
--- a/libs/libcurl/include/curl/system.h
+++ b/libs/libcurl/include/curl/system.h
@@ -237,33 +237,28 @@
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__MVS__)
-# if defined(__IBMC__) || defined(__IBMCPP__)
-# if defined(_ILP32)
-# elif defined(_LP64)
-# endif
-# if defined(_LONG_LONG)
-# define CURL_TYPEOF_CURL_OFF_T long long
-# define CURL_FORMAT_CURL_OFF_T "lld"
-# define CURL_FORMAT_CURL_OFF_TU "llu"
-# define CURL_SUFFIX_CURL_OFF_T LL
-# define CURL_SUFFIX_CURL_OFF_TU ULL
-# elif defined(_LP64)
-# define CURL_TYPEOF_CURL_OFF_T long
-# define CURL_FORMAT_CURL_OFF_T "ld"
-# define CURL_FORMAT_CURL_OFF_TU "lu"
-# define CURL_SUFFIX_CURL_OFF_T L
-# define CURL_SUFFIX_CURL_OFF_TU UL
-# else
-# define CURL_TYPEOF_CURL_OFF_T long
-# define CURL_FORMAT_CURL_OFF_T "ld"
-# define CURL_FORMAT_CURL_OFF_TU "lu"
-# define CURL_SUFFIX_CURL_OFF_T L
-# define CURL_SUFFIX_CURL_OFF_TU UL
-# endif
-# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
-# define CURL_PULL_SYS_TYPES_H 1
-# define CURL_PULL_SYS_SOCKET_H 1
+# if defined(_LONG_LONG)
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+# elif defined(_LP64)
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+# else
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
+# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+# define CURL_PULL_SYS_TYPES_H 1
+# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__370__)
# if defined(__IBMC__) || defined(__IBMCPP__)
diff --git a/libs/libcurl/include/curl/typecheck-gcc.h b/libs/libcurl/include/curl/typecheck-gcc.h
index a67a9145c3..b3fb12b358 100644
--- a/libs/libcurl/include/curl/typecheck-gcc.h
+++ b/libs/libcurl/include/curl/typecheck-gcc.h
@@ -280,6 +280,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
(option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_HSTS || \
+ (option) == CURLOPT_HAPROXY_CLIENT_IP || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_ISSUERCERT || \
(option) == CURLOPT_KEYPASSWD || \
diff --git a/libs/libcurl/include/curl/websockets.h b/libs/libcurl/include/curl/websockets.h
index d6c2e47381..774e85a4cf 100644
--- a/libs/libcurl/include/curl/websockets.h
+++ b/libs/libcurl/include/curl/websockets.h
@@ -54,7 +54,7 @@ struct curl_ws_frame {
*/
CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
size_t *recv,
- struct curl_ws_frame **metap);
+ const struct curl_ws_frame **metap);
/* sendflags for curl_ws_send() */
#define CURLWS_PONG (1<<6)
@@ -75,7 +75,7 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
/* bits for the CURLOPT_WS_OPTIONS bitmask: */
#define CURLWS_RAW_MODE (1<<0)
-CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl);
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl);
#ifdef __cplusplus
}
diff --git a/libs/libcurl/libcurl.vcxproj b/libs/libcurl/libcurl.vcxproj
index ae88c6edb0..e07dc059cd 100644
--- a/libs/libcurl/libcurl.vcxproj
+++ b/libs/libcurl/libcurl.vcxproj
@@ -263,6 +263,9 @@
<ClCompile Include="src\llist.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\macos.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\md4.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -572,6 +575,7 @@
<ClInclude Include="src\inet_ntop.h" />
<ClInclude Include="src\inet_pton.h" />
<ClInclude Include="src\llist.h" />
+ <ClInclude Include="src\macos.h" />
<ClInclude Include="src\memdebug.h" />
<ClInclude Include="src\mime.h" />
<ClInclude Include="src\mqtt.h" />
diff --git a/libs/libcurl/libcurl.vcxproj.filters b/libs/libcurl/libcurl.vcxproj.filters
index b7049ee81d..6828329cc8 100644
--- a/libs/libcurl/libcurl.vcxproj.filters
+++ b/libs/libcurl/libcurl.vcxproj.filters
@@ -239,6 +239,9 @@
<ClCompile Include="src\llist.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\macos.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="src\md4.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -769,6 +772,9 @@
<ClInclude Include="src\llist.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\macos.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="src\memdebug.h">
<Filter>Header Files</Filter>
</ClInclude>
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt
index 7e0be5a1eb..6d404d588b 100644
--- a/libs/libcurl/src/CMakeLists.txt
+++ b/libs/libcurl/src/CMakeLists.txt
@@ -69,6 +69,12 @@ add_library(
ALIAS ${LIB_NAME}
)
+if(ENABLE_CURLDEBUG)
+ # We must compile memdebug.c separately to avoid memdebug.h redefinitions
+ # being applied to memdebug.c itself.
+ set_source_files_properties(memdebug.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
+endif()
+
if(NOT BUILD_SHARED_LIBS)
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
endif()
diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in
index 8ae1bceda7..aced171048 100644
--- a/libs/libcurl/src/Makefile.in
+++ b/libs/libcurl/src/Makefile.in
@@ -226,11 +226,11 @@ am__libcurl_la_SOURCES_DIST = altsvc.c amigaos.c asyn-ares.c \
hostip4.c hostip6.c hostsyn.c hsts.c http.c http1.c http2.c \
http_chunks.c http_digest.c http_negotiate.c http_ntlm.c \
http_proxy.c http_aws_sigv4.c idn.c if2ip.c imap.c inet_ntop.c \
- inet_pton.c krb5.c ldap.c llist.c md4.c md5.c memdebug.c \
- mime.c mprintf.c mqtt.c multi.c netrc.c nonblock.c noproxy.c \
- openldap.c parsedate.c pingpong.c pop3.c progress.c psl.c \
- rand.c rename.c rtsp.c select.c sendf.c setopt.c sha256.c \
- share.c slist.c smb.c smtp.c socketpair.c socks.c \
+ inet_pton.c krb5.c ldap.c llist.c macos.c md4.c md5.c \
+ memdebug.c mime.c mprintf.c mqtt.c multi.c netrc.c nonblock.c \
+ noproxy.c openldap.c parsedate.c pingpong.c pop3.c progress.c \
+ psl.c rand.c rename.c rtsp.c select.c sendf.c setopt.c \
+ sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c \
strdup.c strerror.c strtok.c strtoofft.c system_win32.c \
telnet.c tftp.c timediff.c timeval.c transfer.c url.c urlapi.c \
@@ -262,8 +262,8 @@ am__libcurl_la_SOURCES_DIST = altsvc.c amigaos.c asyn-ares.c \
gopher.h hash.h headers.h hostip.h hsts.h http.h http1.h \
http2.h http_chunks.h http_digest.h http_negotiate.h \
http_ntlm.h http_proxy.h http_aws_sigv4.h idn.h if2ip.h imap.h \
- inet_ntop.h inet_pton.h llist.h memdebug.h mime.h mqtt.h \
- multihandle.h multiif.h netrc.h nonblock.h noproxy.h \
+ inet_ntop.h inet_pton.h llist.h macos.h memdebug.h mime.h \
+ mqtt.h multihandle.h multiif.h netrc.h nonblock.h noproxy.h \
parsedate.h pingpong.h pop3.h progress.h psl.h rand.h rename.h \
rtsp.h select.h sendf.h setopt.h setup-vms.h share.h sigpipe.h \
slist.h smb.h smtp.h sockaddr.h socketpair.h socks.h \
@@ -274,10 +274,11 @@ am__libcurl_la_SOURCES_DIST = altsvc.c amigaos.c asyn-ares.c \
vauth/vauth.h vtls/bearssl.h vtls/gskit.h vtls/gtls.h \
vtls/hostcheck.h vtls/keylog.h vtls/mbedtls.h \
vtls/mbedtls_threadlock.h vtls/nssg.h vtls/openssl.h \
- vtls/rustls.h vtls/schannel.h vtls/sectransp.h vtls/vtls.h \
- vtls/vtls_int.h vtls/wolfssl.h vtls/x509asn1.h \
- vquic/curl_msh3.h vquic/curl_ngtcp2.h vquic/curl_quiche.h \
- vquic/vquic.h vquic/vquic_int.h vssh/ssh.h libcurl.rc
+ vtls/rustls.h vtls/schannel.h vtls/schannel_int.h \
+ vtls/sectransp.h vtls/vtls.h vtls/vtls_int.h vtls/wolfssl.h \
+ vtls/x509asn1.h vquic/curl_msh3.h vquic/curl_ngtcp2.h \
+ vquic/curl_quiche.h vquic/vquic.h vquic/vquic_int.h vssh/ssh.h \
+ libcurl.rc
am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \
libcurl_la-asyn-ares.lo libcurl_la-asyn-thread.lo \
libcurl_la-base64.lo libcurl_la-bufq.lo libcurl_la-bufref.lo \
@@ -314,9 +315,10 @@ am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \
libcurl_la-idn.lo libcurl_la-if2ip.lo libcurl_la-imap.lo \
libcurl_la-inet_ntop.lo libcurl_la-inet_pton.lo \
libcurl_la-krb5.lo libcurl_la-ldap.lo libcurl_la-llist.lo \
- libcurl_la-md4.lo libcurl_la-md5.lo libcurl_la-memdebug.lo \
- libcurl_la-mime.lo libcurl_la-mprintf.lo libcurl_la-mqtt.lo \
- libcurl_la-multi.lo libcurl_la-netrc.lo libcurl_la-nonblock.lo \
+ libcurl_la-macos.lo libcurl_la-md4.lo libcurl_la-md5.lo \
+ libcurl_la-memdebug.lo libcurl_la-mime.lo \
+ libcurl_la-mprintf.lo libcurl_la-mqtt.lo libcurl_la-multi.lo \
+ libcurl_la-netrc.lo libcurl_la-nonblock.lo \
libcurl_la-noproxy.lo libcurl_la-openldap.lo \
libcurl_la-parsedate.lo libcurl_la-pingpong.lo \
libcurl_la-pop3.lo libcurl_la-progress.lo libcurl_la-psl.lo \
@@ -410,8 +412,9 @@ am__objects_11 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \
libcurlu_la-idn.lo libcurlu_la-if2ip.lo libcurlu_la-imap.lo \
libcurlu_la-inet_ntop.lo libcurlu_la-inet_pton.lo \
libcurlu_la-krb5.lo libcurlu_la-ldap.lo libcurlu_la-llist.lo \
- libcurlu_la-md4.lo libcurlu_la-md5.lo libcurlu_la-memdebug.lo \
- libcurlu_la-mime.lo libcurlu_la-mprintf.lo libcurlu_la-mqtt.lo \
+ libcurlu_la-macos.lo libcurlu_la-md4.lo libcurlu_la-md5.lo \
+ libcurlu_la-memdebug.lo libcurlu_la-mime.lo \
+ libcurlu_la-mprintf.lo libcurlu_la-mqtt.lo \
libcurlu_la-multi.lo libcurlu_la-netrc.lo \
libcurlu_la-nonblock.lo libcurlu_la-noproxy.lo \
libcurlu_la-openldap.lo libcurlu_la-parsedate.lo \
@@ -556,6 +559,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurl_la-krb5.Plo \
./$(DEPDIR)/libcurl_la-ldap.Plo \
./$(DEPDIR)/libcurl_la-llist.Plo \
+ ./$(DEPDIR)/libcurl_la-macos.Plo \
./$(DEPDIR)/libcurl_la-md4.Plo ./$(DEPDIR)/libcurl_la-md5.Plo \
./$(DEPDIR)/libcurl_la-memdebug.Plo \
./$(DEPDIR)/libcurl_la-mime.Plo \
@@ -682,6 +686,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurlu_la-krb5.Plo \
./$(DEPDIR)/libcurlu_la-ldap.Plo \
./$(DEPDIR)/libcurlu_la-llist.Plo \
+ ./$(DEPDIR)/libcurlu_la-macos.Plo \
./$(DEPDIR)/libcurlu_la-md4.Plo \
./$(DEPDIR)/libcurlu_la-md5.Plo \
./$(DEPDIR)/libcurlu_la-memdebug.Plo \
@@ -1006,7 +1011,7 @@ USE_NGHTTP2 = @USE_NGHTTP2@
USE_NGHTTP3 = @USE_NGHTTP3@
USE_NGTCP2 = @USE_NGTCP2@
USE_NGTCP2_CRYPTO_GNUTLS = @USE_NGTCP2_CRYPTO_GNUTLS@
-USE_NGTCP2_CRYPTO_OPENSSL = @USE_NGTCP2_CRYPTO_OPENSSL@
+USE_NGTCP2_CRYPTO_QUICTLS = @USE_NGTCP2_CRYPTO_QUICTLS@
USE_NGTCP2_CRYPTO_WOLFSSL = @USE_NGTCP2_CRYPTO_WOLFSSL@
USE_NSS = @USE_NSS@
USE_OPENLDAP = @USE_OPENLDAP@
@@ -1183,6 +1188,7 @@ LIB_VTLS_HFILES = \
vtls/openssl.h \
vtls/rustls.h \
vtls/schannel.h \
+ vtls/schannel_int.h \
vtls/sectransp.h \
vtls/vtls.h \
vtls/vtls_int.h \
@@ -1290,6 +1296,7 @@ LIB_CFILES = \
krb5.c \
ldap.c \
llist.c \
+ macos.c \
md4.c \
md5.c \
memdebug.c \
@@ -1426,6 +1433,7 @@ LIB_HFILES = \
inet_ntop.h \
inet_pton.h \
llist.h \
+ macos.h \
memdebug.h \
mime.h \
mqtt.h \
@@ -1871,6 +1879,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-krb5.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ldap.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-llist.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-macos.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-md4.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-md5.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-memdebug.Plo@am__quote@ # am--include-marker
@@ -2000,6 +2009,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-krb5.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ldap.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-llist.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-macos.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-md4.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-md5.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-memdebug.Plo@am__quote@ # am--include-marker
@@ -2706,6 +2716,13 @@ libcurl_la-llist.lo: llist.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-llist.lo `test -f 'llist.c' || echo '$(srcdir)/'`llist.c
+libcurl_la-macos.lo: macos.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-macos.lo -MD -MP -MF $(DEPDIR)/libcurl_la-macos.Tpo -c -o libcurl_la-macos.lo `test -f 'macos.c' || echo '$(srcdir)/'`macos.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-macos.Tpo $(DEPDIR)/libcurl_la-macos.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='macos.c' object='libcurl_la-macos.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-macos.lo `test -f 'macos.c' || echo '$(srcdir)/'`macos.c
+
libcurl_la-md4.lo: md4.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-md4.lo -MD -MP -MF $(DEPDIR)/libcurl_la-md4.Tpo -c -o libcurl_la-md4.lo `test -f 'md4.c' || echo '$(srcdir)/'`md4.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-md4.Tpo $(DEPDIR)/libcurl_la-md4.Plo
@@ -3861,6 +3878,13 @@ libcurlu_la-llist.lo: llist.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-llist.lo `test -f 'llist.c' || echo '$(srcdir)/'`llist.c
+libcurlu_la-macos.lo: macos.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-macos.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-macos.Tpo -c -o libcurlu_la-macos.lo `test -f 'macos.c' || echo '$(srcdir)/'`macos.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-macos.Tpo $(DEPDIR)/libcurlu_la-macos.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='macos.c' object='libcurlu_la-macos.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-macos.lo `test -f 'macos.c' || echo '$(srcdir)/'`macos.c
+
libcurlu_la-md4.lo: md4.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-md4.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-md4.Tpo -c -o libcurlu_la-md4.lo `test -f 'md4.c' || echo '$(srcdir)/'`md4.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-md4.Tpo $(DEPDIR)/libcurlu_la-md4.Plo
@@ -4688,6 +4712,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurl_la-krb5.Plo
-rm -f ./$(DEPDIR)/libcurl_la-ldap.Plo
-rm -f ./$(DEPDIR)/libcurl_la-llist.Plo
+ -rm -f ./$(DEPDIR)/libcurl_la-macos.Plo
-rm -f ./$(DEPDIR)/libcurl_la-md4.Plo
-rm -f ./$(DEPDIR)/libcurl_la-md5.Plo
-rm -f ./$(DEPDIR)/libcurl_la-memdebug.Plo
@@ -4817,6 +4842,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurlu_la-krb5.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-ldap.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-llist.Plo
+ -rm -f ./$(DEPDIR)/libcurlu_la-macos.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-md4.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-md5.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-memdebug.Plo
@@ -5063,6 +5089,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurl_la-krb5.Plo
-rm -f ./$(DEPDIR)/libcurl_la-ldap.Plo
-rm -f ./$(DEPDIR)/libcurl_la-llist.Plo
+ -rm -f ./$(DEPDIR)/libcurl_la-macos.Plo
-rm -f ./$(DEPDIR)/libcurl_la-md4.Plo
-rm -f ./$(DEPDIR)/libcurl_la-md5.Plo
-rm -f ./$(DEPDIR)/libcurl_la-memdebug.Plo
@@ -5192,6 +5219,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurlu_la-krb5.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-ldap.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-llist.Plo
+ -rm -f ./$(DEPDIR)/libcurlu_la-macos.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-md4.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-md5.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-memdebug.Plo
diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc
index c0f3c662c9..996a2b8cae 100644
--- a/libs/libcurl/src/Makefile.inc
+++ b/libs/libcurl/src/Makefile.inc
@@ -72,6 +72,7 @@ LIB_VTLS_HFILES = \
vtls/openssl.h \
vtls/rustls.h \
vtls/schannel.h \
+ vtls/schannel_int.h \
vtls/sectransp.h \
vtls/vtls.h \
vtls/vtls_int.h \
@@ -179,6 +180,7 @@ LIB_CFILES = \
krb5.c \
ldap.c \
llist.c \
+ macos.c \
md4.c \
md5.c \
memdebug.c \
@@ -315,6 +317,7 @@ LIB_HFILES = \
inet_ntop.h \
inet_pton.h \
llist.h \
+ macos.h \
memdebug.h \
mime.h \
mqtt.h \
diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c
index ca9f670b29..724bf17cd8 100644
--- a/libs/libcurl/src/altsvc.c
+++ b/libs/libcurl/src/altsvc.c
@@ -424,7 +424,7 @@ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
#ifdef DEBUGBUILD
/* to play well with debug builds, we can *set* a fixed time this will
return */
-static time_t debugtime(void *unused)
+static time_t altsvc_debugtime(void *unused)
{
char *timestr = getenv("CURL_TIME");
(void)unused;
@@ -434,7 +434,8 @@ static time_t debugtime(void *unused)
}
return time(NULL);
}
-#define time(x) debugtime(x)
+#undef time
+#define time(x) altsvc_debugtime(x)
#endif
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
diff --git a/libs/libcurl/src/base64.c b/libs/libcurl/src/base64.c
index 5d52992485..7e5531e737 100644
--- a/libs/libcurl/src/base64.c
+++ b/libs/libcurl/src/base64.c
@@ -43,7 +43,7 @@
/* ---- Base64 Encoding/Decoding Table --- */
/* Padding character string starts at offset 64. */
-static const char base64[]=
+static const char base64encdec[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
@@ -120,7 +120,7 @@ CURLcode Curl_base64_decode(const char *src,
/* replaces
{
unsigned char c;
- const unsigned char *p = (const unsigned char *)base64;
+ const unsigned char *p = (const unsigned char *)base64encdec;
for(c = 0; *p; c++, p++)
lookup[*p] = c;
}
@@ -264,7 +264,7 @@ static CURLcode base64_encode(const char *table64,
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
- return base64_encode(base64, inputbuff, insize, outptr, outlen);
+ return base64_encode(base64encdec, inputbuff, insize, outptr, outlen);
}
/*
diff --git a/libs/libcurl/src/bufq.c b/libs/libcurl/src/bufq.c
index de86b7136e..d851e63400 100644
--- a/libs/libcurl/src/bufq.c
+++ b/libs/libcurl/src/bufq.c
@@ -418,7 +418,8 @@ ssize_t Curl_bufq_write(struct bufq *q,
break;
}
n = chunk_append(tail, buf, len);
- DEBUGASSERT(n);
+ if(!n)
+ break;
nwritten += n;
buf += n;
len -= n;
@@ -528,6 +529,14 @@ ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
}
break;
}
+ if(!chunk_written) {
+ if(!nwritten) {
+ /* treat as blocked */
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ }
+ break;
+ }
Curl_bufq_skip(q, (size_t)chunk_written);
nwritten += chunk_written;
}
@@ -551,7 +560,8 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */
return -1;
}
- /* would block */
+ /* would block, bufq is full, give up */
+ break;
}
}
@@ -562,16 +572,25 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */
return -1;
}
- /* no room in bufq, bail out */
- goto out;
+ /* no room in bufq */
+ break;
}
+ /* edge case of writer returning 0 (and len is >0)
+ * break or we might enter an infinite loop here */
+ if(n == 0)
+ break;
+
/* Maybe only part of `data` has been added, continue to loop */
buf += (size_t)n;
len -= (size_t)n;
nwritten += (size_t)n;
}
-out:
+ if(!nwritten && len) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ *err = CURLE_OK;
return nwritten;
}
diff --git a/libs/libcurl/src/c-hyper.c b/libs/libcurl/src/c-hyper.c
index b36341e2f3..ea8d2248f3 100644
--- a/libs/libcurl/src/c-hyper.c
+++ b/libs/libcurl/src/c-hyper.c
@@ -71,9 +71,11 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
DEBUGASSERT(conn);
(void)ctx;
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu)", buflen));
result = Curl_read(data, conn->sockfd, (char *)buf, buflen, &nread);
if(result == CURLE_AGAIN) {
/* would block, register interest */
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> EAGAIN", buflen));
if(data->hyp.read_waker)
hyper_waker_free(data->hyp.read_waker);
data->hyp.read_waker = hyper_context_waker(ctx);
@@ -87,6 +89,7 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
failf(data, "Curl_read failed");
return HYPER_IO_ERROR;
}
+ DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> %zd", buflen, nread));
return (size_t)nread;
}
@@ -98,8 +101,12 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx,
CURLcode result;
ssize_t nwrote;
+ DEBUGF(infof(data, "Curl_hyper_send(%zu)", buflen));
result = Curl_write(data, conn->sockfd, (void *)buf, buflen, &nwrote);
+ if(!result && !nwrote)
+ result = CURLE_AGAIN;
if(result == CURLE_AGAIN) {
+ DEBUGF(infof(data, "Curl_hyper_send(%zu) -> EAGAIN", buflen));
/* would block, register interest */
if(data->hyp.write_waker)
hyper_waker_free(data->hyp.write_waker);
@@ -114,6 +121,7 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx,
failf(data, "Curl_write failed");
return HYPER_IO_ERROR;
}
+ DEBUGF(infof(data, "Curl_hyper_send(%zu) -> %zd", buflen, nwrote));
return (size_t)nwrote;
}
@@ -433,8 +441,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
break;
}
else if(t != HYPER_TASK_RESPONSE) {
- *didwhat = KEEP_RECV;
- break;
+ continue;
}
/* HYPER_TASK_RESPONSE */
diff --git a/libs/libcurl/src/cf-h1-proxy.c b/libs/libcurl/src/cf-h1-proxy.c
index 3d886e1ea9..57277598b0 100644
--- a/libs/libcurl/src/cf-h1-proxy.c
+++ b/libs/libcurl/src/cf-h1-proxy.c
@@ -54,16 +54,16 @@
typedef enum {
- TUNNEL_INIT, /* init/default/no tunnel state */
- TUNNEL_CONNECT, /* CONNECT request is being send */
- TUNNEL_RECEIVE, /* CONNECT answer is being received */
- TUNNEL_RESPONSE, /* CONNECT response received completely */
- TUNNEL_ESTABLISHED,
- TUNNEL_FAILED
-} tunnel_state;
+ H1_TUNNEL_INIT, /* init/default/no tunnel state */
+ H1_TUNNEL_CONNECT, /* CONNECT request is being send */
+ H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
+ H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
+ H1_TUNNEL_ESTABLISHED,
+ H1_TUNNEL_FAILED
+} h1_tunnel_state;
/* struct for HTTP CONNECT tunneling */
-struct tunnel_state {
+struct h1_tunnel_state {
int sockindex;
const char *hostname;
int remote_port;
@@ -78,23 +78,23 @@ struct tunnel_state {
KEEPON_IGNORE
} keepon;
curl_off_t cl; /* size of content to read and ignore */
- tunnel_state tunnel_state;
+ h1_tunnel_state tunnel_state;
BIT(chunked_encoding);
BIT(close_connection);
};
-static bool tunnel_is_established(struct tunnel_state *ts)
+static bool tunnel_is_established(struct h1_tunnel_state *ts)
{
- return ts && (ts->tunnel_state == TUNNEL_ESTABLISHED);
+ return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED);
}
-static bool tunnel_is_failed(struct tunnel_state *ts)
+static bool tunnel_is_failed(struct h1_tunnel_state *ts)
{
- return ts && (ts->tunnel_state == TUNNEL_FAILED);
+ return ts && (ts->tunnel_state == H1_TUNNEL_FAILED);
}
-static CURLcode tunnel_reinit(struct tunnel_state *ts,
+static CURLcode tunnel_reinit(struct h1_tunnel_state *ts,
struct connectdata *conn,
struct Curl_easy *data)
{
@@ -102,7 +102,7 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts,
DEBUGASSERT(ts);
Curl_dyn_reset(&ts->rcvbuf);
Curl_dyn_reset(&ts->req);
- ts->tunnel_state = TUNNEL_INIT;
+ ts->tunnel_state = H1_TUNNEL_INIT;
ts->keepon = KEEPON_CONNECT;
ts->cl = 0;
ts->close_connection = FALSE;
@@ -124,12 +124,12 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts,
return CURLE_OK;
}
-static CURLcode tunnel_init(struct tunnel_state **pts,
+static CURLcode tunnel_init(struct h1_tunnel_state **pts,
struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
- struct tunnel_state *ts;
+ struct h1_tunnel_state *ts;
CURLcode result;
if(conn->handler->flags & PROTOPT_NOTCPPROXY) {
@@ -157,16 +157,16 @@ static CURLcode tunnel_init(struct tunnel_state **pts,
return tunnel_reinit(ts, conn, data);
}
-static void tunnel_go_state(struct Curl_cfilter *cf,
- struct tunnel_state *ts,
- tunnel_state new_state,
- struct Curl_easy *data)
+static void h1_tunnel_go_state(struct Curl_cfilter *cf,
+ struct h1_tunnel_state *ts,
+ h1_tunnel_state new_state,
+ struct Curl_easy *data)
{
if(ts->tunnel_state == new_state)
return;
/* leaving this one */
switch(ts->tunnel_state) {
- case TUNNEL_CONNECT:
+ case H1_TUNNEL_CONNECT:
data->req.ignorebody = FALSE;
break;
default:
@@ -174,36 +174,36 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
}
/* entering this one */
switch(new_state) {
- case TUNNEL_INIT:
+ case H1_TUNNEL_INIT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
tunnel_reinit(ts, cf->conn, data);
break;
- case TUNNEL_CONNECT:
+ case H1_TUNNEL_CONNECT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
- ts->tunnel_state = TUNNEL_CONNECT;
+ ts->tunnel_state = H1_TUNNEL_CONNECT;
ts->keepon = KEEPON_CONNECT;
Curl_dyn_reset(&ts->rcvbuf);
break;
- case TUNNEL_RECEIVE:
+ case H1_TUNNEL_RECEIVE:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'receive'"));
- ts->tunnel_state = TUNNEL_RECEIVE;
+ ts->tunnel_state = H1_TUNNEL_RECEIVE;
break;
- case TUNNEL_RESPONSE:
+ case H1_TUNNEL_RESPONSE:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
- ts->tunnel_state = TUNNEL_RESPONSE;
+ ts->tunnel_state = H1_TUNNEL_RESPONSE;
break;
- case TUNNEL_ESTABLISHED:
+ case H1_TUNNEL_ESTABLISHED:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
infof(data, "CONNECT phase completed");
data->state.authproxy.done = TRUE;
data->state.authproxy.multipass = FALSE;
/* FALLTHROUGH */
- case TUNNEL_FAILED:
- if(new_state == TUNNEL_FAILED)
+ case H1_TUNNEL_FAILED:
+ if(new_state == H1_TUNNEL_FAILED)
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
ts->tunnel_state = new_state;
Curl_dyn_reset(&ts->rcvbuf);
@@ -225,9 +225,9 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
static void tunnel_free(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
- struct tunnel_state *ts = cf->ctx;
+ struct h1_tunnel_state *ts = cf->ctx;
if(ts) {
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
Curl_dyn_free(&ts->rcvbuf);
Curl_dyn_free(&ts->req);
free(ts);
@@ -270,7 +270,7 @@ static CURLcode CONNECT_host(struct Curl_easy *data,
#ifndef USE_HYPER
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts)
+ struct h1_tunnel_state *ts)
{
struct connectdata *conn = cf->conn;
char *hostheader = NULL;
@@ -351,7 +351,7 @@ out:
static CURLcode send_CONNECT(struct Curl_easy *data,
struct connectdata *conn,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
struct SingleRequest *k = &data->req;
@@ -399,7 +399,7 @@ out:
static CURLcode on_resp_header(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
const char *header)
{
CURLcode result = CURLE_OK;
@@ -475,7 +475,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
CURLcode result = CURLE_OK;
@@ -671,7 +671,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
/* The Hyper version of CONNECT */
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts)
+ struct h1_tunnel_state *ts)
{
struct connectdata *conn = cf->conn;
struct hyptransfer *h = &data->hyp;
@@ -882,7 +882,7 @@ error:
static CURLcode send_CONNECT(struct Curl_easy *data,
struct connectdata *conn,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
struct hyptransfer *h = &data->hyp;
@@ -919,7 +919,7 @@ error:
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct tunnel_state *ts,
+ struct h1_tunnel_state *ts,
bool *done)
{
struct hyptransfer *h = &data->hyp;
@@ -949,9 +949,9 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
#endif /* USE_HYPER */
-static CURLcode CONNECT(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct tunnel_state *ts)
+static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts)
{
struct connectdata *conn = cf->conn;
CURLcode result;
@@ -973,25 +973,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
}
switch(ts->tunnel_state) {
- case TUNNEL_INIT:
+ case H1_TUNNEL_INIT:
/* Prepare the CONNECT request and make a first attempt to send. */
DEBUGF(LOG_CF(data, cf, "CONNECT start"));
result = start_CONNECT(cf, data, ts);
if(result)
goto out;
- tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_CONNECT, data);
/* FALLTHROUGH */
- case TUNNEL_CONNECT:
+ case H1_TUNNEL_CONNECT:
/* see that the request is completely sent */
DEBUGF(LOG_CF(data, cf, "CONNECT send"));
result = send_CONNECT(data, cf->conn, ts, &done);
if(result || !done)
goto out;
- tunnel_go_state(cf, ts, TUNNEL_RECEIVE, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_RECEIVE, data);
/* FALLTHROUGH */
- case TUNNEL_RECEIVE:
+ case H1_TUNNEL_RECEIVE:
/* read what is there */
DEBUGF(LOG_CF(data, cf, "CONNECT receive"));
result = recv_CONNECT_resp(cf, data, ts, &done);
@@ -1003,10 +1003,10 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
if(result || !done)
goto out;
/* got it */
- tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_RESPONSE, data);
/* FALLTHROUGH */
- case TUNNEL_RESPONSE:
+ case H1_TUNNEL_RESPONSE:
DEBUGF(LOG_CF(data, cf, "CONNECT response"));
if(data->req.newurl) {
/* not the "final" response, we need to do a follow up request.
@@ -1028,7 +1028,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
}
else {
/* staying on this connection, reset state */
- tunnel_go_state(cf, ts, TUNNEL_INIT, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_INIT, data);
}
}
break;
@@ -1039,25 +1039,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
} while(data->req.newurl);
- DEBUGASSERT(ts->tunnel_state == TUNNEL_RESPONSE);
+ DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE);
if(data->info.httpproxycode/100 != 2) {
/* a non-2xx response and we have no next url to try. */
Curl_safefree(data->req.newurl);
/* failure, close this connection to avoid re-use */
streamclose(conn, "proxy CONNECT failure");
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
return CURLE_RECV_ERROR;
}
/* 2xx response, SUCCESS! */
- tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data);
infof(data, "CONNECT tunnel established, response %d",
data->info.httpproxycode);
result = CURLE_OK;
out:
if(result)
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
return result;
}
@@ -1066,7 +1066,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
bool blocking, bool *done)
{
CURLcode result;
- struct tunnel_state *ts = cf->ctx;
+ struct h1_tunnel_state *ts = cf->ctx;
if(cf->connected) {
*done = TRUE;
@@ -1089,7 +1089,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
/* TODO: can we do blocking? */
/* We want "seamless" operations through HTTP proxy tunnel */
- result = CONNECT(cf, data, ts);
+ result = H1_CONNECT(cf, data, ts);
if(result)
goto out;
Curl_safefree(data->state.aptr.proxyuserpwd);
@@ -1107,7 +1107,7 @@ static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
{
- struct tunnel_state *ts = cf->ctx;
+ struct h1_tunnel_state *ts = cf->ctx;
int fds;
fds = cf->next->cft->get_select_socks(cf->next, data, socks);
@@ -1143,7 +1143,7 @@ static void cf_h1_proxy_close(struct Curl_cfilter *cf,
DEBUGF(LOG_CF(data, cf, "close"));
cf->connected = FALSE;
if(cf->ctx) {
- tunnel_go_state(cf, cf->ctx, TUNNEL_INIT, data);
+ h1_tunnel_go_state(cf, cf->ctx, H1_TUNNEL_INIT, data);
}
if(cf->next)
cf->next->cft->close(cf->next, data);
diff --git a/libs/libcurl/src/cf-h2-proxy.c b/libs/libcurl/src/cf-h2-proxy.c
index b504504e89..5248660fc8 100644
--- a/libs/libcurl/src/cf-h2-proxy.c
+++ b/libs/libcurl/src/cf-h2-proxy.c
@@ -44,26 +44,25 @@
#include "curl_memory.h"
#include "memdebug.h"
-#define H2_NW_CHUNK_SIZE (128*1024)
-#define H2_NW_RECV_CHUNKS 1
-#define H2_NW_SEND_CHUNKS 1
+#define H2_CHUNK_SIZE (16*1024)
-#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
+#define PROXY_HTTP2_HUGE_WINDOW_SIZE (100 * 1024 * 1024)
+#define H2_TUNNEL_WINDOW_SIZE (10 * 1024 * 1024)
+
+#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / H2_CHUNK_SIZE)
+#define PROXY_H2_NW_SEND_CHUNKS 1
+
+#define H2_TUNNEL_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / H2_CHUNK_SIZE)
+#define H2_TUNNEL_SEND_CHUNKS ((128 * 1024) / H2_CHUNK_SIZE)
-#define H2_TUNNEL_WINDOW_SIZE (1024 * 1024)
-#define H2_TUNNEL_CHUNK_SIZE (32 * 1024)
-#define H2_TUNNEL_RECV_CHUNKS \
- (H2_TUNNEL_WINDOW_SIZE / H2_TUNNEL_CHUNK_SIZE)
-#define H2_TUNNEL_SEND_CHUNKS \
- (H2_TUNNEL_WINDOW_SIZE / H2_TUNNEL_CHUNK_SIZE)
typedef enum {
- TUNNEL_INIT, /* init/default/no tunnel state */
- TUNNEL_CONNECT, /* CONNECT request is being send */
- TUNNEL_RESPONSE, /* CONNECT response received completely */
- TUNNEL_ESTABLISHED,
- TUNNEL_FAILED
-} tunnel_state;
+ H2_TUNNEL_INIT, /* init/default/no tunnel state */
+ H2_TUNNEL_CONNECT, /* CONNECT request is being send */
+ H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
+ H2_TUNNEL_ESTABLISHED,
+ H2_TUNNEL_FAILED
+} h2_tunnel_state;
struct tunnel_stream {
struct http_resp *resp;
@@ -72,10 +71,11 @@ struct tunnel_stream {
char *authority;
int32_t stream_id;
uint32_t error;
- tunnel_state state;
- bool has_final_response;
- bool closed;
- bool reset;
+ size_t upload_blocked_len;
+ h2_tunnel_state state;
+ BIT(has_final_response);
+ BIT(closed);
+ BIT(reset);
};
static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
@@ -85,11 +85,11 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
int port;
bool ipv6_ip = cf->conn->bits.ipv6_ip;
- ts->state = TUNNEL_INIT;
+ ts->state = H2_TUNNEL_INIT;
ts->stream_id = -1;
- Curl_bufq_init2(&ts->recvbuf, H2_TUNNEL_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
+ Curl_bufq_init2(&ts->recvbuf, H2_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
BUFQ_OPT_SOFT_LIMIT);
- Curl_bufq_init(&ts->sendbuf, H2_TUNNEL_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
+ Curl_bufq_init(&ts->sendbuf, H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
if(cf->conn->bits.conn_to_host)
hostname = cf->conn->conn_to_host.name;
@@ -123,13 +123,13 @@ static void tunnel_stream_clear(struct tunnel_stream *ts)
Curl_bufq_free(&ts->sendbuf);
Curl_safefree(ts->authority);
memset(ts, 0, sizeof(*ts));
- ts->state = TUNNEL_INIT;
+ ts->state = H2_TUNNEL_INIT;
}
-static void tunnel_go_state(struct Curl_cfilter *cf,
- struct tunnel_stream *ts,
- tunnel_state new_state,
- struct Curl_easy *data)
+static void h2_tunnel_go_state(struct Curl_cfilter *cf,
+ struct tunnel_stream *ts,
+ h2_tunnel_state new_state,
+ struct Curl_easy *data)
{
(void)cf;
@@ -137,7 +137,7 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
return;
/* leaving this one */
switch(ts->state) {
- case TUNNEL_CONNECT:
+ case H2_TUNNEL_CONNECT:
data->req.ignorebody = FALSE;
break;
default:
@@ -145,29 +145,29 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
}
/* entering this one */
switch(new_state) {
- case TUNNEL_INIT:
+ case H2_TUNNEL_INIT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
tunnel_stream_clear(ts);
break;
- case TUNNEL_CONNECT:
+ case H2_TUNNEL_CONNECT:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
- ts->state = TUNNEL_CONNECT;
+ ts->state = H2_TUNNEL_CONNECT;
break;
- case TUNNEL_RESPONSE:
+ case H2_TUNNEL_RESPONSE:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
- ts->state = TUNNEL_RESPONSE;
+ ts->state = H2_TUNNEL_RESPONSE;
break;
- case TUNNEL_ESTABLISHED:
+ case H2_TUNNEL_ESTABLISHED:
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
infof(data, "CONNECT phase completed");
data->state.authproxy.done = TRUE;
data->state.authproxy.multipass = FALSE;
/* FALLTHROUGH */
- case TUNNEL_FAILED:
- if(new_state == TUNNEL_FAILED)
+ case H2_TUNNEL_FAILED:
+ if(new_state == H2_TUNNEL_FAILED)
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
ts->state = new_state;
/* If a proxy-authorization header was used for the proxy, then we should
@@ -191,9 +191,11 @@ struct cf_h2_proxy_ctx {
int32_t last_stream_id;
BIT(conn_closed);
BIT(goaway);
+ BIT(nw_out_blocked);
};
/* How to access `call_data` from a cf_h2 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
@@ -219,35 +221,54 @@ static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx)
}
}
-static ssize_t nw_in_reader(void *reader_ctx,
- unsigned char *buf, size_t buflen,
- CURLcode *err)
+static void drain_tunnel(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *tunnel)
+{
+ unsigned char bits;
+
+ (void)cf;
+ bits = CURL_CSELECT_IN;
+ if(!tunnel->closed && !tunnel->reset && tunnel->upload_blocked_len)
+ bits |= CURL_CSELECT_OUT;
+ if(data->state.dselect_bits != bits) {
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] DRAIN dselect_bits=%x",
+ tunnel->stream_id, bits));
+ data->state.dselect_bits = bits;
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ }
+}
+
+static ssize_t proxy_nw_in_reader(void *reader_ctx,
+ unsigned char *buf, size_t buflen,
+ CURLcode *err)
{
struct Curl_cfilter *cf = reader_ctx;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
nread = Curl_conn_cf_recv(cf->next, data, (char *)buf, buflen, err);
- DEBUGF(LOG_CF(data, cf, "nw_in recv(len=%zu) -> %zd, %d",
+ DEBUGF(LOG_CF(data, cf, "nw_in_reader(len=%zu) -> %zd, %d",
buflen, nread, *err));
return nread;
}
-static ssize_t nw_out_writer(void *writer_ctx,
- const unsigned char *buf, size_t buflen,
- CURLcode *err)
+static ssize_t proxy_h2_nw_out_writer(void *writer_ctx,
+ const unsigned char *buf, size_t buflen,
+ CURLcode *err)
{
struct Curl_cfilter *cf = writer_ctx;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, err);
- DEBUGF(LOG_CF(data, cf, "nw_out send(len=%zu) -> %zd", buflen, nwritten));
+ DEBUGF(LOG_CF(data, cf, "nw_out_writer(len=%zu) -> %zd, %d",
+ buflen, nwritten, *err));
return nwritten;
}
-static int h2_client_new(struct Curl_cfilter *cf,
- nghttp2_session_callbacks *cbs)
+static int proxy_h2_client_new(struct Curl_cfilter *cf,
+ nghttp2_session_callbacks *cbs)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
nghttp2_option *o;
@@ -271,15 +292,18 @@ static int h2_client_new(struct Curl_cfilter *cf,
static ssize_t on_session_send(nghttp2_session *h2,
const uint8_t *buf, size_t blen,
int flags, void *userp);
-static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
- void *userp);
-static int on_stream_close(nghttp2_session *session, int32_t stream_id,
- uint32_t error_code, void *userp);
-static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
- const uint8_t *name, size_t namelen,
- const uint8_t *value, size_t valuelen,
- uint8_t flags,
- void *userp);
+static int proxy_h2_on_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp);
+static int proxy_h2_on_stream_close(nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code, void *userp);
+static int proxy_h2_on_header(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp);
static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const uint8_t *mem, size_t len, void *userp);
@@ -298,8 +322,8 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
DEBUGASSERT(!ctx->h2);
memset(&ctx->tunnel, 0, sizeof(ctx->tunnel));
- Curl_bufq_init(&ctx->inbufq, H2_NW_CHUNK_SIZE, H2_NW_RECV_CHUNKS);
- Curl_bufq_init(&ctx->outbufq, H2_NW_CHUNK_SIZE, H2_NW_SEND_CHUNKS);
+ Curl_bufq_init(&ctx->inbufq, H2_CHUNK_SIZE, PROXY_H2_NW_RECV_CHUNKS);
+ Curl_bufq_init(&ctx->outbufq, H2_CHUNK_SIZE, PROXY_H2_NW_SEND_CHUNKS);
if(tunnel_stream_init(cf, &ctx->tunnel))
goto out;
@@ -311,14 +335,16 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
}
nghttp2_session_callbacks_set_send_callback(cbs, on_session_send);
- nghttp2_session_callbacks_set_on_frame_recv_callback(cbs, on_frame_recv);
+ nghttp2_session_callbacks_set_on_frame_recv_callback(
+ cbs, proxy_h2_on_frame_recv);
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
cbs, tunnel_recv_callback);
- nghttp2_session_callbacks_set_on_stream_close_callback(cbs, on_stream_close);
- nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
+ nghttp2_session_callbacks_set_on_stream_close_callback(
+ cbs, proxy_h2_on_stream_close);
+ nghttp2_session_callbacks_set_on_header_callback(cbs, proxy_h2_on_header);
/* The nghttp2 session is not yet setup, do it */
- rc = h2_client_new(cf, cbs);
+ rc = proxy_h2_client_new(cf, cbs);
if(rc) {
failf(data, "Couldn't initialize nghttp2");
goto out;
@@ -343,7 +369,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
}
rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0,
- HTTP2_HUGE_WINDOW_SIZE);
+ PROXY_HTTP2_HUGE_WINDOW_SIZE);
if(rc) {
failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
nghttp2_strerror(rc), rc);
@@ -362,27 +388,35 @@ out:
return result;
}
-static CURLcode nw_out_flush(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static int should_close_session(struct cf_h2_proxy_ctx *ctx)
+{
+ return !nghttp2_session_want_read(ctx->h2) &&
+ !nghttp2_session_want_write(ctx->h2);
+}
+
+static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
- size_t buflen = Curl_bufq_len(&ctx->outbufq);
ssize_t nwritten;
CURLcode result;
(void)data;
- if(!buflen)
+ if(Curl_bufq_is_empty(&ctx->outbufq))
return CURLE_OK;
- DEBUGF(LOG_CF(data, cf, "h2 conn flush %zu bytes", buflen));
- nwritten = Curl_bufq_pass(&ctx->outbufq, nw_out_writer, cf, &result);
+ nwritten = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf,
+ &result);
if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ DEBUGF(LOG_CF(data, cf, "flush nw send buffer(%zu) -> EAGAIN",
+ Curl_bufq_len(&ctx->outbufq)));
+ ctx->nw_out_blocked = 1;
+ }
return result;
}
- if((size_t)nwritten < buflen) {
- return CURLE_AGAIN;
- }
- return CURLE_OK;
+ DEBUGF(LOG_CF(data, cf, "nw send buffer flushed"));
+ return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
}
/*
@@ -390,9 +424,9 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
* This function returns 0 if it succeeds, or -1 and error code will
* be assigned to *err.
*/
-static int h2_process_pending_input(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- CURLcode *err)
+static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ CURLcode *err)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
const unsigned char *buf;
@@ -422,19 +456,11 @@ static int h2_process_pending_input(struct Curl_cfilter *cf,
}
}
- if(nghttp2_session_check_request_allowed(ctx->h2) == 0) {
- /* No more requests are allowed in the current session, so
- the connection may not be reused. This is set when a
- GOAWAY frame has been received or when the limit of stream
- identifiers has been reached. */
- connclose(cf->conn, "http/2: No new requests allowed");
- }
-
return 0;
}
-static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
CURLcode result = CURLE_OK;
@@ -442,9 +468,9 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
/* Process network input buffer fist */
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
- DEBUGF(LOG_CF(data, cf, "Process %zd bytes in connection buffer",
+ DEBUGF(LOG_CF(data, cf, "Process %zu bytes in connection buffer",
Curl_bufq_len(&ctx->inbufq)));
- if(h2_process_pending_input(cf, data, &result) < 0)
+ if(proxy_h2_process_pending_input(cf, data, &result) < 0)
return result;
}
@@ -455,8 +481,8 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
!Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
- nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
- DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
+ nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
+ DEBUGF(LOG_CF(data, cf, "read %zu bytes nw data -> %zd, %d",
Curl_bufq_len(&ctx->inbufq), nread, result));
if(nread < 0) {
if(result != CURLE_AGAIN) {
@@ -470,7 +496,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
break;
}
- if(h2_process_pending_input(cf, data, &result))
+ if(proxy_h2_process_pending_input(cf, data, &result))
return result;
}
@@ -481,25 +507,22 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
return CURLE_OK;
}
-/*
- * Check if there's been an update in the priority /
- * dependency settings and if so it submits a PRIORITY frame with the updated
- * info.
- * Flush any out data pending in the network buffer.
- */
-static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode proxy_h2_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
int rv = 0;
- rv = nghttp2_session_send(ctx->h2);
+ ctx->nw_out_blocked = 0;
+ while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2))
+ rv = nghttp2_session_send(ctx->h2);
+
if(nghttp2_is_fatal(rv)) {
DEBUGF(LOG_CF(data, cf, "nghttp2_session_send error (%s)%d",
nghttp2_strerror(rv), rv));
return CURLE_SEND_ERROR;
}
- return nw_out_flush(cf, data);
+ return proxy_h2_nw_out_flush(cf, data);
}
static ssize_t on_session_send(nghttp2_session *h2,
@@ -517,7 +540,7 @@ static ssize_t on_session_send(nghttp2_session *h2,
DEBUGASSERT(data);
nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
- nw_out_writer, cf, &result);
+ proxy_h2_nw_out_writer, cf, &result);
if(nwritten < 0) {
if(result == CURLE_AGAIN) {
return NGHTTP2_ERR_WOULDBLOCK;
@@ -532,8 +555,9 @@ static ssize_t on_session_send(nghttp2_session *h2,
return nwritten;
}
-static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
- void *userp)
+static int proxy_h2_on_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp)
{
struct Curl_cfilter *cf = userp;
struct cf_h2_proxy_ctx *ctx = cf->ctx;
@@ -616,11 +640,12 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
return 0;
}
-static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
- const uint8_t *name, size_t namelen,
- const uint8_t *value, size_t valuelen,
- uint8_t flags,
- void *userp)
+static int proxy_h2_on_header(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp)
{
struct Curl_cfilter *cf = userp;
struct cf_h2_proxy_ctx *ctx = cf->ctx;
@@ -752,8 +777,9 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
return 0;
}
-static int on_stream_close(nghttp2_session *session, int32_t stream_id,
- uint32_t error_code, void *userp)
+static int proxy_h2_on_stream_close(nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code, void *userp)
{
struct Curl_cfilter *cf = userp;
struct cf_h2_proxy_ctx *ctx = cf->ctx;
@@ -765,7 +791,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
if(stream_id != ctx->tunnel.stream_id)
return 0;
- DEBUGF(LOG_CF(data, cf, "[h2sid=%u] on_stream_close, %s (err %d)",
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%u] proxy_h2_on_stream_close, %s (err %d)",
stream_id, nghttp2_http2_strerror(error_code), error_code));
ctx->tunnel.closed = TRUE;
ctx->tunnel.error = error_code;
@@ -773,15 +799,15 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return 0;
}
-static CURLcode h2_submit(int32_t *pstream_id,
- struct Curl_cfilter *cf,
- struct Curl_easy *data,
- nghttp2_session *h2,
- struct httpreq *req,
- const nghttp2_priority_spec *pri_spec,
- void *stream_user_data,
- nghttp2_data_source_read_callback read_callback,
- void *read_ctx)
+static CURLcode proxy_h2_submit(int32_t *pstream_id,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ nghttp2_session *h2,
+ struct httpreq *req,
+ const nghttp2_priority_spec *pri_spec,
+ void *stream_user_data,
+ nghttp2_data_source_read_callback read_callback,
+ void *read_ctx)
{
struct dynhds h2_headers;
nghttp2_nv *nva = NULL;
@@ -881,8 +907,8 @@ static CURLcode submit_CONNECT(struct Curl_cfilter *cf,
if(result)
goto out;
- result = h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
- NULL, ts, tunnel_send_callback, cf);
+ result = proxy_h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
+ NULL, ts, tunnel_send_callback, cf);
if(result) {
DEBUGF(LOG_CF(data, cf, "send: nghttp2_submit_request error (%s)%u",
nghttp2_strerror(ts->stream_id), ts->stream_id));
@@ -907,7 +933,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
DEBUGASSERT(ts->resp);
if(ts->resp->status/100 == 2) {
infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
- tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data);
return CURLE_OK;
}
@@ -928,7 +954,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
if(data->req.newurl) {
/* Inidicator that we should try again */
Curl_safefree(data->req.newurl);
- tunnel_go_state(cf, ts, TUNNEL_INIT, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_INIT, data);
return CURLE_OK;
}
}
@@ -937,9 +963,9 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
return CURLE_RECV_ERROR;
}
-static CURLcode CONNECT(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- struct tunnel_stream *ts)
+static CURLcode H2_CONNECT(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct tunnel_stream *ts)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
CURLcode result = CURLE_OK;
@@ -948,27 +974,27 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
DEBUGASSERT(ts->authority);
do {
switch(ts->state) {
- case TUNNEL_INIT:
+ case H2_TUNNEL_INIT:
/* Prepare the CONNECT request and make a first attempt to send. */
DEBUGF(LOG_CF(data, cf, "CONNECT start for %s", ts->authority));
result = submit_CONNECT(cf, data, ts);
if(result)
goto out;
- tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_CONNECT, data);
/* FALLTHROUGH */
- case TUNNEL_CONNECT:
+ case H2_TUNNEL_CONNECT:
/* see that the request is completely sent */
- result = h2_progress_ingress(cf, data);
+ result = proxy_h2_progress_ingress(cf, data);
if(!result)
- result = h2_progress_egress(cf, data);
- if(result) {
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ result = proxy_h2_progress_egress(cf, data);
+ if(result && result != CURLE_AGAIN) {
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
break;
}
if(ts->has_final_response) {
- tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_RESPONSE, data);
}
else {
result = CURLE_OK;
@@ -976,28 +1002,28 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
}
/* FALLTHROUGH */
- case TUNNEL_RESPONSE:
+ case H2_TUNNEL_RESPONSE:
DEBUGASSERT(ts->has_final_response);
result = inspect_response(cf, data, ts);
if(result)
goto out;
break;
- case TUNNEL_ESTABLISHED:
+ case H2_TUNNEL_ESTABLISHED:
return CURLE_OK;
- case TUNNEL_FAILED:
+ case H2_TUNNEL_FAILED:
return CURLE_RECV_ERROR;
default:
break;
}
- } while(ts->state == TUNNEL_INIT);
+ } while(ts->state == H2_TUNNEL_INIT);
out:
if(result || ctx->tunnel.closed)
- tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
+ h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
return result;
}
@@ -1043,10 +1069,10 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
- result = CONNECT(cf, data, ts);
+ result = H2_CONNECT(cf, data, ts);
out:
- *done = (result == CURLE_OK) && (ts->state == TUNNEL_ESTABLISHED);
+ *done = (result == CURLE_OK) && (ts->state == H2_TUNNEL_ESTABLISHED);
cf->connected = *done;
CF_DATA_RESTORE(cf, save);
return result;
@@ -1082,7 +1108,7 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) ||
- (ctx && ctx->tunnel.state == TUNNEL_ESTABLISHED &&
+ (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED &&
!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
return TRUE;
return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
@@ -1188,14 +1214,14 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
struct cf_call_data save;
CURLcode result;
- if(ctx->tunnel.state != TUNNEL_ESTABLISHED) {
+ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
*err = CURLE_RECV_ERROR;
return -1;
}
CF_DATA_SAVE(save, cf, data);
if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) {
- *err = h2_progress_ingress(cf, data);
+ *err = proxy_h2_progress_ingress(cf, data);
if(*err)
goto out;
}
@@ -1208,13 +1234,19 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, (size_t)nread);
}
- result = h2_progress_egress(cf, data);
- if(result) {
+ result = proxy_h2_progress_egress(cf, data);
+ if(result && result != CURLE_AGAIN) {
*err = result;
nread = -1;
}
out:
+ if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) &&
+ (nread >= 0 || *err == CURLE_AGAIN)) {
+ /* data pending and no fatal error to report. Need to trigger
+ * draining to avoid stalling when no socket events happen. */
+ drain_tunnel(cf, data, &ctx->tunnel);
+ }
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] cf_recv(len=%zu) -> %zd %d",
ctx->tunnel.stream_id, len, nread, *err));
CF_DATA_RESTORE(cf, save);
@@ -1223,93 +1255,188 @@ out:
static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
- const void *mem, size_t len, CURLcode *err)
+ const void *buf, size_t len, CURLcode *err)
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
struct cf_call_data save;
- ssize_t nwritten = -1;
- const unsigned char *buf = mem;
- size_t start_len = len;
int rv;
+ ssize_t nwritten;
+ CURLcode result;
+ int blocked = 0;
- if(ctx->tunnel.state != TUNNEL_ESTABLISHED) {
+ if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
*err = CURLE_SEND_ERROR;
return -1;
}
CF_DATA_SAVE(save, cf, data);
- while(len) {
+ if(ctx->tunnel.closed) {
+ nwritten = -1;
+ *err = CURLE_SEND_ERROR;
+ goto out;
+ }
+ else if(ctx->tunnel.upload_blocked_len) {
+ /* the data in `buf` has alread been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= ctx->tunnel.upload_blocked_len);
+ if(len < ctx->tunnel.upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happend. We are not prepared to handle that. */
+ failf(data, "HTTP/2 proxy, send again with decreased length");
+ *err = CURLE_HTTP2;
+ nwritten = -1;
+ goto out;
+ }
+ nwritten = (ssize_t)ctx->tunnel.upload_blocked_len;
+ ctx->tunnel.upload_blocked_len = 0;
+ }
+ else {
nwritten = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, err);
- if(nwritten <= 0) {
- if(*err && *err != CURLE_AGAIN) {
- DEBUGF(LOG_CF(data, cf, "error adding data to tunnel sendbuf: %d",
- *err));
- nwritten = -1;
+ if(nwritten < 0) {
+ if(*err != CURLE_AGAIN)
goto out;
- }
- /* blocked */
nwritten = 0;
}
- else {
- DEBUGASSERT((size_t)nwritten <= len);
- buf += (size_t)nwritten;
- len -= (size_t)nwritten;
- }
+ }
- /* resume the tunnel stream and let the h2 session send, which
- * triggers reading from tunnel.sendbuf */
+ if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
+ /* req body data is buffered, resume the potentially suspended stream */
rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id);
if(nghttp2_is_fatal(rv)) {
*err = CURLE_SEND_ERROR;
nwritten = -1;
goto out;
}
- *err = h2_progress_egress(cf, data);
- if(*err) {
- nwritten = -1;
- goto out;
- }
-
- if(!nwritten && Curl_bufq_is_full(&ctx->tunnel.sendbuf)) {
- size_t rwin;
- /* we could not add to the buffer and after session processing,
- * it is still full. */
- rwin = nghttp2_session_get_stream_remote_window_size(
- ctx->h2, ctx->tunnel.stream_id);
- DEBUGF(LOG_CF(data, cf, "cf_send: tunnel win %u/%zu",
- nghttp2_session_get_remote_window_size(ctx->h2), rwin));
- if(rwin == 0) {
- /* We cannot upload more as the stream's remote window size
- * is 0. We need to receive WIN_UPDATEs before we can continue.
- */
- data->req.keepon |= KEEP_SEND_HOLD;
- DEBUGF(LOG_CF(data, cf, "pausing send as remote flow "
- "window is exhausted"));
- }
- break;
- }
}
- nwritten = start_len - len;
- if(nwritten > 0) {
- *err = CURLE_OK;
+ /* Call the nghttp2 send loop and flush to write ALL buffered data,
+ * headers and/or request body completely out to the network */
+ result = proxy_h2_progress_egress(cf, data);
+ if(result == CURLE_AGAIN) {
+ blocked = 1;
}
- else if(ctx->tunnel.closed) {
+ else if(result) {
+ *err = result;
nwritten = -1;
- *err = CURLE_SEND_ERROR;
+ goto out;
}
- else {
- nwritten = -1;
+ else if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) {
+ /* although we wrote everything that nghttp2 wants to send now,
+ * there is data left in our stream send buffer unwritten. This may
+ * be due to the stream's HTTP/2 flow window being exhausted. */
+ blocked = 1;
+ }
+
+ if(blocked) {
+ /* Unable to send all data, due to connection blocked or H2 window
+ * exhaustion. Data is left in our stream buffer, or nghttp2's internal
+ * frame buffer or our network out buffer. */
+ size_t rwin = nghttp2_session_get_stream_remote_window_size(
+ ctx->h2, ctx->tunnel.stream_id);
+ if(rwin == 0) {
+ /* H2 flow window exhaustion.
+ * FIXME: there is no way to HOLD all transfers that use this
+ * proxy connection AND to UNHOLD all of them again when the
+ * window increases.
+ * We *could* iterate over all data on this conn maybe? */
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] remote flow "
+ "window is exhausted", ctx->tunnel.stream_id));
+ }
+
+ /* Whatever the cause, we need to return CURL_EAGAIN for this call.
+ * We have unwritten state that needs us being invoked again and EAGAIN
+ * is the only way to ensure that. */
+ ctx->tunnel.upload_blocked_len = nwritten;
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) BLOCK: win %u/%zu "
+ "blocked_len=%zu",
+ ctx->tunnel.stream_id, len,
+ nghttp2_session_get_remote_window_size(ctx->h2), rwin,
+ nwritten));
*err = CURLE_AGAIN;
+ nwritten = -1;
+ goto out;
+ }
+ else if(should_close_session(ctx)) {
+ /* nghttp2 thinks this session is done. If the stream has not been
+ * closed, this is an error state for out transfer */
+ if(ctx->tunnel.closed) {
+ *err = CURLE_SEND_ERROR;
+ nwritten = -1;
+ }
+ else {
+ DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
+ *err = CURLE_HTTP2;
+ nwritten = -1;
+ }
}
out:
- DEBUGF(LOG_CF(data, cf, "cf_send(len=%zu) -> %zd, %d ",
- start_len, nwritten, *err));
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) -> %zd, %d, "
+ "h2 windows %d-%d (stream-conn), "
+ "buffers %zu-%zu (stream-conn)",
+ ctx->tunnel.stream_id, len, nwritten, *err,
+ nghttp2_session_get_stream_remote_window_size(
+ ctx->h2, ctx->tunnel.stream_id),
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&ctx->tunnel.sendbuf),
+ Curl_bufq_len(&ctx->outbufq)));
CF_DATA_RESTORE(cf, save);
return nwritten;
}
+static bool proxy_h2_connisalive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ bool alive = TRUE;
+
+ *input_pending = FALSE;
+ if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending))
+ return FALSE;
+
+ if(*input_pending) {
+ /* This happens before we've sent off a request and the connection is
+ not in use by any other transfer, there shouldn't be any data here,
+ only "protocol frames" */
+ CURLcode result;
+ ssize_t nread = -1;
+
+ *input_pending = FALSE;
+ nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
+ if(nread != -1) {
+ if(proxy_h2_process_pending_input(cf, data, &result) < 0)
+ /* immediate error, considered dead */
+ alive = FALSE;
+ else {
+ alive = !should_close_session(ctx);
+ }
+ }
+ else if(result != CURLE_AGAIN) {
+ /* the read failed so let's say this is dead anyway */
+ alive = FALSE;
+ }
+ }
+
+ return alive;
+}
+
+static bool cf_h2_proxy_is_alive(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *input_pending)
+{
+ struct cf_h2_proxy_ctx *ctx = cf->ctx;
+ CURLcode result;
+ struct cf_call_data save;
+
+ CF_DATA_SAVE(save, cf, data);
+ result = (ctx && ctx->h2 && proxy_h2_connisalive(cf, data, input_pending));
+ DEBUGF(LOG_CF(data, cf, "conn alive -> %d, input_pending=%d",
+ result, *input_pending));
+ CF_DATA_RESTORE(cf, save);
+ return result;
+}
+
struct Curl_cftype Curl_cft_h2_proxy = {
"H2-PROXY",
CF_TYPE_IP_CONNECT,
@@ -1323,7 +1450,7 @@ struct Curl_cftype Curl_cft_h2_proxy = {
cf_h2_proxy_send,
cf_h2_proxy_recv,
Curl_cf_def_cntrl,
- Curl_cf_def_conn_is_alive,
+ cf_h2_proxy_is_alive,
Curl_cf_def_conn_keep_alive,
Curl_cf_def_query,
};
diff --git a/libs/libcurl/src/cf-haproxy.c b/libs/libcurl/src/cf-haproxy.c
index 0d58261ada..0848943135 100644
--- a/libs/libcurl/src/cf-haproxy.c
+++ b/libs/libcurl/src/cf-haproxy.c
@@ -71,6 +71,7 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
struct cf_haproxy_ctx *ctx = cf->ctx;
CURLcode result;
const char *tcp_version;
+ const char *client_ip;
DEBUGASSERT(ctx);
DEBUGASSERT(ctx->state == HAPROXY_INIT);
@@ -82,11 +83,15 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
#endif /* USE_UNIX_SOCKETS */
/* Emit the correct prefix for IPv6 */
tcp_version = cf->conn->bits.ipv6 ? "TCP6" : "TCP4";
+ if(data->set.str[STRING_HAPROXY_CLIENT_IP])
+ client_ip = data->set.str[STRING_HAPROXY_CLIENT_IP];
+ else
+ client_ip = data->info.conn_primary_ip;
result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
tcp_version,
data->info.conn_local_ip,
- data->info.conn_primary_ip,
+ client_ip,
data->info.conn_local_port,
data->info.conn_primary_port);
diff --git a/libs/libcurl/src/cf-https-connect.c b/libs/libcurl/src/cf-https-connect.c
index 6cdd0ae3f8..387da5ab5c 100644
--- a/libs/libcurl/src/cf-https-connect.c
+++ b/libs/libcurl/src/cf-https-connect.c
@@ -376,9 +376,9 @@ static bool cf_hc_data_pending(struct Curl_cfilter *cf,
|| cf_hc_baller_data_pending(&ctx->h21_baller, data);
}
-static struct curltime get_max_baller_time(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- int query)
+static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ int query)
{
struct cf_hc_ctx *ctx = cf->ctx;
struct Curl_cfilter *cfb;
@@ -408,12 +408,12 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
switch(query) {
case CF_QUERY_TIMER_CONNECT: {
struct curltime *when = pres2;
- *when = get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
+ *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
return CURLE_OK;
}
case CF_QUERY_TIMER_APPCONNECT: {
struct curltime *when = pres2;
- *when = get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
+ *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
return CURLE_OK;
}
default:
diff --git a/libs/libcurl/src/cf-socket.c b/libs/libcurl/src/cf-socket.c
index 73de784fe1..78b0c48fcb 100644
--- a/libs/libcurl/src/cf-socket.c
+++ b/libs/libcurl/src/cf-socket.c
@@ -871,7 +871,7 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
/* this is our local socket, we did never publish it */
DEBUGF(LOG_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
", not active)", ctx->sock));
- sclose(ctx->sock);
+ socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
ctx->sock = CURL_SOCKET_BAD;
}
Curl_bufq_reset(&ctx->recvbuf);
@@ -901,22 +901,26 @@ static CURLcode set_local_ip(struct Curl_cfilter *cf,
struct cf_socket_ctx *ctx = cf->ctx;
#ifdef HAVE_GETSOCKNAME
- char buffer[STRERROR_LEN];
- struct Curl_sockaddr_storage ssloc;
- curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
+ if(!(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+ /* TFTP does not connect, so it cannot get the IP like this */
- memset(&ssloc, 0, sizeof(ssloc));
- if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
- int error = SOCKERRNO;
- failf(data, "getsockname() failed with errno %d: %s",
- error, Curl_strerror(error, buffer, sizeof(buffer)));
- return CURLE_FAILED_INIT;
- }
- if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
- ctx->l_ip, &ctx->l_port)) {
- failf(data, "ssloc inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- return CURLE_FAILED_INIT;
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssloc;
+ curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
+
+ memset(&ssloc, 0, sizeof(ssloc));
+ if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
+ int error = SOCKERRNO;
+ failf(data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+ ctx->l_ip, &ctx->l_port)) {
+ failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return CURLE_FAILED_INIT;
+ }
}
#else
(void)data;
@@ -1356,26 +1360,31 @@ out:
static void conn_set_primary_ip(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
- struct cf_socket_ctx *ctx = cf->ctx;
#ifdef HAVE_GETPEERNAME
- char buffer[STRERROR_LEN];
- struct Curl_sockaddr_storage ssrem;
- curl_socklen_t plen;
- int port;
+ struct cf_socket_ctx *ctx = cf->ctx;
+ if(!(data->conn->handler->protocol & CURLPROTO_TFTP)) {
+ /* TFTP does not connect the endpoint: getpeername() failed with errno
+ 107: Transport endpoint is not connected */
- plen = sizeof(ssrem);
- memset(&ssrem, 0, plen);
- if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
- int error = SOCKERRNO;
- failf(data, "getpeername() failed with errno %d: %s",
- error, Curl_strerror(error, buffer, sizeof(buffer)));
- return;
- }
- if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
- cf->conn->primary_ip, &port)) {
- failf(data, "ssrem inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- return;
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssrem;
+ curl_socklen_t plen;
+ int port;
+
+ plen = sizeof(ssrem);
+ memset(&ssrem, 0, plen);
+ if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
+ int error = SOCKERRNO;
+ failf(data, "getpeername() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+ cf->conn->primary_ip, &port)) {
+ failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return;
+ }
}
#else
cf->conn->primary_ip[0] = 0;
diff --git a/libs/libcurl/src/cfilters.c b/libs/libcurl/src/cfilters.c
index c6ddd47a4e..a83a5cc590 100644
--- a/libs/libcurl/src/cfilters.c
+++ b/libs/libcurl/src/cfilters.c
@@ -179,7 +179,7 @@ ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
if(cf) {
return cf->cft->do_recv(cf, data, buf, len, code);
}
- failf(data, CMSGI(data->conn, num, "recv: no filter connected"));
+ failf(data, "recv: no filter connected");
*code = CURLE_FAILED_INIT;
return -1;
}
@@ -198,7 +198,7 @@ ssize_t Curl_conn_send(struct Curl_easy *data, int num,
if(cf) {
return cf->cft->do_send(cf, data, mem, len, code);
}
- failf(data, CMSGI(data->conn, num, "send: no filter connected"));
+ failf(data, "send: no filter connected");
DEBUGASSERT(0);
*code = CURLE_FAILED_INIT;
return -1;
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index 5536ebfa7a..e12ab552fd 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.h
@@ -205,10 +205,6 @@
/* Define if you have the socket function. */
#define HAVE_SOCKET 1
-/* Define if libSSH2 is in use */
-#define USE_LIBSSH2 1
-#define HAVE_LIBSSH2_H 1
-
/* Define if you have the strcasecmp function. */
#ifdef __MINGW32__
#define HAVE_STRCASECMP 1
@@ -627,9 +623,6 @@ Vista
# define CURL_DISABLE_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/conncache.h b/libs/libcurl/src/conncache.h
index a9e7dbe9d4..90a2bb917c 100644
--- a/libs/libcurl/src/conncache.h
+++ b/libs/libcurl/src/conncache.h
@@ -39,7 +39,8 @@ struct connectdata;
struct conncache {
struct Curl_hash hash;
size_t num_conn;
- long next_connection_id;
+ curl_off_t next_connection_id;
+ curl_off_t next_easy_id;
struct curltime last_cleanup;
/* handle used for closing cached connections */
struct Curl_easy *closure_handle;
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index 70bb7717e6..9a8e1e3bbb 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -253,7 +253,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
}
struct connfind {
- long id_tofind;
+ curl_off_t id_tofind;
struct connectdata *found;
};
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index 61cd0948a8..e905065930 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.c
@@ -123,8 +123,9 @@ static void freecookie(struct Cookie *co)
free(co);
}
-static bool tailmatch(const char *cookie_domain, size_t cookie_domain_len,
- const char *hostname)
+static bool cookie_tailmatch(const char *cookie_domain,
+ size_t cookie_domain_len,
+ const char *hostname)
{
size_t hostname_len = strlen(hostname);
@@ -696,7 +697,7 @@ Curl_cookie_add(struct Curl_easy *data,
if(!domain
|| (is_ip && !strncmp(valuep, domain, vlen) &&
(vlen == strlen(domain)))
- || (!is_ip && tailmatch(valuep, vlen, domain))) {
+ || (!is_ip && cookie_tailmatch(valuep, vlen, domain))) {
strstore(&co->domain, valuep, vlen);
if(!co->domain) {
badcookie = TRUE;
@@ -1431,7 +1432,7 @@ struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
/* now check if the domain is correct */
if(!co->domain ||
(co->tailmatch && !is_ip &&
- tailmatch(co->domain, strlen(co->domain), host)) ||
+ cookie_tailmatch(co->domain, strlen(co->domain), host)) ||
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
/*
* the right part of the host matches the domain stuff in the
diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake
index 476e5b7ca0..1b8490a578 100644
--- a/libs/libcurl/src/curl_config.h.cmake
+++ b/libs/libcurl/src/curl_config.h.cmake
@@ -448,6 +448,9 @@
/* Define to 1 if you have the sigsetjmp function or macro. */
#cmakedefine HAVE_SIGSETJMP 1
+/* Define to 1 if you have the `snprintf' function. */
+#cmakedefine HAVE_SNPRINTF
+
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
@@ -577,9 +580,6 @@
/* Define to 1 if you have the windows.h header file. */
#cmakedefine HAVE_WINDOWS_H 1
-/* Define to 1 if you have the winldap.h header file. */
-#cmakedefine HAVE_WINLDAP_H 1
-
/* Define to 1 if you have the winsock2.h header file. */
#cmakedefine HAVE_WINSOCK2_H 1
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index d94099b443..6600a64fe3 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -177,6 +177,10 @@
/* Define to 1 if you have the clock_gettime function and monotonic timer. */
#undef HAVE_CLOCK_GETTIME_MONOTONIC
+/* Define to 1 if you have the clock_gettime function and raw monotonic timer.
+ */
+#undef HAVE_CLOCK_GETTIME_MONOTONIC_RAW
+
/* Define to 1 if you have the closesocket function. */
#undef HAVE_CLOSESOCKET
@@ -362,6 +366,9 @@
/* Define to 1 if you have the ldap.h header file. */
#undef HAVE_LDAP_H
+/* Define to 1 if you have the `ldap_init_fd' function. */
+#undef HAVE_LDAP_INIT_FD
+
/* Use LDAPS implementation */
#undef HAVE_LDAP_SSL
@@ -721,9 +728,6 @@
/* Define to 1 if you have the windows.h header file. */
#undef HAVE_WINDOWS_H
-/* Define to 1 if you have the winldap.h header file. */
-#undef HAVE_WINLDAP_H
-
/* Define to 1 if you have the winsock2.h header file. */
#undef HAVE_WINSOCK2_H
@@ -885,8 +889,8 @@
/* if ngtcp2_crypto_gnutls is in use */
#undef USE_NGTCP2_CRYPTO_GNUTLS
-/* if ngtcp2_crypto_openssl is in use */
-#undef USE_NGTCP2_CRYPTO_OPENSSL
+/* if ngtcp2_crypto_quictls is in use */
+#undef USE_NGTCP2_CRYPTO_QUICTLS
/* if ngtcp2_crypto_wolfssl is in use */
#undef USE_NGTCP2_CRYPTO_WOLFSSL
diff --git a/libs/libcurl/src/curl_log.c b/libs/libcurl/src/curl_log.c
index ecde0b3e02..d6f2423cca 100644
--- a/libs/libcurl/src/curl_log.c
+++ b/libs/libcurl/src/curl_log.c
@@ -130,13 +130,11 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...)
{
DEBUGASSERT(cf);
- if(data && Curl_log_cf_is_debug(cf)) {
+ if(data && Curl_log_cf_is_debug(cf, data)) {
va_list ap;
int len;
char buffer[MAXINFO + 2];
- len = msnprintf(buffer, MAXINFO, "[CONN-%ld%s-%s] ",
- cf->conn->connection_id, cf->sockindex? "/2" : "",
- cf->cft->name);
+ len = msnprintf(buffer, MAXINFO, "[%s] ", cf->cft->name);
va_start(ap, fmt);
len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
va_end(ap);
diff --git a/libs/libcurl/src/curl_log.h b/libs/libcurl/src/curl_log.h
index 95375ab58f..6ac4aac159 100644
--- a/libs/libcurl/src/curl_log.h
+++ b/libs/libcurl/src/curl_log.h
@@ -74,7 +74,7 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type,
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define LOG_CF(data, cf, ...) \
- do { if(Curl_log_cf_is_debug(cf)) \
+ do { if(Curl_log_cf_is_debug(cf, data)) \
Curl_log_cf_debug(data, cf, __VA_ARGS__); } while(0)
#else
#define LOG_CF Curl_log_cf_debug
@@ -90,8 +90,10 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...);
#endif
-#define Curl_log_cf_is_debug(cf) \
- ((cf) && (cf)->cft->log_level >= CURL_LOG_DEBUG)
+#define Curl_log_cf_is_debug(cf, data) \
+ ((data) && (data)->set.verbose && \
+ (cf) && (cf)->cft->log_level >= CURL_LOG_DEBUG)
+
#else /* !DEBUGBUILD */
@@ -110,29 +112,10 @@ void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...);
#endif
-#define Curl_log_cf_is_debug(x) ((void)(x), FALSE)
+#define Curl_log_cf_is_debug(x,y) ((void)(x), (void)(y), FALSE)
#endif /* !DEBUGBUILD */
-#define LOG_CF_IS_DEBUG(x) Curl_log_cf_is_debug(x)
-
-/* Macros intended for DEBUGF logging, use like:
- * DEBUGF(infof(data, CFMSG(cf, "this filter %s rocks"), "very much"));
- * and it will output:
- * [CONN-1-0][CF-SSL] this filter very much rocks
- * on connection #1 with sockindex 0 for filter of type "SSL". */
-#define DMSG(d,msg) \
- "[CONN-%ld] "msg, (d)->conn->connection_id
-#define DMSGI(d,i,msg) \
- "[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i)
-#define CMSG(c,msg) \
- "[CONN-%ld] "msg, (c)->connection_id
-#define CMSGI(c,i,msg) \
- "[CONN-%ld-%d] "msg, (c)->connection_id, (i)
-#define CFMSG(cf,msg) \
- "[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \
- (cf)->sockindex, (cf)->cft->name
-
-
+#define LOG_CF_IS_DEBUG(cf, data) Curl_log_cf_is_debug(cf, data)
#endif /* HEADER_CURL_LOG_H */
diff --git a/libs/libcurl/src/curl_memory.h b/libs/libcurl/src/curl_memory.h
index 404ad93886..0340c142db 100644
--- a/libs/libcurl/src/curl_memory.h
+++ b/libs/libcurl/src/curl_memory.h
@@ -55,9 +55,65 @@
*/
#ifdef HEADER_CURL_MEMDEBUG_H
-#error "Header memdebug.h shall not be included before curl_memory.h"
+/* cleanup after memdebug.h */
+
+#ifdef MEMDEBUG_NODEFINES
+#ifdef CURLDEBUG
+
+#undef strdup
+#undef malloc
+#undef calloc
+#undef realloc
+#undef free
+#undef send
+#undef recv
+
+#ifdef WIN32
+# ifdef UNICODE
+# undef wcsdup
+# undef _wcsdup
+# undef _tcsdup
+# else
+# undef _tcsdup
+# endif
+#endif
+
+#undef socket
+#undef accept
+#ifdef HAVE_SOCKETPAIR
+#undef socketpair
#endif
+#ifdef HAVE_GETADDRINFO
+#if defined(getaddrinfo) && defined(__osf__)
+#undef ogetaddrinfo
+#else
+#undef getaddrinfo
+#endif
+#endif /* HAVE_GETADDRINFO */
+
+#ifdef HAVE_FREEADDRINFO
+#undef freeaddrinfo
+#endif /* HAVE_FREEADDRINFO */
+
+/* sclose is probably already defined, redefine it! */
+#undef sclose
+#undef fopen
+#undef fdopen
+#undef fclose
+
+#endif /* MEMDEBUG_NODEFINES */
+#endif /* CURLDEBUG */
+
+#undef HEADER_CURL_MEMDEBUG_H
+#endif /* HEADER_CURL_MEMDEBUG_H */
+
+/*
+** Following section applies even when CURLDEBUG is not defined.
+*/
+
+#undef fake_sclose
+
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
/*
* The following memory function replacement typedef's are COPIED from
diff --git a/libs/libcurl/src/curl_printf.h b/libs/libcurl/src/curl_printf.h
index 2cf4e36939..a3c3ce773f 100644
--- a/libs/libcurl/src/curl_printf.h
+++ b/libs/libcurl/src/curl_printf.h
@@ -37,6 +37,7 @@
# undef vprintf
# undef vfprintf
# undef vsnprintf
+# undef mvsnprintf
# undef aprintf
# undef vaprintf
# define printf curl_mprintf
diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c
index 6e59061380..ff05f250da 100644
--- a/libs/libcurl/src/curl_sasl.c
+++ b/libs/libcurl/src/curl_sasl.c
@@ -221,12 +221,12 @@ void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
}
/*
- * state()
+ * sasl_state()
*
* This is the ONLY way to change SASL state!
*/
-static void state(struct SASL *sasl, struct Curl_easy *data,
- saslstate newstate)
+static void sasl_state(struct SASL *sasl, struct Curl_easy *data,
+ saslstate newstate)
{
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* for debug purposes */
@@ -508,7 +508,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
if(!result) {
*progress = SASL_INPROGRESS;
- state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
+ sasl_state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
}
}
@@ -548,14 +548,14 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
if(code != sasl->params->finalcode)
result = CURLE_LOGIN_DENIED;
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return result;
}
if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
code != sasl->params->contcode) {
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return CURLE_LOGIN_DENIED;
}
@@ -698,7 +698,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
if(code == sasl->params->finalcode) {
/* Final response was received so we are done */
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return result;
}
else if(code == sasl->params->contcode) {
@@ -708,7 +708,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
}
else {
*progress = SASL_DONE;
- state(sasl, data, SASL_STOP);
+ sasl_state(sasl, data, SASL_STOP);
return CURLE_LOGIN_DENIED;
}
@@ -745,7 +745,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
Curl_bufref_free(&resp);
- state(sasl, data, newstate);
+ sasl_state(sasl, data, newstate);
return result;
}
diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h
index bdb746bd81..cd78a1efa6 100644
--- a/libs/libcurl/src/curl_setup.h
+++ b/libs/libcurl/src/curl_setup.h
@@ -61,6 +61,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 <winapifamily.h>
+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
+ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+# define CURL_WINDOWS_APP
+# endif
+# endif
#endif
/*
@@ -248,7 +258,7 @@
#if defined(__APPLE__) && !defined(USE_ARES)
#include <TargetConditionals.h>
#define USE_RESOLVE_ON_IPS 1
-# if defined(TARGET_OS_OSX) && TARGET_OS_OSX
+# if !defined(TARGET_OS_OSX) || TARGET_OS_OSX
# define CURL_OSX_CALL_COPYPROXIES 1
# endif
#endif
diff --git a/libs/libcurl/src/curl_setup_once.h b/libs/libcurl/src/curl_setup_once.h
index 98e481ddc8..df1d35e961 100644
--- a/libs/libcurl/src/curl_setup_once.h
+++ b/libs/libcurl/src/curl_setup_once.h
@@ -77,6 +77,12 @@
# endif
#endif
+#ifdef USE_SCHANNEL
+/* Must set this before <schannel.h> is included directly or indirectly by
+ another Windows header. */
+# define SCHANNEL_USE_BLACKLISTS 1
+#endif
+
#ifdef __hpux
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
# ifdef _APP32_64BIT_OFF_T
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index 919b83de83..a89ebdc59f 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -63,6 +63,7 @@
#include "slist.h"
#include "mime.h"
#include "amigaos.h"
+#include "macos.h"
#include "warnless.h"
#include "sigpipe.h"
#include "vssh/ssh.h"
@@ -83,7 +84,7 @@
/* true globals -- for curl_global_init() and curl_global_cleanup() */
static unsigned int initialized;
-static long init_flags;
+static long easy_init_flags;
#ifdef GLOBAL_INIT_IS_THREADSAFE
@@ -181,6 +182,11 @@ static CURLcode global_init(long flags, bool memoryfuncs)
}
#endif
+ if(Curl_macos_init()) {
+ DEBUGF(fprintf(stderr, "Error: Curl_macos_init failed\n"));
+ goto fail;
+ }
+
if(Curl_resolver_global_init()) {
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
goto fail;
@@ -199,7 +205,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
}
#endif
- init_flags = flags;
+ easy_init_flags = flags;
#ifdef DEBUGBUILD
if(getenv("CURL_GLOBAL_INIT"))
@@ -274,7 +280,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
/**
* curl_global_cleanup() globally cleanups curl, uses the value of
- * "init_flags" to determine what needs to be cleaned up and what doesn't.
+ * "easy_init_flags" to determine what needs to be cleaned up and what doesn't.
*/
void curl_global_cleanup(void)
{
@@ -294,7 +300,7 @@ void curl_global_cleanup(void)
Curl_resolver_global_cleanup();
#ifdef WIN32
- Curl_win32_cleanup(init_flags);
+ Curl_win32_cleanup(easy_init_flags);
#endif
Curl_amiga_cleanup();
@@ -308,7 +314,7 @@ void curl_global_cleanup(void)
free(leakpointer);
#endif
- init_flags = 0;
+ easy_init_flags = 0;
global_init_unlock();
}
@@ -893,6 +899,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
/* the connection cache is setup on demand */
outcurl->state.conn_cache = NULL;
outcurl->state.lastconnect_id = -1;
+ outcurl->state.recent_conn_id = -1;
+ outcurl->id = -1;
outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
diff --git a/libs/libcurl/src/easy_lock.h b/libs/libcurl/src/easy_lock.h
index 4dc523f46a..dfa39ad3b2 100644
--- a/libs/libcurl/src/easy_lock.h
+++ b/libs/libcurl/src/easy_lock.h
@@ -1,3 +1,5 @@
+#ifndef HEADER_CURL_EASY_LOCK_H
+#define HEADER_CURL_EASY_LOCK_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -103,3 +105,5 @@ static inline void curl_simple_lock_unlock(curl_simple_lock *lock)
#undef GLOBAL_INIT_IS_THREADSAFE
#endif
+
+#endif /* HEADER_CURL_EASY_LOCK_H */
diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c
index 9889860217..deade8ed71 100644
--- a/libs/libcurl/src/easyoptions.c
+++ b/libs/libcurl/src/easyoptions.c
@@ -120,6 +120,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS,
CURLOT_LONG, 0},
{"HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0},
+ {"HAPROXY_CLIENT_IP", CURLOPT_HAPROXY_CLIENT_IP, CURLOT_STRING, 0},
{"HEADER", CURLOPT_HEADER, CURLOT_LONG, 0},
{"HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0},
{"HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0},
@@ -164,7 +165,9 @@ struct curl_easyoption Curl_easyopts[] = {
{"MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0},
{"MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0},
{"MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0},
- {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOT_LONG, 0},
+ {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS,
+ CURLOT_LONG, CURLOT_FLAG_ALIAS},
+ {"MAIL_RCPT_ALLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOT_LONG, 0},
{"MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0},
{"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0},
{"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0},
@@ -370,6 +373,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (322 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (323 + 1));
}
#endif
diff --git a/libs/libcurl/src/fopen.c b/libs/libcurl/src/fopen.c
index 0e9b704a7c..60dd1e18c4 100644
--- a/libs/libcurl/src/fopen.c
+++ b/libs/libcurl/src/fopen.c
@@ -56,13 +56,13 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
int fd = -1;
*tempname = NULL;
- if(stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode)) {
- /* a non-regular file, fallback to direct fopen() */
- *fh = fopen(filename, FOPEN_WRITETEXT);
- if(*fh)
- return CURLE_OK;
+ *fh = fopen(filename, FOPEN_WRITETEXT);
+ if(!*fh)
goto fail;
- }
+ if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode))
+ return CURLE_OK;
+ fclose(*fh);
+ *fh = NULL;
result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix));
if(result)
@@ -85,7 +85,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
if((fstat(fd, &nsb) != -1) &&
(nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) {
/* if the user and group are the same, clone the original mode */
- if(fchmod(fd, sb.st_mode) == -1)
+ if(fchmod(fd, (mode_t)sb.st_mode) == -1)
goto fail;
}
}
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index 17eba04e4e..851f75cedf 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.c
@@ -93,14 +93,14 @@
/* Local API functions */
#ifndef DEBUGBUILD
-static void _state(struct Curl_easy *data,
- ftpstate newstate);
-#define state(x,y) _state(x,y)
+static void _ftp_state(struct Curl_easy *data,
+ ftpstate newstate);
+#define ftp_state(x,y) _ftp_state(x,y)
#else
-static void _state(struct Curl_easy *data,
- ftpstate newstate,
- int lineno);
-#define state(x,y) _state(x,y,__LINE__)
+static void _ftp_state(struct Curl_easy *data,
+ ftpstate newstate,
+ int lineno);
+#define ftp_state(x,y) _ftp_state(x,y,__LINE__)
#endif
static CURLcode ftp_sendquote(struct Curl_easy *data,
@@ -463,7 +463,7 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
@@ -591,7 +591,7 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
* generically is a good idea.
*/
infof(data, "We got a 421 - timeout");
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OPERATION_TIMEDOUT;
}
@@ -750,10 +750,10 @@ static const char * const ftp_state_names[]={
#endif
/* This is the ONLY way to change FTP state! */
-static void _state(struct Curl_easy *data,
- ftpstate newstate
+static void _ftp_state(struct Curl_easy *data,
+ ftpstate newstate
#ifdef DEBUGBUILD
- , int lineno
+ , int lineno
#endif
)
{
@@ -784,7 +784,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
if(!result) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
ftpc->ftp_trying_alternative = FALSE;
- state(data, FTP_USER);
+ ftp_state(data, FTP_USER);
}
return result;
}
@@ -794,7 +794,7 @@ static CURLcode ftp_state_pwd(struct Curl_easy *data,
{
CURLcode result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PWD");
if(!result)
- state(data, FTP_PWD);
+ ftp_state(data, FTP_PWD);
return result;
}
@@ -872,7 +872,7 @@ static CURLcode ftp_state_cwd(struct Curl_easy *data,
for all upcoming ones in the ftp->dirs[] array */
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath);
if(!result)
- state(data, FTP_CWD);
+ ftp_state(data, FTP_CWD);
}
else {
if(ftpc->dirdepth) {
@@ -882,7 +882,7 @@ static CURLcode ftp_state_cwd(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount -1]);
if(!result)
- state(data, FTP_CWD);
+ ftp_state(data, FTP_CWD);
}
else {
/* No CWD necessary */
@@ -1261,11 +1261,11 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
if(result)
goto out;
portsock = CURL_SOCKET_BAD; /* now held in filter */
- state(data, FTP_PORT);
+ ftp_state(data, FTP_PORT);
out:
if(result) {
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
}
if(portsock != CURL_SOCKET_BAD)
Curl_socket_close(data, conn, portsock);
@@ -1307,7 +1307,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
if(!result) {
ftpc->count1 = modeoff;
- state(data, FTP_PASV);
+ ftp_state(data, FTP_PASV);
infof(data, "Connect data stream passively");
}
return result;
@@ -1330,7 +1330,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
/* doesn't transfer any data */
/* still possibly do PRE QUOTE jobs */
- state(data, FTP_RETR_PREQUOTE);
+ ftp_state(data, FTP_RETR_PREQUOTE);
result = ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE);
}
else if(data->set.ftp_use_port) {
@@ -1355,7 +1355,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s",
conn->proto.ftpc.file);
if(!result)
- state(data, FTP_PRET);
+ ftp_state(data, FTP_PRET);
}
else
result = ftp_state_use_pasv(data, conn);
@@ -1377,7 +1377,7 @@ static CURLcode ftp_state_rest(struct Curl_easy *data,
whether it supports range */
result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0);
if(!result)
- state(data, FTP_REST);
+ ftp_state(data, FTP_REST);
}
else
result = ftp_state_prepare_transfer(data);
@@ -1398,7 +1398,7 @@ static CURLcode ftp_state_size(struct Curl_easy *data,
/* we know ftpc->file is a valid pointer to a file name */
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(data, FTP_SIZE);
+ ftp_state(data, FTP_SIZE);
}
else
result = ftp_state_rest(data, conn);
@@ -1466,7 +1466,7 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
free(cmd);
if(!result)
- state(data, FTP_LIST);
+ ftp_state(data, FTP_LIST);
return result;
}
@@ -1530,7 +1530,7 @@ static CURLcode ftp_state_mdtm(struct Curl_easy *data)
result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file);
if(!result)
- state(data, FTP_MDTM);
+ ftp_state(data, FTP_MDTM);
}
else
result = ftp_state_type(data);
@@ -1569,7 +1569,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
/* Got no given size to start from, figure it out */
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(data, FTP_STOR_SIZE);
+ ftp_state(data, FTP_STOR_SIZE);
return result;
}
@@ -1624,7 +1624,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
* ftp_done() because we didn't transfer anything! */
ftp->transfer = PPTRANSFER_NONE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
}
@@ -1634,7 +1634,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s",
ftpc->file);
if(!result)
- state(data, FTP_STOR);
+ ftp_state(data, FTP_STOR);
return result;
}
@@ -1695,7 +1695,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
if(result)
return result;
- state(data, instate);
+ ftp_state(data, instate);
quote = TRUE;
}
}
@@ -1709,7 +1709,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
break;
case FTP_RETR_PREQUOTE:
if(ftp->transfer != PPTRANSFER_BODY)
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
else {
if(ftpc->known_filesize != -1) {
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
@@ -1731,12 +1731,12 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
*/
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(data, FTP_RETR);
+ ftp_state(data, FTP_RETR);
}
else {
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
if(!result)
- state(data, FTP_RETR_SIZE);
+ ftp_state(data, FTP_RETR_SIZE);
}
}
}
@@ -1780,7 +1780,7 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
if(!result) {
conn->proto.ftpc.count1++;
/* remain in/go to the FTP_PASV state */
- state(data, FTP_PASV);
+ ftp_state(data, FTP_PASV);
}
return result;
}
@@ -2005,7 +2005,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
conn->bits.do_more = TRUE;
- state(data, FTP_STOP); /* this phase is completed */
+ ftp_state(data, FTP_STOP); /* this phase is completed */
return result;
}
@@ -2039,7 +2039,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
}
else {
infof(data, "Connect data stream actively");
- state(data, FTP_STOP); /* end of DO phase */
+ ftp_state(data, FTP_STOP); /* end of DO phase */
result = ftp_dophase_done(data, FALSE);
}
@@ -2151,7 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
infof(data, "The requested document is not new enough");
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
data->info.timecond = TRUE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
break;
@@ -2160,7 +2160,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
infof(data, "The requested document is not old enough");
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
data->info.timecond = TRUE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
break;
@@ -2268,7 +2268,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
/* Set ->transfer so that we won't get any error in ftp_done()
* because we didn't transfer the any file */
ftp->transfer = PPTRANSFER_NONE;
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return CURLE_OK;
}
@@ -2279,13 +2279,13 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
data->state.resume_from);
if(!result)
- state(data, FTP_RETR_REST);
+ ftp_state(data, FTP_RETR_REST);
}
else {
/* no resume */
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(data, FTP_RETR);
+ ftp_state(data, FTP_RETR);
}
return result;
@@ -2385,7 +2385,7 @@ static CURLcode ftp_state_rest_resp(struct Curl_easy *data,
else {
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
if(!result)
- state(data, FTP_RETR);
+ ftp_state(data, FTP_RETR);
}
break;
}
@@ -2401,7 +2401,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
if(ftpcode >= 400) {
failf(data, "Failed FTP upload: %0d", ftpcode);
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
/* oops, we never close the sockets! */
return CURLE_UPLOAD_FAILED;
}
@@ -2412,7 +2412,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
if(data->set.ftp_use_port) {
bool connected;
- state(data, FTP_STOP); /* no longer in STOR state */
+ ftp_state(data, FTP_STOP); /* no longer in STOR state */
result = AllowServerConnect(data, &connected);
if(result)
@@ -2535,7 +2535,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately");
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
ftpc->wait_data_conn = TRUE;
}
}
@@ -2546,7 +2546,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
if((instate == FTP_LIST) && (ftpcode == 450)) {
/* simply no matching files in the dir listing */
ftp->transfer = PPTRANSFER_NONE; /* don't download anything */
- state(data, FTP_STOP); /* this phase is over */
+ ftp_state(data, FTP_STOP); /* this phase is over */
}
else {
failf(data, "RETR response: %03d", ftpcode);
@@ -2582,7 +2582,7 @@ static CURLcode ftp_state_loggedin(struct Curl_easy *data)
*/
result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "PBSZ %d", 0);
if(!result)
- state(data, FTP_PBSZ);
+ ftp_state(data, FTP_PBSZ);
}
else {
result = ftp_state_pwd(data, conn);
@@ -2605,7 +2605,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
conn->passwd?conn->passwd:"");
if(!result)
- state(data, FTP_PASS);
+ ftp_state(data, FTP_PASS);
}
else if(ftpcode/100 == 2) {
/* 230 User ... logged in.
@@ -2617,7 +2617,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s",
data->set.str[STRING_FTP_ACCOUNT]);
if(!result)
- state(data, FTP_ACCT);
+ ftp_state(data, FTP_ACCT);
}
else {
failf(data, "ACCT requested but none available");
@@ -2638,7 +2638,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
if(!result) {
ftpc->ftp_trying_alternative = TRUE;
- state(data, FTP_USER);
+ ftp_state(data, FTP_USER);
}
}
else {
@@ -2741,7 +2741,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s",
ftpauth[ftpc->count1]);
if(!result)
- state(data, FTP_AUTH);
+ ftp_state(data, FTP_AUTH);
}
else
result = ftp_state_user(data, conn);
@@ -2808,7 +2808,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
Curl_pp_sendf(data, &ftpc->pp, "PROT %c",
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
if(!result)
- state(data, FTP_PROT);
+ ftp_state(data, FTP_PROT);
break;
case FTP_PROT:
@@ -2827,7 +2827,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
*/
result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC");
if(!result)
- state(data, FTP_CCC);
+ ftp_state(data, FTP_CCC);
}
else
result = ftp_state_pwd(data, conn);
@@ -2919,7 +2919,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
infof(data, "Entry path is '%s'", ftpc->entrypath);
/* also save it where getinfo can access it: */
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
- state(data, FTP_SYST);
+ ftp_state(data, FTP_SYST);
break;
}
@@ -2935,7 +2935,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
infof(data, "Failed to figure out path");
}
}
- state(data, FTP_STOP); /* we are done with the CONNECT phase! */
+ ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE"));
break;
@@ -2970,7 +2970,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* remember target server OS */
Curl_safefree(ftpc->server_os);
ftpc->server_os = os;
- state(data, FTP_NAMEFMT);
+ ftp_state(data, FTP_NAMEFMT);
break;
}
/* Nothing special for the target server. */
@@ -2982,7 +2982,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* Cannot identify server OS. Continue anyway and cross fingers. */
}
- state(data, FTP_STOP); /* we are done with the CONNECT phase! */
+ ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE"));
break;
@@ -2993,7 +2993,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
break;
}
- state(data, FTP_STOP); /* we are done with the CONNECT phase! */
+ ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
DEBUGF(infof(data, "protocol connect phase DONE"));
break;
@@ -3026,7 +3026,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
result = Curl_pp_sendf(data, &ftpc->pp, "MKD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
if(!result)
- state(data, FTP_MKD);
+ ftp_state(data, FTP_MKD);
}
else {
/* return failure */
@@ -3055,7 +3055,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
result = CURLE_REMOTE_ACCESS_DENIED;
}
else {
- state(data, FTP_CWD);
+ ftp_state(data, FTP_CWD);
/* send CWD */
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
ftpc->dirs[ftpc->cwdcount - 1]);
@@ -3114,7 +3114,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
/* fallthrough, just stop! */
default:
/* internal error */
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
break;
}
} /* if(ftpcode) */
@@ -3191,7 +3191,7 @@ static CURLcode ftp_connect(struct Curl_easy *data,
/* When we connect, we start in the state where we await the 220
response */
- state(data, FTP_WAIT220);
+ ftp_state(data, FTP_WAIT220);
result = ftp_multi_statemach(data, done);
@@ -3516,13 +3516,13 @@ static CURLcode ftp_nb_type(struct Curl_easy *data,
char want = (char)(ascii?'A':'I');
if(ftpc->transfertype == want) {
- state(data, newstate);
+ ftp_state(data, newstate);
return ftp_state_type_resp(data, 200, newstate);
}
result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want);
if(!result) {
- state(data, newstate);
+ ftp_state(data, newstate);
/* keep track of our current transfer type */
ftpc->transfertype = want;
@@ -4039,11 +4039,11 @@ static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn)
curl_easy_strerror(result));
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
connclose(conn, "QUIT command failed"); /* mark for connection closure */
- state(data, FTP_STOP);
+ ftp_state(data, FTP_STOP);
return result;
}
- state(data, FTP_QUIT);
+ ftp_state(data, FTP_QUIT);
result = ftp_block_statemach(data, conn);
}
diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c
index 0a29666c85..28e9c06c1d 100644
--- a/libs/libcurl/src/getinfo.c
+++ b/libs/libcurl/src/getinfo.c
@@ -415,6 +415,13 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
case CURLINFO_RETRY_AFTER:
*param_offt = data->info.retry_after;
break;
+ case CURLINFO_XFER_ID:
+ *param_offt = data->id;
+ break;
+ case CURLINFO_CONN_ID:
+ *param_offt = data->conn?
+ data->conn->connection_id : data->state.recent_conn_id;
+ break;
default:
return CURLE_UNKNOWN_OPTION;
}
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index 57479b1428..04ac91437c 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -67,10 +67,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
-#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
-#endif
-
#if defined(CURLRES_SYNCH) && \
defined(HAVE_ALARM) && \
defined(SIGALRM) && \
@@ -743,23 +739,6 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
return CURLRESOLV_ERROR;
}
-#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
- {
- /*
- * The automagic conversion from IPv4 literals to IPv6 literals only
- * works if the SCDynamicStoreCopyProxies system function gets called
- * first. As Curl currently doesn't support system-wide HTTP proxies, we
- * therefore don't use any value this function might return.
- *
- * This function is only available on a macOS and is not needed for
- * IPv4-only builds, hence the conditions above.
- */
- CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
- if(dict)
- CFRelease(dict);
- }
-#endif
-
#ifndef USE_RESOLVE_ON_IPS
/* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
diff --git a/libs/libcurl/src/hsts.c b/libs/libcurl/src/hsts.c
index 535465ce79..baf308874a 100644
--- a/libs/libcurl/src/hsts.c
+++ b/libs/libcurl/src/hsts.c
@@ -57,7 +57,7 @@
/* to play well with debug builds, we can *set* a fixed time this will
return */
time_t deltatime; /* allow for "adjustments" for unit test purposes */
-static time_t debugtime(void *unused)
+static time_t hsts_debugtime(void *unused)
{
char *timestr = getenv("CURL_TIME");
(void)unused;
@@ -70,7 +70,8 @@ static time_t debugtime(void *unused)
}
return time(NULL);
}
-#define time(x) debugtime(x)
+#undef time
+#define time(x) hsts_debugtime(x)
#endif
struct hsts *Curl_hsts_init(void)
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index c335f872e0..fcbbeddaaa 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -2667,11 +2667,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
#ifndef USE_HYPER
/* With Hyper the body is always passed on separately */
if(data->set.postfields) {
-
- /* In HTTP2, we send request body in DATA frame regardless of
- its size. */
- if(conn->httpversion < 20 &&
- !data->state.expect100header &&
+ if(!data->state.expect100header &&
(http->postsize < MAX_INITIAL_POST_SIZE)) {
/* if we don't use expect: 100 AND
postsize is less than MAX_INITIAL_POST_SIZE
@@ -2832,16 +2828,18 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
}
if(co) {
struct Cookie *store = co;
+ size_t clen = 8; /* hold the size of the generated Cookie: header */
/* now loop through all cookies that matched */
while(co) {
if(co->value) {
- if(0 == count) {
+ size_t add;
+ if(!count) {
result = Curl_dyn_addn(r, STRCONST("Cookie: "));
if(result)
break;
}
- if((Curl_dyn_len(r) + strlen(co->name) + strlen(co->value) + 1) >=
- MAX_COOKIE_HEADER_LEN) {
+ add = strlen(co->name) + strlen(co->value) + 1;
+ if(clen + add >= MAX_COOKIE_HEADER_LEN) {
infof(data, "Restricted outgoing cookies due to header size, "
"'%s' not sent", co->name);
linecap = TRUE;
@@ -2851,6 +2849,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
co->name, co->value);
if(result)
break;
+ clen += add + (count ? 2 : 0);
count++;
}
co = co->next; /* next cookie please */
diff --git a/libs/libcurl/src/http1.c b/libs/libcurl/src/http1.c
index a5c85f50b4..6845f8c2f4 100644
--- a/libs/libcurl/src/http1.c
+++ b/libs/libcurl/src/http1.c
@@ -38,124 +38,97 @@
#include "memdebug.h"
-#define MAX_URL_LEN (4*1024)
+#define H1_MAX_URL_LEN (8*1024)
void Curl_h1_req_parse_init(struct h1_req_parser *parser, size_t max_line_len)
{
memset(parser, 0, sizeof(*parser));
parser->max_line_len = max_line_len;
- Curl_bufq_init(&parser->scratch, max_line_len, 1);
+ Curl_dyn_init(&parser->scratch, max_line_len);
}
void Curl_h1_req_parse_free(struct h1_req_parser *parser)
{
if(parser) {
Curl_http_req_free(parser->req);
- Curl_bufq_free(&parser->scratch);
+ Curl_dyn_free(&parser->scratch);
parser->req = NULL;
parser->done = FALSE;
}
}
+static CURLcode trim_line(struct h1_req_parser *parser, int options)
+{
+ DEBUGASSERT(parser->line);
+ if(parser->line_len) {
+ if(parser->line[parser->line_len - 1] == '\n')
+ --parser->line_len;
+ if(parser->line_len) {
+ if(parser->line[parser->line_len - 1] == '\r')
+ --parser->line_len;
+ else if(options & H1_PARSE_OPT_STRICT)
+ return CURLE_URL_MALFORMAT;
+ }
+ else if(options & H1_PARSE_OPT_STRICT)
+ return CURLE_URL_MALFORMAT;
+ }
+ else if(options & H1_PARSE_OPT_STRICT)
+ return CURLE_URL_MALFORMAT;
+
+ if(parser->line_len > parser->max_line_len) {
+ return CURLE_URL_MALFORMAT;
+ }
+ return CURLE_OK;
+}
+
static ssize_t detect_line(struct h1_req_parser *parser,
- const char *buf, const size_t buflen, int options,
+ const char *buf, const size_t buflen,
CURLcode *err)
{
const char *line_end;
- size_t len;
DEBUGASSERT(!parser->line);
line_end = memchr(buf, '\n', buflen);
if(!line_end) {
- *err = (buflen > parser->max_line_len)? CURLE_URL_MALFORMAT : CURLE_AGAIN;
+ *err = CURLE_AGAIN;
return -1;
}
- len = line_end - buf + 1;
- if(len > parser->max_line_len) {
- *err = CURLE_URL_MALFORMAT;
- return -1;
- }
-
- if(options & H1_PARSE_OPT_STRICT) {
- if((len == 1) || (buf[len - 2] != '\r')) {
- *err = CURLE_URL_MALFORMAT;
- return -1;
- }
- parser->line = buf;
- parser->line_len = len - 2;
- }
- else {
- parser->line = buf;
- parser->line_len = len - (((len == 1) || (buf[len - 2] != '\r'))? 1 : 2);
- }
+ parser->line = buf;
+ parser->line_len = line_end - buf + 1;
*err = CURLE_OK;
- return (ssize_t)len;
+ return (ssize_t)parser->line_len;
}
static ssize_t next_line(struct h1_req_parser *parser,
const char *buf, const size_t buflen, int options,
CURLcode *err)
{
- ssize_t nread = 0, n;
+ ssize_t nread = 0;
if(parser->line) {
- if(parser->scratch_skip) {
- /* last line was from scratch. Remove it now, since we are done
- * with it and look for the next one. */
- Curl_bufq_skip_and_shift(&parser->scratch, parser->scratch_skip);
- parser->scratch_skip = 0;
- }
parser->line = NULL;
parser->line_len = 0;
+ Curl_dyn_reset(&parser->scratch);
}
- if(Curl_bufq_is_empty(&parser->scratch)) {
- nread = detect_line(parser, buf, buflen, options, err);
- if(nread < 0) {
- if(*err != CURLE_AGAIN)
+ nread = detect_line(parser, buf, buflen, err);
+ if(nread >= 0) {
+ if(Curl_dyn_len(&parser->scratch)) {
+ /* append detected line to scratch to have the complete line */
+ *err = Curl_dyn_addn(&parser->scratch, parser->line, parser->line_len);
+ if(*err)
return -1;
- /* not a complete line, add to scratch for later revisit */
- nread = Curl_bufq_write(&parser->scratch,
- (const unsigned char *)buf, buflen, err);
- return nread;
+ parser->line = Curl_dyn_ptr(&parser->scratch);
+ parser->line_len = Curl_dyn_len(&parser->scratch);
}
- /* found one */
+ *err = trim_line(parser, options);
+ if(*err)
+ return -1;
}
- else {
- const char *sbuf;
- size_t sbuflen;
-
- /* scratch contains bytes from last attempt, add more to it */
- if(buflen) {
- const char *line_end;
- size_t add_len;
- ssize_t pos;
-
- line_end = memchr(buf, '\n', buflen);
- pos = line_end? (line_end - buf + 1) : -1;
- add_len = (pos >= 0)? (size_t)pos : buflen;
- nread = Curl_bufq_write(&parser->scratch,
- (const unsigned char *)buf, add_len, err);
- if(nread < 0) {
- /* Unable to add anything to scratch is an error, since we should
- * have seen a line there then before. */
- if(*err == CURLE_AGAIN)
- *err = CURLE_URL_MALFORMAT;
- return -1;
- }
- }
-
- if(Curl_bufq_peek(&parser->scratch,
- (const unsigned char **)&sbuf, &sbuflen)) {
- n = detect_line(parser, sbuf, sbuflen, options, err);
- if(n < 0 && *err != CURLE_AGAIN)
- return -1; /* real error */
- parser->scratch_skip = (size_t)n;
- }
- else {
- /* we SHOULD be able to peek at scratch data */
- DEBUGASSERT(0);
- }
+ else if(*err == CURLE_AGAIN) {
+ /* no line end in `buf`, add it to our scratch */
+ *err = Curl_dyn_addn(&parser->scratch, (const unsigned char *)buf, buflen);
+ nread = (*err)? -1 : (ssize_t)buflen;
}
return nread;
}
@@ -231,7 +204,7 @@ static CURLcode start_req(struct h1_req_parser *parser,
else {
/* origin-form OR absolute-form */
CURLUcode uc;
- char tmp[MAX_URL_LEN];
+ char tmp[H1_MAX_URL_LEN];
/* default, unless we see an absolute URL */
path = target;
@@ -328,7 +301,7 @@ ssize_t Curl_h1_req_parse_read(struct h1_req_parser *parser,
goto out;
}
parser->done = TRUE;
- Curl_bufq_free(&parser->scratch);
+ Curl_dyn_reset(&parser->scratch);
/* last chance adjustments */
}
else {
diff --git a/libs/libcurl/src/http1.h b/libs/libcurl/src/http1.h
index 4d8c7f41bd..0047b349ca 100644
--- a/libs/libcurl/src/http1.h
+++ b/libs/libcurl/src/http1.h
@@ -33,11 +33,11 @@
#define H1_PARSE_OPT_NONE (0)
#define H1_PARSE_OPT_STRICT (1 << 0)
-#define H1_PARSE_DEFAULT_MAX_LINE_LEN (8 * 1024)
+#define H1_PARSE_DEFAULT_MAX_LINE_LEN DYN_HTTP_REQUEST
struct h1_req_parser {
struct httpreq *req;
- struct bufq scratch;
+ struct dynbuf scratch;
size_t scratch_skip;
const char *line;
size_t max_line_len;
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index 9e9a7e3e72..00a5b107c0 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -134,9 +134,11 @@ struct cf_h2_ctx {
BIT(conn_closed);
BIT(goaway);
BIT(enable_push);
+ BIT(nw_out_blocked);
};
/* How to access `call_data` from a cf_h2 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_h2_ctx *)(cf)->ctx)->call_data
@@ -175,6 +177,7 @@ struct stream_ctx {
struct bufq sendbuf; /* request buffer */
struct dynhds resp_trailers; /* response trailer fields */
size_t resp_hds_len; /* amount of response header bytes in recvbuf */
+ size_t upload_blocked_len;
curl_off_t upload_left; /* number of request bytes left to upload */
char **push_headers; /* allocated array */
@@ -183,6 +186,7 @@ struct stream_ctx {
int status_code; /* HTTP response status code */
uint32_t error; /* stream error code */
+ uint32_t local_window_size; /* the local recv window size */
bool closed; /* TRUE on stream close */
bool reset; /* TRUE on stream reset */
bool close_handled; /* TRUE if stream closure is handled by libcurl */
@@ -209,9 +213,12 @@ static void drain_stream(struct Curl_cfilter *cf,
(void)cf;
bits = CURL_CSELECT_IN;
- if(!stream->send_closed && stream->upload_left)
+ if(!stream->send_closed &&
+ (stream->upload_left || stream->upload_blocked_len))
bits |= CURL_CSELECT_OUT;
if(data->state.dselect_bits != bits) {
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] DRAIN dselect_bits=%x",
+ stream->id, bits));
data->state.dselect_bits = bits;
Curl_expire(data, 0, EXPIRE_RUN_NOW);
}
@@ -252,6 +259,7 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf,
stream->closed = FALSE;
stream->close_handled = FALSE;
stream->error = NGHTTP2_NO_ERROR;
+ stream->local_window_size = H2_STREAM_WINDOW_SIZE;
stream->upload_left = 0;
H2_STREAM_LCTX(data) = stream;
@@ -580,7 +588,6 @@ static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data,
ssize_t nread = -1;
*input_pending = FALSE;
- Curl_attach_connection(data, cf->conn);
nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
if(nread != -1) {
DEBUGF(LOG_CF(data, cf, "%zd bytes stray data read before trying "
@@ -592,11 +599,10 @@ static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data,
alive = !should_close_session(ctx);
}
}
- else {
+ else if(result != CURLE_AGAIN) {
/* the read failed so let's say this is dead anyway */
alive = FALSE;
}
- Curl_detach_connection(data);
}
return alive;
@@ -644,13 +650,17 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
if(Curl_bufq_is_empty(&ctx->outbufq))
return CURLE_OK;
- DEBUGF(LOG_CF(data, cf, "h2 conn flush %zu bytes",
- Curl_bufq_len(&ctx->outbufq)));
nwritten = Curl_bufq_pass(&ctx->outbufq, nw_out_writer, cf, &result);
- if(nwritten < 0 && result != CURLE_AGAIN) {
+ if(nwritten < 0) {
+ if(result == CURLE_AGAIN) {
+ DEBUGF(LOG_CF(data, cf, "flush nw send buffer(%zu) -> EAGAIN",
+ Curl_bufq_len(&ctx->outbufq)));
+ ctx->nw_out_blocked = 1;
+ }
return result;
}
- return CURLE_OK;
+ DEBUGF(LOG_CF(data, cf, "nw send buffer flushed"));
+ return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
}
/*
@@ -676,15 +686,17 @@ static ssize_t send_callback(nghttp2_session *h2,
nw_out_writer, cf, &result);
if(nwritten < 0) {
if(result == CURLE_AGAIN) {
+ ctx->nw_out_blocked = 1;
return NGHTTP2_ERR_WOULDBLOCK;
}
failf(data, "Failed sending HTTP2 data");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- if(!nwritten)
+ if(!nwritten) {
+ ctx->nw_out_blocked = 1;
return NGHTTP2_ERR_WOULDBLOCK;
-
+ }
return nwritten;
}
@@ -964,6 +976,7 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
struct stream_ctx *stream = H2_STREAM_CTX(data);
int32_t stream_id = frame->hd.stream_id;
CURLcode result;
+ size_t rbuflen;
int rv;
if(!stream) {
@@ -973,10 +986,10 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
switch(frame->hd.type) {
case NGHTTP2_DATA:
+ rbuflen = Curl_bufq_len(&stream->recvbuf);
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] FRAME[DATA len=%zu pad=%zu], "
"buffered=%zu, window=%d/%d",
- stream_id, frame->hd.length, frame->data.padlen,
- Curl_bufq_len(&stream->recvbuf),
+ stream_id, frame->hd.length, frame->data.padlen, rbuflen,
nghttp2_session_get_stream_effective_recv_data_length(
ctx->h2, stream->id),
nghttp2_session_get_stream_effective_local_window_size(
@@ -993,6 +1006,20 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
drain_stream(cf, data, stream);
}
+ else if(rbuflen > stream->local_window_size) {
+ int32_t wsize = nghttp2_session_get_stream_local_window_size(
+ ctx->h2, stream->id);
+ if(wsize > 0 && (uint32_t)wsize != stream->local_window_size) {
+ /* H2 flow control is not absolute, as the server might not have the
+ * same view, yet. When we recieve more than we want, we enforce
+ * the local window size again to make nghttp2 send WINDOW_UPATEs
+ * accordingly. */
+ nghttp2_session_set_local_window_size(ctx->h2,
+ NGHTTP2_FLAG_NONE,
+ stream->id,
+ stream->local_window_size);
+ }
+ }
break;
case NGHTTP2_HEADERS:
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] FRAME[HEADERS]", stream_id));
@@ -1095,6 +1122,21 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
ctx->max_concurrent_streams));
multi_connchanged(data->multi);
}
+ /* Since the initial stream window is 64K, a request might be on HOLD,
+ * due to exhaustion. The (initial) SETTINGS may announce a much larger
+ * window and *assume* that we treat this like a WINDOW_UPDATE. Some
+ * servers send an explicit WINDOW_UPDATE, but not all seem to do that.
+ * To be safe, we UNHOLD a stream in order not to stall. */
+ if((data->req.keepon & KEEP_SEND_HOLD) &&
+ (data->req.keepon & KEEP_SEND)) {
+ struct stream_ctx *stream = H2_STREAM_CTX(data);
+ data->req.keepon &= ~KEEP_SEND_HOLD;
+ if(stream) {
+ drain_stream(cf, data, stream);
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] un-holding after SETTINGS",
+ stream_id));
+ }
+ }
break;
}
case NGHTTP2_GOAWAY:
@@ -1448,8 +1490,8 @@ static ssize_t req_body_read_callback(nghttp2_session *session,
if(nread > 0 && stream->upload_left != -1)
stream->upload_left -= nread;
- DEBUGF(LOG_CF(data_s, cf, "[h2sid=%d] req_body_read(len=%zu) left=%zd"
- " -> %zd, %d",
+ DEBUGF(LOG_CF(data_s, cf, "[h2sid=%d] req_body_read(len=%zu) left=%"
+ CURL_FORMAT_CURL_OFF_T " -> %zd, %d",
stream_id, length, stream->upload_left, nread, result));
if(stream->upload_left == 0)
@@ -1555,11 +1597,6 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf,
*err = CURLE_SEND_ERROR; /* trigger Curl_retry_request() later */
return -1;
}
- else if(stream->reset) {
- failf(data, "HTTP/2 stream %u was reset", stream->id);
- *err = stream->bodystarted? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR;
- return -1;
- }
else if(stream->error != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %u)",
stream->id, nghttp2_http2_strerror(stream->error),
@@ -1567,6 +1604,11 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf,
*err = CURLE_HTTP2_STREAM;
return -1;
}
+ else if(stream->reset) {
+ failf(data, "HTTP/2 stream %u was reset", stream->id);
+ *err = stream->bodystarted? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR;
+ return -1;
+ }
if(!stream->bodystarted) {
failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
@@ -1659,9 +1701,10 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
struct stream_ctx *stream = H2_STREAM_CTX(data);
int rv = 0;
- if((sweight_wanted(data) != sweight_in_effect(data)) ||
- (data->set.priority.exclusive != data->state.priority.exclusive) ||
- (data->set.priority.parent != data->state.priority.parent) ) {
+ if(stream && stream->id > 0 &&
+ ((sweight_wanted(data) != sweight_in_effect(data)) ||
+ (data->set.priority.exclusive != data->state.priority.exclusive) ||
+ (data->set.priority.parent != data->state.priority.parent)) ) {
/* send new weight and/or dependency */
nghttp2_priority_spec pri_spec;
@@ -1675,7 +1718,8 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
goto out;
}
- while(!rv && nghttp2_session_want_write(ctx->h2))
+ ctx->nw_out_blocked = 0;
+ while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2))
rv = nghttp2_session_send(ctx->h2);
out:
@@ -1739,7 +1783,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
/* Process network input buffer fist */
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
- DEBUGF(LOG_CF(data, cf, "Process %zd bytes in connection buffer",
+ DEBUGF(LOG_CF(data, cf, "Process %zu bytes in connection buffer",
Curl_bufq_len(&ctx->inbufq)));
if(h2_process_pending_input(cf, data, &result) < 0)
return result;
@@ -1760,7 +1804,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
}
nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
- /* DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
+ /* DEBUGF(LOG_CF(data, cf, "read %zu bytes nw data -> %zd, %d",
Curl_bufq_len(&ctx->inbufq), nread, result)); */
if(nread < 0) {
if(result != CURLE_AGAIN) {
@@ -1836,7 +1880,7 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
out:
result = h2_progress_egress(cf, data);
- if(result) {
+ if(result && result != CURLE_AGAIN) {
*err = result;
nread = -1;
}
@@ -1864,7 +1908,8 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
struct h1_req_parser h1;
struct dynhds h2_headers;
nghttp2_nv *nva = NULL;
- size_t nheader, i;
+ const void *body = NULL;
+ size_t nheader, bodylen, i;
nghttp2_data_provider data_prd;
int32_t stream_id;
nghttp2_priority_spec pri_spec;
@@ -1929,8 +1974,8 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
h2_pri_spec(data, &pri_spec);
- DEBUGF(LOG_CF(data, cf, "send request allowed %d (easy handle %p)",
- nghttp2_session_check_request_allowed(ctx->h2), (void *)data));
+ DEBUGF(LOG_CF(data, cf, "send request allowed %d",
+ nghttp2_session_check_request_allowed(ctx->h2)));
switch(data->state.httpreq) {
case HTTPREQ_POST:
@@ -1966,9 +2011,35 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) submit %s",
stream_id, len, data->state.url));
- infof(data, "Using Stream ID: %u (easy handle %p)",
- stream_id, (void *)data);
+ infof(data, "Using Stream ID: %u", stream_id);
stream->id = stream_id;
+ stream->local_window_size = H2_STREAM_WINDOW_SIZE;
+ if(data->set.max_recv_speed) {
+ /* We are asked to only receive `max_recv_speed` bytes per second.
+ * Let's limit our stream window size around that, otherwise the server
+ * will send in large bursts only. We make the window 50% larger to
+ * allow for data in flight and avoid stalling. */
+ curl_off_t n = (((data->set.max_recv_speed - 1) / H2_CHUNK_SIZE) + 1);
+ n += CURLMAX((n/2), 1);
+ if(n < (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE) &&
+ n < (UINT_MAX / H2_CHUNK_SIZE)) {
+ stream->local_window_size = (uint32_t)n * H2_CHUNK_SIZE;
+ }
+ }
+
+ body = (const char *)buf + nwritten;
+ bodylen = len - nwritten;
+
+ if(bodylen) {
+ /* We have request body to send in DATA frame */
+ ssize_t n = Curl_bufq_write(&stream->sendbuf, body, bodylen, err);
+ if(n < 0) {
+ *err = CURLE_SEND_ERROR;
+ nwritten = -1;
+ goto out;
+ }
+ nwritten += n;
+ }
out:
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] submit -> %zd, %d",
@@ -1982,17 +2053,13 @@ out:
static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
- /*
- * Currently, we send request in this function, but this function is also
- * used to send request body. It would be nice to add dedicated function for
- * request.
- */
struct cf_h2_ctx *ctx = cf->ctx;
struct stream_ctx *stream = H2_STREAM_CTX(data);
struct cf_call_data save;
int rv;
ssize_t nwritten;
CURLcode result;
+ int blocked = 0;
CF_DATA_SAVE(save, cf, data);
@@ -2007,18 +2074,35 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
nwritten = http2_handle_stream_close(cf, data, stream, err);
goto out;
}
- /* If stream_id != -1, we have dispatched request HEADERS, and now
- are going to send or sending request body in DATA frame */
- nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err);
- if(nwritten < 0) {
- if(*err != CURLE_AGAIN)
+ else if(stream->upload_blocked_len) {
+ /* the data in `buf` has alread been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= stream->upload_blocked_len);
+ if(len < stream->upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happend. We are not prepared to handle that. */
+ failf(data, "HTTP/2 send again with decreased length");
+ *err = CURLE_HTTP2;
+ nwritten = -1;
goto out;
- nwritten = 0;
+ }
+ nwritten = (ssize_t)stream->upload_blocked_len;
+ stream->upload_blocked_len = 0;
+ }
+ else {
+ /* If stream_id != -1, we have dispatched request HEADERS and
+ * optionally request body, and now are going to send or sending
+ * more request body in DATA frame */
+ nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err);
+ if(nwritten < 0) {
+ if(*err != CURLE_AGAIN)
+ goto out;
+ nwritten = 0;
+ }
}
- DEBUGF(LOG_CF(data, cf, "[h2sid=%u] bufq_write(len=%zu) -> %zd, %d",
- stream->id, len, nwritten, *err));
if(!Curl_bufq_is_empty(&stream->sendbuf)) {
+ /* req body data is buffered, resume the potentially suspended stream */
rv = nghttp2_session_resume_data(ctx->h2, stream->id);
if(nghttp2_is_fatal(rv)) {
*err = CURLE_SEND_ERROR;
@@ -2026,104 +2110,93 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
goto out;
}
}
-
- result = h2_progress_ingress(cf, data);
- if(result) {
- *err = result;
- nwritten = -1;
- goto out;
- }
-
- result = h2_progress_egress(cf, data);
- if(result) {
- *err = result;
- nwritten = -1;
- goto out;
- }
-
- if(should_close_session(ctx)) {
- if(stream->closed) {
- nwritten = http2_handle_stream_close(cf, data, stream, err);
- }
- else {
- DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
- *err = CURLE_HTTP2;
- nwritten = -1;
- }
- goto out;
- }
-
- if(!nwritten) {
- size_t rwin = nghttp2_session_get_stream_remote_window_size(ctx->h2,
- stream->id);
- DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send: win %u/%zu",
- stream->id,
- nghttp2_session_get_remote_window_size(ctx->h2), rwin));
- if(rwin == 0) {
- /* We cannot upload more as the stream's remote window size
- * is 0. We need to receive WIN_UPDATEs before we can continue.
- */
- data->req.keepon |= KEEP_SEND_HOLD;
- DEBUGF(LOG_CF(data, cf, "[h2sid=%d] holding send as remote flow "
- "window is exhausted", stream->id));
- }
- nwritten = -1;
- *err = CURLE_AGAIN;
- }
- /* handled writing BODY for open stream. */
- goto out;
}
else {
nwritten = h2_submit(&stream, cf, data, buf, len, err);
if(nwritten < 0) {
goto out;
}
+ DEBUGASSERT(stream);
+ }
- result = h2_progress_ingress(cf, data);
- if(result) {
- *err = result;
- nwritten = -1;
- goto out;
+ /* Call the nghttp2 send loop and flush to write ALL buffered data,
+ * headers and/or request body completely out to the network */
+ result = h2_progress_egress(cf, data);
+ if(result == CURLE_AGAIN) {
+ blocked = 1;
+ }
+ else if(result) {
+ *err = result;
+ nwritten = -1;
+ goto out;
+ }
+ else if(!Curl_bufq_is_empty(&stream->sendbuf)) {
+ /* although we wrote everything that nghttp2 wants to send now,
+ * there is data left in our stream send buffer unwritten. This may
+ * be due to the stream's HTTP/2 flow window being exhausted. */
+ blocked = 1;
+ }
+
+ if(blocked) {
+ /* Unable to send all data, due to connection blocked or H2 window
+ * exhaustion. Data is left in our stream buffer, or nghttp2's internal
+ * frame buffer or our network out buffer. */
+ size_t rwin = nghttp2_session_get_stream_remote_window_size(ctx->h2,
+ stream->id);
+ if(rwin == 0) {
+ /* H2 flow window exhaustion. We need to HOLD upload until we get
+ * a WINDOW_UPDATE from the server. */
+ data->req.keepon |= KEEP_SEND_HOLD;
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] holding send as remote flow "
+ "window is exhausted", stream->id));
+ }
+
+ /* Whatever the cause, we need to return CURL_EAGAIN for this call.
+ * We have unwritten state that needs us being invoked again and EAGAIN
+ * is the only way to ensure that. */
+ stream->upload_blocked_len = nwritten;
+ DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) BLOCK: win %u/%zu "
+ "blocked_len=%zu",
+ stream->id, len,
+ nghttp2_session_get_remote_window_size(ctx->h2), rwin,
+ nwritten));
+ *err = CURLE_AGAIN;
+ nwritten = -1;
+ goto out;
+ }
+ else if(should_close_session(ctx)) {
+ /* nghttp2 thinks this session is done. If the stream has not been
+ * closed, this is an error state for out transfer */
+ if(stream->closed) {
+ nwritten = http2_handle_stream_close(cf, data, stream, err);
}
-
- result = h2_progress_egress(cf, data);
- if(result) {
- *err = result;
+ else {
+ DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
+ *err = CURLE_HTTP2;
nwritten = -1;
- goto out;
- }
-
- if(should_close_session(ctx)) {
- if(stream->closed) {
- nwritten = http2_handle_stream_close(cf, data, stream, err);
- }
- else {
- DEBUGF(LOG_CF(data, cf, "send: nothing to do in this session"));
- *err = CURLE_HTTP2;
- nwritten = -1;
- }
- goto out;
}
}
out:
if(stream) {
DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_send(len=%zu) -> %zd, %d, "
- "buffered=%zu, upload_left=%zu, stream-window=%d, "
- "connection-window=%d",
+ "upload_left=%" CURL_FORMAT_CURL_OFF_T ", "
+ "h2 windows %d-%d (stream-conn), "
+ "buffers %zu-%zu (stream-conn)",
stream->id, len, nwritten, *err,
- Curl_bufq_len(&stream->sendbuf),
(ssize_t)stream->upload_left,
nghttp2_session_get_stream_remote_window_size(
ctx->h2, stream->id),
- nghttp2_session_get_remote_window_size(ctx->h2)));
- drain_stream(cf, data, stream);
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&stream->sendbuf),
+ Curl_bufq_len(&ctx->outbufq)));
}
else {
DEBUGF(LOG_CF(data, cf, "cf_send(len=%zu) -> %zd, %d, "
- "connection-window=%d",
+ "connection-window=%d, nw_send_buffer(%zu)",
len, nwritten, *err,
- nghttp2_session_get_remote_window_size(ctx->h2)));
+ nghttp2_session_get_remote_window_size(ctx->h2),
+ Curl_bufq_len(&ctx->outbufq)));
}
CF_DATA_RESTORE(cf, save);
return nwritten;
@@ -2241,8 +2314,7 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf,
DEBUGASSERT(data);
if(ctx && ctx->h2 && stream) {
- uint32_t window = !pause * H2_STREAM_WINDOW_SIZE;
- CURLcode result;
+ uint32_t window = pause? 0 : stream->local_window_size;
int rv = nghttp2_session_set_local_window_size(ctx->h2,
NGHTTP2_FLAG_NONE,
@@ -2257,10 +2329,8 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf,
if(!pause)
drain_stream(cf, data, stream);
- /* make sure the window update gets sent */
- result = h2_progress_egress(cf, data);
- if(result)
- return result;
+ /* attempt to send the window update */
+ (void)h2_progress_egress(cf, data);
if(!pause) {
/* Unpausing a h2 transfer, requires it to be run again. The server
@@ -2510,7 +2580,7 @@ CURLcode Curl_http2_switch(struct Curl_easy *data,
CURLcode result;
DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex));
- DEBUGF(infof(data, DMSGI(data, sockindex, "switching to HTTP/2")));
+ DEBUGF(infof(data, "switching to HTTP/2"));
result = http2_cfilter_add(&cf, data, conn, sockindex);
if(result)
@@ -2569,7 +2639,7 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data,
CURLcode result;
DEBUGASSERT(!Curl_conn_is_http2(data, conn, sockindex));
- DEBUGF(infof(data, DMSGI(data, sockindex, "upgrading to HTTP/2")));
+ DEBUGF(infof(data, "upgrading to HTTP/2"));
DEBUGASSERT(data->req.upgr101 == UPGR101_RECEIVED);
result = http2_cfilter_add(&cf, data, conn, sockindex);
diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c
index b2eb1b2d85..1e0c506f1c 100644
--- a/libs/libcurl/src/imap.c
+++ b/libs/libcurl/src/imap.c
@@ -385,11 +385,11 @@ static CURLcode imap_get_message(struct Curl_easy *data, struct bufref *out)
/***********************************************************************
*
- * state()
+ * imap_state()
*
* This is the ONLY way to change IMAP state!
*/
-static void state(struct Curl_easy *data, imapstate newstate)
+static void imap_state(struct Curl_easy *data, imapstate newstate)
{
struct imap_conn *imapc = &data->conn->proto.imapc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -441,7 +441,7 @@ static CURLcode imap_perform_capability(struct Curl_easy *data,
result = imap_sendf(data, "CAPABILITY");
if(!result)
- state(data, IMAP_CAPABILITY);
+ imap_state(data, IMAP_CAPABILITY);
return result;
}
@@ -458,7 +458,7 @@ static CURLcode imap_perform_starttls(struct Curl_easy *data)
CURLcode result = imap_sendf(data, "STARTTLS");
if(!result)
- state(data, IMAP_STARTTLS);
+ imap_state(data, IMAP_STARTTLS);
return result;
}
@@ -487,7 +487,7 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
if(!result) {
imapc->ssldone = ssldone;
if(imapc->state != IMAP_UPGRADETLS)
- state(data, IMAP_UPGRADETLS);
+ imap_state(data, IMAP_UPGRADETLS);
if(imapc->ssldone) {
imap_to_imaps(conn);
@@ -514,7 +514,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!data->state.aptr.user) {
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -531,7 +531,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
free(passwd);
if(!result)
- state(data, IMAP_LOGIN);
+ imap_state(data, IMAP_LOGIN);
return result;
}
@@ -615,7 +615,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
with and end the connect phase if we don't */
if(imapc->preauth ||
!Curl_sasl_can_authenticate(&imapc->sasl, data)) {
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -624,7 +624,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
if(!result) {
if(progress == SASL_INPROGRESS)
- state(data, IMAP_AUTHENTICATE);
+ imap_state(data, IMAP_AUTHENTICATE);
else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
/* Perform clear text authentication */
result = imap_perform_login(data, conn);
@@ -667,7 +667,7 @@ static CURLcode imap_perform_list(struct Curl_easy *data)
}
if(!result)
- state(data, IMAP_LIST);
+ imap_state(data, IMAP_LIST);
return result;
}
@@ -707,7 +707,7 @@ static CURLcode imap_perform_select(struct Curl_easy *data)
free(mailbox);
if(!result)
- state(data, IMAP_SELECT);
+ imap_state(data, IMAP_SELECT);
return result;
}
@@ -749,7 +749,7 @@ static CURLcode imap_perform_fetch(struct Curl_easy *data)
return CURLE_URL_MALFORMAT;
}
if(!result)
- state(data, IMAP_FETCH);
+ imap_state(data, IMAP_FETCH);
return result;
}
@@ -820,7 +820,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data)
free(mailbox);
if(!result)
- state(data, IMAP_APPEND);
+ imap_state(data, IMAP_APPEND);
return result;
}
@@ -846,7 +846,7 @@ static CURLcode imap_perform_search(struct Curl_easy *data)
result = imap_sendf(data, "SEARCH %s", imap->query);
if(!result)
- state(data, IMAP_SEARCH);
+ imap_state(data, IMAP_SEARCH);
return result;
}
@@ -863,7 +863,7 @@ static CURLcode imap_perform_logout(struct Curl_easy *data)
CURLcode result = imap_sendf(data, "LOGOUT");
if(!result)
- state(data, IMAP_LOGOUT);
+ imap_state(data, IMAP_LOGOUT);
return result;
}
@@ -1017,7 +1017,7 @@ static CURLcode imap_state_auth_resp(struct Curl_easy *data,
if(!result)
switch(progress) {
case SASL_DONE:
- state(data, IMAP_STOP); /* Authenticated */
+ imap_state(data, IMAP_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
@@ -1049,7 +1049,7 @@ static CURLcode imap_state_login_resp(struct Curl_easy *data,
}
else
/* End of connect phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1075,7 +1075,7 @@ static CURLcode imap_state_listsearch_resp(struct Curl_easy *data,
result = CURLE_QUOTE_ERROR;
else
/* End of DO phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1143,7 +1143,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
if(imapcode != '*') {
Curl_pgrsSetDownloadSize(data, -1);
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return CURLE_REMOTE_FILE_NOT_FOUND;
}
@@ -1178,7 +1178,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
if(!chunk) {
/* no size, we're done with the data */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return CURLE_OK;
}
result = Curl_client_write(data, CLIENTWRITE_BODY, pp->cache, chunk);
@@ -1224,7 +1224,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
}
/* End of DO phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1242,7 +1242,7 @@ static CURLcode imap_state_fetch_final_resp(struct Curl_easy *data,
result = CURLE_WEIRD_SERVER_REPLY;
else
/* End of DONE phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1265,7 +1265,7 @@ static CURLcode imap_state_append_resp(struct Curl_easy *data, int imapcode,
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
}
return result;
@@ -1284,7 +1284,7 @@ static CURLcode imap_state_append_final_resp(struct Curl_easy *data,
result = CURLE_UPLOAD_FAILED;
else
/* End of DONE phase */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
return result;
}
@@ -1372,7 +1372,7 @@ static CURLcode imap_statemachine(struct Curl_easy *data,
/* fallthrough, just stop! */
default:
/* internal error */
- state(data, IMAP_STOP);
+ imap_state(data, IMAP_STOP);
break;
}
} while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
@@ -1475,7 +1475,7 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done)
return result;
/* Start off waiting for the server greeting response */
- state(data, IMAP_SERVERGREET);
+ imap_state(data, IMAP_SERVERGREET);
/* Start off with an response id of '*' */
strcpy(imapc->resptag, "*");
@@ -1516,12 +1516,12 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
/* Handle responses after FETCH or APPEND transfer has finished */
if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
- state(data, IMAP_FETCH_FINAL);
+ imap_state(data, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
result = Curl_pp_sendf(data, &conn->proto.imapc.pp, "%s", "");
if(!result)
- state(data, IMAP_APPEND_FINAL);
+ imap_state(data, IMAP_APPEND_FINAL);
}
/* Run the state-machine */
@@ -1777,7 +1777,7 @@ static CURLcode imap_sendf(struct Curl_easy *data, const char *fmt, ...)
/* Calculate the tag based on the connection ID and command ID */
msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
- 'A' + curlx_sltosi(data->conn->connection_id % 26),
+ 'A' + curlx_sltosi((long)(data->conn->connection_id % 26)),
++imapc->cmdid);
/* start with a blank buffer */
@@ -1925,6 +1925,7 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
const char *ptr = conn->options;
+ bool prefer_login = false;
while(!result && ptr && *ptr) {
const char *key = ptr;
@@ -1938,26 +1939,39 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
while(*ptr && *ptr != ';')
ptr++;
- if(strncasecompare(key, "AUTH=", 5))
+ if(strncasecompare(key, "AUTH=+LOGIN", 11)) {
+ /* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */
+ prefer_login = true;
+ imapc->sasl.prefmech = SASL_AUTH_NONE;
+ }
+ else if(strncasecompare(key, "AUTH=", 5)) {
+ prefer_login = false;
result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
value, ptr - value);
- else
+ }
+ else {
+ prefer_login = false;
result = CURLE_URL_MALFORMAT;
+ }
if(*ptr == ';')
ptr++;
}
- switch(imapc->sasl.prefmech) {
- case SASL_AUTH_NONE:
- imapc->preftype = IMAP_TYPE_NONE;
- break;
- case SASL_AUTH_DEFAULT:
- imapc->preftype = IMAP_TYPE_ANY;
- break;
- default:
- imapc->preftype = IMAP_TYPE_SASL;
- break;
+ if(prefer_login)
+ imapc->preftype = IMAP_TYPE_CLEARTEXT;
+ else {
+ switch(imapc->sasl.prefmech) {
+ case SASL_AUTH_NONE:
+ imapc->preftype = IMAP_TYPE_NONE;
+ break;
+ case SASL_AUTH_DEFAULT:
+ imapc->preftype = IMAP_TYPE_ANY;
+ break;
+ default:
+ imapc->preftype = IMAP_TYPE_SASL;
+ break;
+ }
}
return result;
diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c
index 856bc7464f..7c9e8da7ba 100644
--- a/libs/libcurl/src/krb5.c
+++ b/libs/libcurl/src/krb5.c
@@ -261,7 +261,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
}
/* We pass NULL as |output_name_type| to avoid a leak. */
gss_display_name(&min, gssname, &output_buffer, NULL);
- infof(data, "Trying against %s", output_buffer.value);
+ infof(data, "Trying against %s", (char *)output_buffer.value);
gssresp = GSS_C_NO_BUFFER;
*context = GSS_C_NO_CONTEXT;
diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c
index 7ed9412062..721c3a6f39 100644
--- a/libs/libcurl/src/ldap.c
+++ b/libs/libcurl/src/ldap.c
@@ -50,6 +50,14 @@
#endif
#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */
+# ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4201)
+# endif
+# include <subauth.h> /* for [P]UNICODE_STRING */
+# ifdef _MSC_VER
+# pragma warning(pop)
+# endif
# include <winldap.h>
# ifndef LDAP_VENDOR_NAME
# error Your Platform SDK is NOT sufficient for LDAP support! \
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index c9bb668381..20247bd436 100644
--- a/libs/libcurl/src/libcurl.plist
+++ b/libs/libcurl/src/libcurl.plist
@@ -15,7 +15,7 @@
<string>se.curl.libcurl</string>
<key>CFBundleVersion</key>
- <string>8.1.2</string>
+ <string>8.2.0</string>
<key>CFBundleName</key>
<string>libcurl</string>
@@ -27,9 +27,9 @@
<string>????</string>
<key>CFBundleShortVersionString</key>
- <string>libcurl 8.1.2</string>
+ <string>libcurl 8.2.0</string>
<key>CFBundleGetInfoString</key>
- <string>libcurl.plist 8.1.2</string>
+ <string>libcurl.plist 8.2.0</string>
</dict>
</plist>
diff --git a/libs/libcurl/src/macos.c b/libs/libcurl/src/macos.c
new file mode 100644
index 0000000000..d316effc5a
--- /dev/null
+++ b/libs/libcurl/src/macos.c
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__APPLE__)
+
+#if !defined(TARGET_OS_OSX) || TARGET_OS_OSX
+
+#include <curl/curl.h>
+
+#include "macos.h"
+
+#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
+#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
+#endif
+
+CURLcode Curl_macos_init(void)
+{
+#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
+ {
+ /*
+ * The automagic conversion from IPv4 literals to IPv6 literals only
+ * works if the SCDynamicStoreCopyProxies system function gets called
+ * first. As Curl currently doesn't support system-wide HTTP proxies, we
+ * therefore don't use any value this function might return.
+ *
+ * This function is only available on a macOS and is not needed for
+ * IPv4-only builds, hence the conditions above.
+ */
+ CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
+ if(dict)
+ CFRelease(dict);
+ }
+#endif
+ return CURLE_OK;
+}
+
+#endif /* TARGET_OS_OSX */
+
+#endif /* __APPLE__ */
diff --git a/libs/libcurl/src/macos.h b/libs/libcurl/src/macos.h
new file mode 100644
index 0000000000..f57b49538e
--- /dev/null
+++ b/libs/libcurl/src/macos.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_MACOS_H
+#define HEADER_CURL_MACOS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(__APPLE__) && (!defined(TARGET_OS_OSX) || TARGET_OS_OSX)
+
+CURLcode Curl_macos_init(void);
+
+#else
+
+#define Curl_macos_init() CURLE_OK
+
+#endif
+
+#endif /* HEADER_CURL_MACOS_H */
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index 5cb20679a4..3e47aee65a 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.c
@@ -84,7 +84,7 @@ static const struct mime_encoder encoders[] = {
};
/* Base64 encoding table */
-static const char base64[] =
+static const char base64enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* Quoted-printable character class table.
@@ -469,10 +469,10 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
i = st->buf[st->bufbeg++] & 0xFF;
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
- *ptr++ = base64[(i >> 18) & 0x3F];
- *ptr++ = base64[(i >> 12) & 0x3F];
- *ptr++ = base64[(i >> 6) & 0x3F];
- *ptr++ = base64[i & 0x3F];
+ *ptr++ = base64enc[(i >> 18) & 0x3F];
+ *ptr++ = base64enc[(i >> 12) & 0x3F];
+ *ptr++ = base64enc[(i >> 6) & 0x3F];
+ *ptr++ = base64enc[i & 0x3F];
cursize += 4;
st->pos += 4;
size -= 4;
@@ -496,10 +496,10 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
i |= (st->buf[st->bufbeg] & 0xFF) << 16;
- ptr[0] = base64[(i >> 18) & 0x3F];
- ptr[1] = base64[(i >> 12) & 0x3F];
+ ptr[0] = base64enc[(i >> 18) & 0x3F];
+ ptr[1] = base64enc[(i >> 12) & 0x3F];
if(++st->bufbeg != st->bufend) {
- ptr[2] = base64[(i >> 6) & 0x3F];
+ ptr[2] = base64enc[(i >> 6) & 0x3F];
st->bufbeg++;
}
cursize += 4;
diff --git a/libs/libcurl/src/mqtt.c b/libs/libcurl/src/mqtt.c
index 0ab7c6467e..cd72c5015e 100644
--- a/libs/libcurl/src/mqtt.c
+++ b/libs/libcurl/src/mqtt.c
@@ -636,7 +636,7 @@ MQTT_SUBACK_COMING:
/* -- switched state -- */
remlen = mq->remaining_length;
- infof(data, "Remaining length: %zd bytes", remlen);
+ infof(data, "Remaining length: %zu bytes", remlen);
if(data->set.max_filesize &&
(curl_off_t)remlen > data->set.max_filesize) {
failf(data, "Maximum file size exceeded");
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index a24d7dd5bb..6d9a39e937 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -112,7 +112,7 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
static void process_pending_handles(struct Curl_multi *multi);
#ifdef DEBUGBUILD
-static const char * const statename[]={
+static const char * const multi_statename[]={
"INIT",
"PENDING",
"CONNECT",
@@ -194,15 +194,10 @@ static void mstate(struct Curl_easy *data, CURLMstate state
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
if(data->mstate >= MSTATE_PENDING &&
data->mstate < MSTATE_COMPLETED) {
- long connection_id = -5000;
-
- if(data->conn)
- connection_id = data->conn->connection_id;
-
infof(data,
- "STATE: %s => %s handle %p; line %d (connection #%ld)",
- statename[oldstate], statename[data->mstate],
- (void *)data, lineno, connection_id);
+ "STATE: %s => %s handle %p; line %d",
+ multi_statename[oldstate], multi_statename[data->mstate],
+ (void *)data, lineno);
}
#endif
@@ -464,6 +459,20 @@ struct Curl_multi *curl_multi_init(void)
CURL_DNS_HASH_SIZE);
}
+#ifdef DEBUGBUILD
+static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
+{
+ if(!multi->warned) {
+ infof(data, "!!! WARNING !!!");
+ infof(data, "This is a debug build of libcurl, "
+ "do not use in production.");
+ multi->warned = true;
+ }
+}
+#else
+#define multi_warn_debug(x,y) Curl_nop_stmt
+#endif
+
/* returns TRUE if the easy handle is supposed to be present in the main link
list */
static bool in_main_list(struct Curl_easy *data)
@@ -623,8 +632,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->set.server_response_timeout;
data->state.conn_cache->closure_handle->set.no_signal =
data->set.no_signal;
+ data->id = data->state.conn_cache->next_easy_id++;
+ if(data->state.conn_cache->next_easy_id <= 0)
+ data->state.conn_cache->next_easy_id = 0;
CONNCACHE_UNLOCK(data);
+ multi_warn_debug(multi, data);
+ infof(data, "processing: %s", data->state.url);
+
return CURLM_OK;
}
@@ -742,6 +757,7 @@ static CURLcode multi_done(struct Curl_easy *data,
but currently we have no such detail knowledge.
*/
+ data->state.recent_conn_id = conn->connection_id;
if((data->set.reuse_forbid
#if defined(USE_NTLM)
&& !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
@@ -753,8 +769,9 @@ static CURLcode multi_done(struct Curl_easy *data,
#endif
) || conn->bits.close
|| (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) {
- DEBUGF(infof(data, "multi_done, not re-using connection=%ld, forbid=%d"
- ", close=%d, premature=%d, conn_multiplex=%d",
+ DEBUGF(infof(data, "multi_done, not re-using connection=%"
+ CURL_FORMAT_CURL_OFF_T ", forbid=%d"
+ ", close=%d, premature=%d, conn_multiplex=%d",
conn->connection_id,
data->set.reuse_forbid, conn->bits.close, premature,
Curl_conn_is_multiplex(conn, FIRSTSOCKET)));
@@ -774,15 +791,16 @@ static CURLcode multi_done(struct Curl_easy *data,
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname;
/* create string before returning the connection */
- long connection_id = conn->connection_id;
+ curl_off_t connection_id = conn->connection_id;
msnprintf(buffer, sizeof(buffer),
- "Connection #%ld to host %s left intact",
+ "Connection #%" CURL_FORMAT_CURL_OFF_T " to host %s left intact",
connection_id, host);
/* the connection is no longer in use by this transfer */
CONNCACHE_UNLOCK(data);
if(Curl_conncache_return_conn(data, conn)) {
/* remember the most recently used connection */
data->state.lastconnect_id = connection_id;
+ data->state.recent_conn_id = connection_id;
infof(data, "%s", buffer);
}
else
@@ -1895,14 +1913,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, MSTATE_COMPLETED);
}
-#ifdef DEBUGBUILD
- if(!multi->warned) {
- infof(data, "!!! WARNING !!!");
- infof(data, "This is a debug build of libcurl, "
- "do not use in production.");
- multi->warned = true;
- }
-#endif
+ multi_warn_debug(multi, data);
do {
/* A "stream" here is a logical stream if the protocol can handle that
@@ -3690,7 +3701,7 @@ void Curl_expire_clear(struct Curl_easy *data)
}
#ifdef DEBUGBUILD
- infof(data, "Expire cleared (transfer %p)", data);
+ infof(data, "Expire cleared");
#endif
nowp->tv_sec = 0;
nowp->tv_usec = 0;
@@ -3798,7 +3809,7 @@ void Curl_multi_dump(struct Curl_multi *multi)
/* only display handles that are not completed */
fprintf(stderr, "handle %p, state %s, %d sockets\n",
(void *)data,
- statename[data->mstate], data->numsocks);
+ multi_statename[data->mstate], data->numsocks);
for(i = 0; i < data->numsocks; i++) {
curl_socket_t s = data->sockets[i];
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c
index 48c2a39d14..d19308dd32 100644
--- a/libs/libcurl/src/pop3.c
+++ b/libs/libcurl/src/pop3.c
@@ -282,11 +282,11 @@ static CURLcode pop3_get_message(struct Curl_easy *data, struct bufref *out)
/***********************************************************************
*
- * state()
+ * pop3_state()
*
* This is the ONLY way to change POP3 state!
*/
-static void state(struct Curl_easy *data, pop3state newstate)
+static void pop3_state(struct Curl_easy *data, pop3state newstate)
{
struct pop3_conn *pop3c = &data->conn->proto.pop3c;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -335,7 +335,7 @@ static CURLcode pop3_perform_capa(struct Curl_easy *data,
result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA");
if(!result)
- state(data, POP3_CAPA);
+ pop3_state(data, POP3_CAPA);
return result;
}
@@ -353,7 +353,7 @@ static CURLcode pop3_perform_starttls(struct Curl_easy *data,
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "STLS");
if(!result)
- state(data, POP3_STARTTLS);
+ pop3_state(data, POP3_STARTTLS);
return result;
}
@@ -383,7 +383,7 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
if(!result) {
pop3c->ssldone = ssldone;
if(pop3c->state != POP3_UPGRADETLS)
- state(data, POP3_UPGRADETLS);
+ pop3_state(data, POP3_UPGRADETLS);
if(pop3c->ssldone) {
pop3_to_pop3s(conn);
@@ -408,7 +408,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!data->state.aptr.user) {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -417,7 +417,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "USER %s",
conn->user ? conn->user : "");
if(!result)
- state(data, POP3_USER);
+ pop3_state(data, POP3_USER);
return result;
}
@@ -442,7 +442,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
if(!data->state.aptr.user) {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -468,7 +468,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
if(!result)
- state(data, POP3_APOP);
+ pop3_state(data, POP3_APOP);
return result;
}
@@ -552,7 +552,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
/* Check we have enough data to authenticate with and end the
connect phase if we don't */
if(!Curl_sasl_can_authenticate(&pop3c->sasl, data)) {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -562,7 +562,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
if(!result)
if(progress == SASL_INPROGRESS)
- state(data, POP3_AUTH);
+ pop3_state(data, POP3_AUTH);
}
if(!result && progress == SASL_IDLE) {
@@ -620,7 +620,7 @@ static CURLcode pop3_perform_command(struct Curl_easy *data)
pop3->custom : command));
if(!result)
- state(data, POP3_COMMAND);
+ pop3_state(data, POP3_COMMAND);
return result;
}
@@ -638,7 +638,7 @@ static CURLcode pop3_perform_quit(struct Curl_easy *data,
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "QUIT");
if(!result)
- state(data, POP3_QUIT);
+ pop3_state(data, POP3_QUIT);
return result;
}
@@ -831,7 +831,7 @@ static CURLcode pop3_state_auth_resp(struct Curl_easy *data,
if(!result)
switch(progress) {
case SASL_DONE:
- state(data, POP3_STOP); /* Authenticated */
+ pop3_state(data, POP3_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
#ifndef CURL_DISABLE_CRYPTO_AUTH
@@ -869,7 +869,7 @@ static CURLcode pop3_state_apop_resp(struct Curl_easy *data, int pop3code,
}
else
/* End of connect phase */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -892,7 +892,7 @@ static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "PASS %s",
conn->passwd ? conn->passwd : "");
if(!result)
- state(data, POP3_PASS);
+ pop3_state(data, POP3_PASS);
return result;
}
@@ -910,7 +910,7 @@ static CURLcode pop3_state_pass_resp(struct Curl_easy *data, int pop3code,
}
else
/* End of connect phase */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -929,7 +929,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
(void)instate; /* no use for this yet */
if(pop3code != '+') {
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return CURLE_WEIRD_SERVER_REPLY;
}
@@ -967,7 +967,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
}
/* End of DO phase */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
return result;
}
@@ -1037,12 +1037,12 @@ static CURLcode pop3_statemachine(struct Curl_easy *data,
break;
case POP3_QUIT:
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
break;
default:
/* internal error */
- state(data, POP3_STOP);
+ pop3_state(data, POP3_STOP);
break;
}
} while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
@@ -1143,7 +1143,7 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done)
return result;
/* Start off waiting for the server greeting response */
- state(data, POP3_SERVERGREET);
+ pop3_state(data, POP3_SERVERGREET);
result = pop3_multi_statemach(data, done);
diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c
index 78645780d2..568493d56b 100644
--- a/libs/libcurl/src/sendf.c
+++ b/libs/libcurl/src/sendf.c
@@ -419,8 +419,6 @@ CURLcode Curl_read(struct Curl_easy *data, /* transfer */
*n += nread;
result = CURLE_OK;
out:
- /* DEBUGF(infof(data, "Curl_read(handle=%p) -> %d, nread=%ld",
- data, result, nread)); */
return result;
}
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index c14ea491cd..029fb341ac 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -1867,6 +1867,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
*/
data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
+ case CURLOPT_HAPROXY_CLIENT_IP:
+ /*
+ * Set the client IP to send through HAProxy PROXY protocol
+ */
+ result = Curl_setstropt(&data->set.str[STRING_HAPROXY_CLIENT_IP],
+ va_arg(param, char *));
+ /* We enable implicitly the HAProxy protocol if we use this flag. */
+ data->set.haproxyprotocol = TRUE;
+ break;
#endif
case CURLOPT_INTERFACE:
/*
@@ -2711,7 +2720,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
/* Set the list of mail recipients */
data->set.mail_rcpt = va_arg(param, struct curl_slist *);
break;
- case CURLOPT_MAIL_RCPT_ALLLOWFAILS:
+ case CURLOPT_MAIL_RCPT_ALLOWFAILS:
/* allow RCPT TO command to fail for some recipients */
data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c
index 0bcd779881..c1e3f9d593 100644
--- a/libs/libcurl/src/smb.c
+++ b/libs/libcurl/src/smb.c
@@ -27,8 +27,6 @@
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
-#define BUILDING_CURL_SMB_C
-
#ifdef WIN32
#define getpid GetCurrentProcessId
#endif
@@ -50,6 +48,199 @@
#include "curl_memory.h"
#include "memdebug.h"
+/*
+ * Definitions for SMB protocol data structures
+ */
+#if defined(_MSC_VER) || defined(__ILEC400__)
+# define PACK
+# pragma pack(push)
+# pragma pack(1)
+#elif defined(__GNUC__)
+# define PACK __attribute__((packed))
+#else
+# define PACK
+#endif
+
+#define SMB_COM_CLOSE 0x04
+#define SMB_COM_READ_ANDX 0x2e
+#define SMB_COM_WRITE_ANDX 0x2f
+#define SMB_COM_TREE_DISCONNECT 0x71
+#define SMB_COM_NEGOTIATE 0x72
+#define SMB_COM_SETUP_ANDX 0x73
+#define SMB_COM_TREE_CONNECT_ANDX 0x75
+#define SMB_COM_NT_CREATE_ANDX 0xa2
+#define SMB_COM_NO_ANDX_COMMAND 0xff
+
+#define SMB_WC_CLOSE 0x03
+#define SMB_WC_READ_ANDX 0x0c
+#define SMB_WC_WRITE_ANDX 0x0e
+#define SMB_WC_SETUP_ANDX 0x0d
+#define SMB_WC_TREE_CONNECT_ANDX 0x04
+#define SMB_WC_NT_CREATE_ANDX 0x18
+
+#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
+#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
+#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
+#define SMB_FLAGS2_IS_LONG_NAME 0x0040
+#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
+
+#define SMB_CAP_LARGE_FILES 0x08
+#define SMB_GENERIC_WRITE 0x40000000
+#define SMB_GENERIC_READ 0x80000000
+#define SMB_FILE_SHARE_ALL 0x07
+#define SMB_FILE_OPEN 0x01
+#define SMB_FILE_OVERWRITE_IF 0x05
+
+#define SMB_ERR_NOACCESS 0x00050001
+
+struct smb_header {
+ unsigned char nbt_type;
+ unsigned char nbt_flags;
+ unsigned short nbt_length;
+ unsigned char magic[4];
+ unsigned char command;
+ unsigned int status;
+ unsigned char flags;
+ unsigned short flags2;
+ unsigned short pid_high;
+ unsigned char signature[8];
+ unsigned short pad;
+ unsigned short tid;
+ unsigned short pid;
+ unsigned short uid;
+ unsigned short mid;
+} PACK;
+
+struct smb_negotiate_response {
+ struct smb_header h;
+ unsigned char word_count;
+ unsigned short dialect_index;
+ unsigned char security_mode;
+ unsigned short max_mpx_count;
+ unsigned short max_number_vcs;
+ unsigned int max_buffer_size;
+ unsigned int max_raw_size;
+ unsigned int session_key;
+ unsigned int capabilities;
+ unsigned int system_time_low;
+ unsigned int system_time_high;
+ unsigned short server_time_zone;
+ unsigned char encryption_key_length;
+ unsigned short byte_count;
+ char bytes[1];
+} PACK;
+
+struct andx {
+ unsigned char command;
+ unsigned char pad;
+ unsigned short offset;
+} PACK;
+
+struct smb_setup {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short max_buffer_size;
+ unsigned short max_mpx_count;
+ unsigned short vc_number;
+ unsigned int session_key;
+ unsigned short lengths[2];
+ unsigned int pad;
+ unsigned int capabilities;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_tree_connect {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short flags;
+ unsigned short pw_len;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_nt_create {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned char pad;
+ unsigned short name_length;
+ unsigned int flags;
+ unsigned int root_fid;
+ unsigned int access;
+ curl_off_t allocation_size;
+ unsigned int ext_file_attributes;
+ unsigned int share_access;
+ unsigned int create_disposition;
+ unsigned int create_options;
+ unsigned int impersonation_level;
+ unsigned char security_flags;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_nt_create_response {
+ struct smb_header h;
+ unsigned char word_count;
+ struct andx andx;
+ unsigned char op_lock_level;
+ unsigned short fid;
+ unsigned int create_disposition;
+
+ curl_off_t create_time;
+ curl_off_t last_access_time;
+ curl_off_t last_write_time;
+ curl_off_t last_change_time;
+ unsigned int ext_file_attributes;
+ curl_off_t allocation_size;
+ curl_off_t end_of_file;
+} PACK;
+
+struct smb_read {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short fid;
+ unsigned int offset;
+ unsigned short max_bytes;
+ unsigned short min_bytes;
+ unsigned int timeout;
+ unsigned short remaining;
+ unsigned int offset_high;
+ unsigned short byte_count;
+} PACK;
+
+struct smb_write {
+ struct smb_header h;
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short fid;
+ unsigned int offset;
+ unsigned int timeout;
+ unsigned short write_mode;
+ unsigned short remaining;
+ unsigned short pad;
+ unsigned short data_length;
+ unsigned short data_offset;
+ unsigned int offset_high;
+ unsigned short byte_count;
+ unsigned char pad2;
+} PACK;
+
+struct smb_close {
+ unsigned char word_count;
+ unsigned short fid;
+ unsigned int last_mtime;
+ unsigned short byte_count;
+} PACK;
+
+struct smb_tree_disconnect {
+ unsigned char word_count;
+ unsigned short byte_count;
+} PACK;
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+# pragma pack(pop)
+#endif
+
/* Local API functions */
static CURLcode smb_setup_connection(struct Curl_easy *data,
struct connectdata *conn);
diff --git a/libs/libcurl/src/smb.h b/libs/libcurl/src/smb.h
index 0e6b069e6b..3947b43382 100644
--- a/libs/libcurl/src/smb.h
+++ b/libs/libcurl/src/smb.h
@@ -48,203 +48,6 @@ struct smb_conn {
size_t got;
};
-/*
- * Definitions for SMB protocol data structures
- */
-#ifdef BUILDING_CURL_SMB_C
-
-#if defined(_MSC_VER) || defined(__ILEC400__)
-# define PACK
-# pragma pack(push)
-# pragma pack(1)
-#elif defined(__GNUC__)
-# define PACK __attribute__((packed))
-#else
-# define PACK
-#endif
-
-#define SMB_COM_CLOSE 0x04
-#define SMB_COM_READ_ANDX 0x2e
-#define SMB_COM_WRITE_ANDX 0x2f
-#define SMB_COM_TREE_DISCONNECT 0x71
-#define SMB_COM_NEGOTIATE 0x72
-#define SMB_COM_SETUP_ANDX 0x73
-#define SMB_COM_TREE_CONNECT_ANDX 0x75
-#define SMB_COM_NT_CREATE_ANDX 0xa2
-#define SMB_COM_NO_ANDX_COMMAND 0xff
-
-#define SMB_WC_CLOSE 0x03
-#define SMB_WC_READ_ANDX 0x0c
-#define SMB_WC_WRITE_ANDX 0x0e
-#define SMB_WC_SETUP_ANDX 0x0d
-#define SMB_WC_TREE_CONNECT_ANDX 0x04
-#define SMB_WC_NT_CREATE_ANDX 0x18
-
-#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
-#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
-#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
-#define SMB_FLAGS2_IS_LONG_NAME 0x0040
-#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
-
-#define SMB_CAP_LARGE_FILES 0x08
-#define SMB_GENERIC_WRITE 0x40000000
-#define SMB_GENERIC_READ 0x80000000
-#define SMB_FILE_SHARE_ALL 0x07
-#define SMB_FILE_OPEN 0x01
-#define SMB_FILE_OVERWRITE_IF 0x05
-
-#define SMB_ERR_NOACCESS 0x00050001
-
-struct smb_header {
- unsigned char nbt_type;
- unsigned char nbt_flags;
- unsigned short nbt_length;
- unsigned char magic[4];
- unsigned char command;
- unsigned int status;
- unsigned char flags;
- unsigned short flags2;
- unsigned short pid_high;
- unsigned char signature[8];
- unsigned short pad;
- unsigned short tid;
- unsigned short pid;
- unsigned short uid;
- unsigned short mid;
-} PACK;
-
-struct smb_negotiate_response {
- struct smb_header h;
- unsigned char word_count;
- unsigned short dialect_index;
- unsigned char security_mode;
- unsigned short max_mpx_count;
- unsigned short max_number_vcs;
- unsigned int max_buffer_size;
- unsigned int max_raw_size;
- unsigned int session_key;
- unsigned int capabilities;
- unsigned int system_time_low;
- unsigned int system_time_high;
- unsigned short server_time_zone;
- unsigned char encryption_key_length;
- unsigned short byte_count;
- char bytes[1];
-} PACK;
-
-struct andx {
- unsigned char command;
- unsigned char pad;
- unsigned short offset;
-} PACK;
-
-struct smb_setup {
- unsigned char word_count;
- struct andx andx;
- unsigned short max_buffer_size;
- unsigned short max_mpx_count;
- unsigned short vc_number;
- unsigned int session_key;
- unsigned short lengths[2];
- unsigned int pad;
- unsigned int capabilities;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_tree_connect {
- unsigned char word_count;
- struct andx andx;
- unsigned short flags;
- unsigned short pw_len;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_nt_create {
- unsigned char word_count;
- struct andx andx;
- unsigned char pad;
- unsigned short name_length;
- unsigned int flags;
- unsigned int root_fid;
- unsigned int access;
- curl_off_t allocation_size;
- unsigned int ext_file_attributes;
- unsigned int share_access;
- unsigned int create_disposition;
- unsigned int create_options;
- unsigned int impersonation_level;
- unsigned char security_flags;
- unsigned short byte_count;
- char bytes[1024];
-} PACK;
-
-struct smb_nt_create_response {
- struct smb_header h;
- unsigned char word_count;
- struct andx andx;
- unsigned char op_lock_level;
- unsigned short fid;
- unsigned int create_disposition;
-
- curl_off_t create_time;
- curl_off_t last_access_time;
- curl_off_t last_write_time;
- curl_off_t last_change_time;
- unsigned int ext_file_attributes;
- curl_off_t allocation_size;
- curl_off_t end_of_file;
-} PACK;
-
-struct smb_read {
- unsigned char word_count;
- struct andx andx;
- unsigned short fid;
- unsigned int offset;
- unsigned short max_bytes;
- unsigned short min_bytes;
- unsigned int timeout;
- unsigned short remaining;
- unsigned int offset_high;
- unsigned short byte_count;
-} PACK;
-
-struct smb_write {
- struct smb_header h;
- unsigned char word_count;
- struct andx andx;
- unsigned short fid;
- unsigned int offset;
- unsigned int timeout;
- unsigned short write_mode;
- unsigned short remaining;
- unsigned short pad;
- unsigned short data_length;
- unsigned short data_offset;
- unsigned int offset_high;
- unsigned short byte_count;
- unsigned char pad2;
-} PACK;
-
-struct smb_close {
- unsigned char word_count;
- unsigned short fid;
- unsigned int last_mtime;
- unsigned short byte_count;
-} PACK;
-
-struct smb_tree_disconnect {
- unsigned char word_count;
- unsigned short byte_count;
-} PACK;
-
-#if defined(_MSC_VER) || defined(__ILEC400__)
-# pragma pack(pop)
-#endif
-
-#endif /* BUILDING_CURL_SMB_C */
-
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
(SIZEOF_CURL_OFF_T > 4)
diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c
index 2b40c9249c..5109c90b93 100644
--- a/libs/libcurl/src/smtp.c
+++ b/libs/libcurl/src/smtp.c
@@ -281,11 +281,11 @@ static CURLcode smtp_get_message(struct Curl_easy *data, struct bufref *out)
/***********************************************************************
*
- * state()
+ * smtp_state()
*
* This is the ONLY way to change SMTP state!
*/
-static void state(struct Curl_easy *data, smtpstate newstate)
+static void smtp_state(struct Curl_easy *data, smtpstate newstate)
{
struct smtp_conn *smtpc = &data->conn->proto.smtpc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -338,7 +338,7 @@ static CURLcode smtp_perform_ehlo(struct Curl_easy *data)
result = Curl_pp_sendf(data, &smtpc->pp, "EHLO %s", smtpc->domain);
if(!result)
- state(data, SMTP_EHLO);
+ smtp_state(data, SMTP_EHLO);
return result;
}
@@ -362,7 +362,7 @@ static CURLcode smtp_perform_helo(struct Curl_easy *data,
result = Curl_pp_sendf(data, &smtpc->pp, "HELO %s", smtpc->domain);
if(!result)
- state(data, SMTP_HELO);
+ smtp_state(data, SMTP_HELO);
return result;
}
@@ -381,7 +381,7 @@ static CURLcode smtp_perform_starttls(struct Curl_easy *data,
"%s", "STARTTLS");
if(!result)
- state(data, SMTP_STARTTLS);
+ smtp_state(data, SMTP_STARTTLS);
return result;
}
@@ -410,7 +410,7 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
if(!result) {
smtpc->ssldone = ssldone;
if(smtpc->state != SMTP_UPGRADETLS)
- state(data, SMTP_UPGRADETLS);
+ smtp_state(data, SMTP_UPGRADETLS);
if(smtpc->ssldone) {
smtp_to_smtps(conn);
@@ -499,7 +499,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
server supports authentication, and end the connect phase if not */
if(!smtpc->auth_supported ||
!Curl_sasl_can_authenticate(&smtpc->sasl, data)) {
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
return result;
}
@@ -508,7 +508,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
if(!result) {
if(progress == SASL_INPROGRESS)
- state(data, SMTP_AUTH);
+ smtp_state(data, SMTP_AUTH);
else {
/* Other mechanisms not supported */
infof(data, "No known authentication mechanisms supported");
@@ -586,7 +586,7 @@ static CURLcode smtp_perform_command(struct Curl_easy *data)
smtp->custom : "HELP");
if(!result)
- state(data, SMTP_COMMAND);
+ smtp_state(data, SMTP_COMMAND);
return result;
}
@@ -771,7 +771,7 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data)
free(size);
if(!result)
- state(data, SMTP_MAIL);
+ smtp_state(data, SMTP_MAIL);
return result;
}
@@ -812,7 +812,7 @@ static CURLcode smtp_perform_rcpt_to(struct Curl_easy *data)
free(address);
if(!result)
- state(data, SMTP_RCPT);
+ smtp_state(data, SMTP_RCPT);
return result;
}
@@ -830,7 +830,7 @@ static CURLcode smtp_perform_quit(struct Curl_easy *data,
CURLcode result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "QUIT");
if(!result)
- state(data, SMTP_QUIT);
+ smtp_state(data, SMTP_QUIT);
return result;
}
@@ -996,7 +996,7 @@ static CURLcode smtp_state_helo_resp(struct Curl_easy *data, int smtpcode,
}
else
/* End of connect phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
return result;
}
@@ -1017,7 +1017,7 @@ static CURLcode smtp_state_auth_resp(struct Curl_easy *data,
if(!result)
switch(progress) {
case SASL_DONE:
- state(data, SMTP_STOP); /* Authenticated */
+ smtp_state(data, SMTP_STOP); /* Authenticated */
break;
case SASL_IDLE: /* No mechanism left after cancellation */
failf(data, "Authentication cancelled");
@@ -1064,11 +1064,11 @@ static CURLcode smtp_state_command_resp(struct Curl_easy *data, int smtpcode,
}
else
/* End of DO phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
}
else
/* End of DO phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
}
}
@@ -1145,7 +1145,7 @@ static CURLcode smtp_state_rcpt_resp(struct Curl_easy *data,
result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "DATA");
if(!result)
- state(data, SMTP_DATA);
+ smtp_state(data, SMTP_DATA);
}
}
}
@@ -1172,7 +1172,7 @@ static CURLcode smtp_state_data_resp(struct Curl_easy *data, int smtpcode,
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* End of DO phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
}
return result;
@@ -1192,7 +1192,7 @@ static CURLcode smtp_state_postdata_resp(struct Curl_easy *data,
result = CURLE_WEIRD_SERVER_REPLY;
/* End of DONE phase */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
return result;
}
@@ -1274,7 +1274,7 @@ static CURLcode smtp_statemachine(struct Curl_easy *data,
/* fallthrough, just stop! */
default:
/* internal error */
- state(data, SMTP_STOP);
+ smtp_state(data, SMTP_STOP);
break;
}
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
@@ -1379,7 +1379,7 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done)
return result;
/* Start off waiting for the server greeting response */
- state(data, SMTP_SERVERGREET);
+ smtp_state(data, SMTP_SERVERGREET);
result = smtp_multi_statemach(data, done);
@@ -1461,7 +1461,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
free(eob);
}
- state(data, SMTP_POSTDATA);
+ smtp_state(data, SMTP_POSTDATA);
/* Run the state-machine */
result = smtp_block_statemach(data, conn, FALSE);
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c
index 5a928b4fdd..a390d10f17 100644
--- a/libs/libcurl/src/socks.c
+++ b/libs/libcurl/src/socks.c
@@ -161,7 +161,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data,
enum connect_t oldstate = sx->state;
#ifdef DEBUG_AND_VERBOSE
/* synced with the state list in urldata.h */
- static const char * const statename[] = {
+ static const char * const socks_statename[] = {
"INIT",
"SOCKS_INIT",
"SOCKS_SEND",
@@ -193,7 +193,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data,
#ifdef DEBUG_AND_VERBOSE
infof(data,
"SXSTATE: %s => %s; line %d",
- statename[oldstate], statename[sx->state],
+ socks_statename[oldstate], socks_statename[sx->state],
lineno);
#endif
}
diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c
index 07ba21d807..e0d54b6c7a 100644
--- a/libs/libcurl/src/telnet.c
+++ b/libs/libcurl/src/telnet.c
@@ -1534,7 +1534,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
}
while(keepon) {
- DEBUGF(infof(data, "telnet_do(handle=%p), poll %d fds", data, poll_cnt));
+ DEBUGF(infof(data, "telnet_do, poll %d fds", poll_cnt));
switch(Curl_poll(pfd, poll_cnt, interval_ms)) {
case -1: /* error, stop reading */
keepon = FALSE;
@@ -1558,8 +1558,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
* in a clean way? Seems to be timing related, happens more
* on slow debug build */
if(data->state.os_errno == ECONNRESET) {
- DEBUGF(infof(data, "telnet_do(handle=%p), unexpected ECONNRESET"
- " on recv", data));
+ DEBUGF(infof(data, "telnet_do, unexpected ECONNRESET on recv"));
}
break;
}
diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c
index bc54d9b935..8f081be9c2 100644
--- a/libs/libcurl/src/timeval.c
+++ b/libs/libcurl/src/timeval.c
@@ -58,7 +58,8 @@ struct curltime Curl_now(void)
return now;
}
-#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) || \
+ defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
struct curltime Curl_now(void)
{
@@ -87,6 +88,19 @@ struct curltime Curl_now(void)
have_clock_gettime = TRUE;
#endif
+#ifdef HAVE_CLOCK_GETTIME_MONOTONIC_RAW
+ if(
+#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
+ (HAVE_BUILTIN_AVAILABLE == 1)
+ have_clock_gettime &&
+#endif
+ (0 == clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow))) {
+ cnow.tv_sec = tsnow.tv_sec;
+ cnow.tv_usec = (unsigned int)(tsnow.tv_nsec / 1000);
+ }
+ else
+#endif
+
if(
#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
(HAVE_BUILTIN_AVAILABLE == 1)
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index 0b561b6c2c..45c47e373c 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.c
@@ -428,6 +428,8 @@ static CURLcode readwrite_data(struct Curl_easy *data,
size_t excess = 0; /* excess bytes read */
bool readmore = FALSE; /* used by RTP to signal for more data */
int maxloops = 100;
+ curl_off_t max_recv = data->set.max_recv_speed?
+ data->set.max_recv_speed : CURL_OFF_T_MAX;
char *buf = data->state.buffer;
DEBUGASSERT(buf);
@@ -472,7 +474,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
else {
/* read nothing but since we wanted nothing we consider this an OK
situation to proceed from */
- DEBUGF(infof(data, DMSG(data, "readwrite_data: we're done")));
+ DEBUGF(infof(data, "readwrite_data: we're done"));
nread = 0;
}
@@ -666,6 +668,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
}
k->bytecount += nread;
+ max_recv -= nread;
Curl_pgrsSetDownloadCounter(data, k->bytecount);
@@ -749,9 +752,9 @@ static CURLcode readwrite_data(struct Curl_easy *data,
break;
}
- } while(data_pending(data) && maxloops--);
+ } while((max_recv > 0) && data_pending(data) && maxloops--);
- if(maxloops <= 0) {
+ if(maxloops <= 0 || max_recv <= 0) {
/* we mark it as read-again-please */
data->state.dselect_bits = CURL_CSELECT_IN;
*comeback = TRUE;
@@ -768,7 +771,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
out:
if(result)
- DEBUGF(infof(data, DMSG(data, "readwrite_data() -> %d"), result));
+ DEBUGF(infof(data, "readwrite_data() -> %d", result));
return result;
}
@@ -1233,7 +1236,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
*done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE;
out:
if(result)
- DEBUGF(infof(data, DMSG(data, "Curl_readwrite() -> %d"), result));
+ DEBUGF(infof(data, "Curl_readwrite() -> %d", result));
return result;
}
@@ -1551,10 +1554,15 @@ CURLcode Curl_follow(struct Curl_easy *data,
if((type != FOLLOW_RETRY) &&
(data->req.httpcode != 401) && (data->req.httpcode != 407) &&
- Curl_is_absolute_url(newurl, NULL, 0, FALSE))
+ Curl_is_absolute_url(newurl, NULL, 0, FALSE)) {
/* If this is not redirect due to a 401 or 407 response and an absolute
URL: don't allow a custom port number */
disallowport = TRUE;
+ if(!data->set.allow_auth_to_other_hosts) {
+ Curl_safefree(data->state.aptr.user);
+ Curl_safefree(data->state.aptr.passwd);
+ }
+ }
DEBUGASSERT(data->state.uh);
uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index c4e217a6be..79a2ad1d8e 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.c
@@ -659,6 +659,9 @@ CURLcode Curl_open(struct Curl_easy **curl)
/* most recent connection is not yet defined */
data->state.lastconnect_id = -1;
+ data->state.recent_conn_id = -1;
+ /* and not assigned an id yet */
+ data->id = -1;
data->progress.flags |= PGRS_HIDE;
data->state.current_speed = -1; /* init to negative == impossible */
@@ -680,7 +683,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
static void conn_shutdown(struct Curl_easy *data)
{
DEBUGASSERT(data);
- infof(data, "Closing connection %ld", data->conn->connection_id);
+ infof(data, "Closing connection");
/* possible left-overs from the async name resolvers */
Curl_resolver_cancel(data);
@@ -763,7 +766,8 @@ void Curl_disconnect(struct Curl_easy *data,
/* the transfer must be detached from the connection */
DEBUGASSERT(!data->conn);
- DEBUGF(infof(data, "Curl_disconnect(conn #%ld, dead=%d)",
+ DEBUGF(infof(data, "Curl_disconnect(conn #%"
+ CURL_FORMAT_CURL_OFF_T ", dead=%d)",
conn->connection_id, dead_connection));
/*
* If this connection isn't marked to force-close, leave it open if there
@@ -937,6 +941,7 @@ static bool extract_if_dead(struct connectdata *conn,
else {
bool input_pending;
+ Curl_attach_connection(data, conn);
dead = !Curl_conn_is_alive(data, conn, &input_pending);
if(input_pending) {
/* For reuse, we want a "clean" connection state. The includes
@@ -949,10 +954,12 @@ static bool extract_if_dead(struct connectdata *conn,
*/
dead = TRUE;
}
+ Curl_detach_connection(data);
}
if(dead) {
- infof(data, "Connection %ld seems to be dead", conn->connection_id);
+ infof(data, "Connection %" CURL_FORMAT_CURL_OFF_T " seems to be dead",
+ conn->connection_id);
Curl_conncache_remove_conn(data, conn, FALSE);
return TRUE;
}
@@ -1147,8 +1154,8 @@ ConnectionExists(struct Curl_easy *data,
/* primary_ip[0] is NUL only if the resolving of the name hasn't
completed yet and until then we don't re-use this connection */
if(!check->primary_ip[0]) {
- infof(data,
- "Connection #%ld is still name resolving, can't reuse",
+ infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T " is still "
+ "name resolving, can't reuse",
check->connection_id);
continue;
}
@@ -1158,8 +1165,8 @@ ConnectionExists(struct Curl_easy *data,
if(!Curl_conn_is_connected(check, FIRSTSOCKET)) {
foundPendingCandidate = TRUE;
/* Don't pick a connection that hasn't connected yet */
- infof(data, "Connection #%ld isn't open enough, can't reuse",
- check->connection_id);
+ infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T
+ "isn't open enough, can't reuse", check->connection_id);
continue;
}
@@ -1335,8 +1342,8 @@ ConnectionExists(struct Curl_easy *data,
if(!Curl_ssl_config_matches(&needle->ssl_config,
&check->ssl_config)) {
DEBUGF(infof(data,
- "Connection #%ld has different SSL parameters, "
- "can't reuse",
+ "Connection #%" CURL_FORMAT_CURL_OFF_T
+ " has different SSL parameters, can't reuse",
check->connection_id));
continue;
}
@@ -1477,14 +1484,14 @@ void Curl_verboseconnect(struct Curl_easy *data,
struct connectdata *conn)
{
if(data->set.verbose)
- infof(data, "Connected to %s (%s) port %u (#%ld)",
+ infof(data, "Connected to %s (%s) port %u",
#ifndef CURL_DISABLE_PROXY
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
#endif
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname,
- conn->primary_ip, conn->port, conn->connection_id);
+ conn->primary_ip, conn->port);
}
#endif
@@ -1857,7 +1864,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
* User name and password set with their own options override the
* credentials possibly set in the URL.
*/
- if(!data->state.aptr.passwd) {
+ if(!data->set.str[STRING_PASSWORD]) {
uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
if(!uc) {
char *decoded;
@@ -3678,15 +3685,14 @@ static CURLcode create_conn(struct Curl_easy *data,
*in_connect = conn;
#ifndef CURL_DISABLE_PROXY
- infof(data, "Re-using existing connection #%ld with %s %s",
- conn->connection_id,
+ infof(data, "Re-using existing connection with %s %s",
conn->bits.proxy?"proxy":"host",
conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
conn->host.dispname);
#else
- infof(data, "Re-using existing connection #%ld with host %s",
- conn->connection_id, conn->host.dispname);
+ infof(data, "Re-using existing connection with host %s",
+ conn->host.dispname);
#endif
}
else {
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c
index 9574ed9727..1125f4a90c 100644
--- a/libs/libcurl/src/urlapi.c
+++ b/libs/libcurl/src/urlapi.c
@@ -201,7 +201,7 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url,
size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
bool guess_scheme)
{
- int i;
+ int i = 0;
DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
(void)buflen; /* only used in debug-builds */
if(buf)
@@ -210,17 +210,18 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url))
return 0;
#endif
- for(i = 0; i < MAX_SCHEME_LEN; ++i) {
- char s = url[i];
- if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) {
- /* RFC 3986 3.1 explains:
- scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
- */
- }
- else {
- break;
+ if(ISALPHA(url[0]))
+ for(i = 1; i < MAX_SCHEME_LEN; ++i) {
+ char s = url[i];
+ if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) {
+ /* RFC 3986 3.1 explains:
+ scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ */
+ }
+ else {
+ break;
+ }
}
- }
if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) {
/* If this does not guess scheme, the scheme always ends with the colon so
that this also detects data: URLs etc. In guessing mode, data: could
@@ -1546,7 +1547,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
}
}
- url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
scheme,
u->user ? u->user : "",
u->password ? ":": "",
@@ -1557,7 +1558,6 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
allochost ? allochost : u->host,
port ? ":": "",
port ? port : "",
- (u->path && (u->path[0] != '/')) ? "/": "",
u->path ? u->path : "/",
(u->query && u->query[0]) ? "?": "",
(u->query && u->query[0]) ? u->query : "",
@@ -1639,8 +1639,10 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0;
bool plusencode = FALSE;
bool urlskipslash = FALSE;
+ bool leadingslash = FALSE;
bool appendquery = FALSE;
bool equalsencode = FALSE;
+ size_t nalloc;
if(!u)
return CURLUE_BAD_HANDLE;
@@ -1693,6 +1695,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_OK;
}
+ nalloc = strlen(part);
+ if(nalloc > CURL_MAX_INPUT_LENGTH)
+ /* excessive input length */
+ return CURLUE_MALFORMED_INPUT;
+
switch(what) {
case CURLUPART_SCHEME: {
size_t plen = strlen(part);
@@ -1706,13 +1713,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_UNSUPPORTED_SCHEME;
storep = &u->scheme;
urlencode = FALSE; /* never */
- /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
- while(plen--) {
- if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.'))
- s++; /* fine */
- else
- return CURLUE_BAD_SCHEME;
+ if(ISALPHA(*s)) {
+ /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
+ while(--plen) {
+ if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.'))
+ s++; /* fine */
+ else
+ return CURLUE_BAD_SCHEME;
+ }
}
+ else
+ return CURLUE_BAD_SCHEME;
break;
}
case CURLUPART_USER:
@@ -1746,6 +1757,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
break;
case CURLUPART_PATH:
urlskipslash = TRUE;
+ leadingslash = TRUE; /* enforce */
storep = &u->path;
break;
case CURLUPART_QUERY:
@@ -1794,18 +1806,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
DEBUGASSERT(storep);
{
- const char *newp = part;
- size_t nalloc = strlen(part);
-
- if(nalloc > CURL_MAX_INPUT_LENGTH)
- /* excessive input length */
- return CURLUE_MALFORMED_INPUT;
+ const char *newp;
+ struct dynbuf enc;
+ Curl_dyn_init(&enc, nalloc * 3 + 1 + leadingslash);
+ if(leadingslash && (part[0] != '/')) {
+ CURLcode result = Curl_dyn_addn(&enc, "/", 1);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
+ }
if(urlencode) {
const unsigned char *i;
- struct dynbuf enc;
-
- Curl_dyn_init(&enc, nalloc * 3 + 1);
for(i = (const unsigned char *)part; *i; i++) {
CURLcode result;
@@ -1833,14 +1844,13 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_OUT_OF_MEMORY;
}
}
- newp = Curl_dyn_ptr(&enc);
}
else {
char *p;
- newp = strdup(part);
- if(!newp)
+ CURLcode result = Curl_dyn_add(&enc, part);
+ if(result)
return CURLUE_OUT_OF_MEMORY;
- p = (char *)newp;
+ p = Curl_dyn_ptr(&enc);
while(*p) {
/* make sure percent encoded are lower case */
if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) &&
@@ -1853,6 +1863,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
p++;
}
}
+ newp = Curl_dyn_ptr(&enc);
if(appendquery) {
/* Append the 'newp' string onto the old query. Add a '&' separator if
@@ -1861,24 +1872,24 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
size_t querylen = u->query ? strlen(u->query) : 0;
bool addamperand = querylen && (u->query[querylen -1] != '&');
if(querylen) {
- struct dynbuf enc;
- Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+ struct dynbuf qbuf;
+ Curl_dyn_init(&qbuf, CURL_MAX_INPUT_LENGTH);
- if(Curl_dyn_addn(&enc, u->query, querylen)) /* add original query */
+ if(Curl_dyn_addn(&qbuf, u->query, querylen)) /* add original query */
goto nomem;
if(addamperand) {
- if(Curl_dyn_addn(&enc, "&", 1))
+ if(Curl_dyn_addn(&qbuf, "&", 1))
goto nomem;
}
- if(Curl_dyn_add(&enc, newp))
+ if(Curl_dyn_add(&qbuf, newp))
goto nomem;
- free((char *)newp);
+ Curl_dyn_free(&enc);
free(*storep);
- *storep = Curl_dyn_ptr(&enc);
+ *storep = Curl_dyn_ptr(&qbuf);
return CURLUE_OK;
nomem:
- free((char *)newp);
+ Curl_dyn_free(&enc);
return CURLUE_OUT_OF_MEMORY;
}
}
@@ -1890,7 +1901,7 @@ nomem:
}
else {
if(!n || hostname_check(u, (char *)newp, n)) {
- free((char *)newp);
+ Curl_dyn_free(&enc);
return CURLUE_BAD_HOSTNAME;
}
}
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index 0295f37c02..81b67bb889 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.h
@@ -882,8 +882,8 @@ struct connectdata {
#define CONN_INUSE(c) ((c)->easyq.size)
/**** Fields set when inited and not modified again */
- long connection_id; /* Contains a unique number to make it easier to
- track the connections in the log output */
+ curl_off_t connection_id; /* Contains a unique number to make it easier to
+ track the connections in the log output */
/* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -1294,7 +1294,9 @@ struct UrlState {
/* buffers to store authentication data in, as parsed from input options */
struct curltime keeps_speed; /* for the progress meter really */
- long lastconnect_id; /* The last connection, -1 if undefined */
+ curl_off_t lastconnect_id; /* The last connection, -1 if undefined */
+ curl_off_t recent_conn_id; /* The most recent connection used, might no
+ * longer exist */
struct dynbuf headerb; /* buffer to store headers in */
char *buffer; /* download buffer */
@@ -1563,6 +1565,7 @@ enum dupstring {
STRING_DNS_LOCAL_IP6,
STRING_SSL_EC_CURVES,
STRING_AWS_SIGV4, /* Parameters for V4 signature */
+ STRING_HAPROXY_CLIENT_IP, /* CURLOPT_HAPROXY_CLIENT_IP */
/* -- end of null-terminated strings -- */
@@ -1902,6 +1905,13 @@ struct Curl_easy {
/* First a simple identifier to easier detect if a user mix up this easy
handle with a multi handle. Set this to CURLEASY_MAGIC_NUMBER */
unsigned int magic;
+ /* once an easy handle is tied to a connection cache
+ a non-negative number to distinguish this transfer from
+ other using the same cache. For easier tracking
+ in log output.
+ This may wrap around after LONG_MAX to 0 again, so it
+ has no uniqueness guarantuee for very large processings. */
+ curl_off_t id;
/* first, two fields for the linked list of these */
struct Curl_easy *next;
diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c
index c43e69fc3c..97de3340c4 100644
--- a/libs/libcurl/src/version.c
+++ b/libs/libcurl/src/version.c
@@ -300,7 +300,7 @@ char *curl_version(void)
protocol line has its own #if line to make things easier on the eye.
*/
-static const char * const protocols[] = {
+static const char * const supported_protocols[] = {
#ifndef CURL_DISABLE_DICT
"dict",
#endif
@@ -535,7 +535,7 @@ static curl_version_info_data version_info = {
NULL, /* ssl_version */
0, /* ssl_version_num, this is kept at zero */
NULL, /* zlib_version */
- protocols,
+ supported_protocols,
NULL, /* c-ares version */
0, /* c-ares version numerical */
NULL, /* libidn version */
diff --git a/libs/libcurl/src/vquic/curl_msh3.c b/libs/libcurl/src/vquic/curl_msh3.c
index 7bf7065774..9e145bfe16 100644
--- a/libs/libcurl/src/vquic/curl_msh3.c
+++ b/libs/libcurl/src/vquic/curl_msh3.c
@@ -123,6 +123,7 @@ struct cf_msh3_ctx {
};
/* How to access `call_data` from a cf_msh3 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_msh3_ctx *)(cf)->ctx)->call_data
@@ -172,7 +173,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
msh3_lock_initialize(&stream->recv_lock);
Curl_bufq_init2(&stream->recvbuf, H3_STREAM_CHUNK_SIZE,
H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
- DEBUGF(LOG_CF(data, cf, "data setup (easy %p)", (void *)data));
+ DEBUGF(LOG_CF(data, cf, "data setup"));
return CURLE_OK;
}
@@ -645,7 +646,7 @@ static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data,
}
else {
/* request is open */
- DEBUGF(LOG_CF(data, cf, "req: send %zd body bytes", len));
+ DEBUGF(LOG_CF(data, cf, "req: send %zu body bytes", len));
if(len > 0xFFFFFFFF) {
len = 0xFFFFFFFF;
}
diff --git a/libs/libcurl/src/vquic/curl_ngtcp2.c b/libs/libcurl/src/vquic/curl_ngtcp2.c
index f47ec4e7c2..41ed55a64a 100644
--- a/libs/libcurl/src/vquic/curl_ngtcp2.c
+++ b/libs/libcurl/src/vquic/curl_ngtcp2.c
@@ -33,7 +33,7 @@
#ifdef OPENSSL_IS_BORINGSSL
#include <ngtcp2/ngtcp2_crypto_boringssl.h>
#else
-#include <ngtcp2/ngtcp2_crypto_openssl.h>
+#include <ngtcp2/ngtcp2_crypto_quictls.h>
#endif
#include "vtls/openssl.h"
#elif defined(USE_GNUTLS)
@@ -165,17 +165,19 @@ struct cf_ngtcp2_ctx {
};
/* How to access `call_data` from a cf_ngtcp2 filter */
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data
/**
* All about the H3 internals of a stream
*/
-struct stream_ctx {
+struct h3_stream_ctx {
int64_t id; /* HTTP/3 protocol identifier */
struct bufq sendbuf; /* h3 request body */
struct bufq recvbuf; /* h3 response body */
size_t sendbuf_len_in_flight; /* sendbuf amount "in flight" */
+ size_t upload_blocked_len; /* the amount written last and EGAINed */
size_t recv_buf_nonflow; /* buffered bytes, not counting for flow control */
uint64_t error3; /* HTTP/3 stream error code */
curl_off_t upload_left; /* number of request bytes left to upload */
@@ -186,18 +188,18 @@ struct stream_ctx {
bool send_closed; /* stream is local closed */
};
-#define H3_STREAM_CTX(d) ((struct stream_ctx *)(((d) && (d)->req.p.http)? \
- ((struct HTTP *)(d)->req.p.http)->h3_ctx \
- : NULL))
-#define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
-#define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \
- H3_STREAM_CTX(d)->id : -2)
+#define H3_STREAM_CTX(d) ((struct h3_stream_ctx *)(((d) && (d)->req.p.http)? \
+ ((struct HTTP *)(d)->req.p.http)->h3_ctx \
+ : NULL))
+#define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
+#define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \
+ H3_STREAM_CTX(d)->id : -2)
static CURLcode h3_data_setup(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
if(!data || !data->req.p.http) {
failf(data, "initialization failure, transfer not http initialized");
@@ -223,13 +225,13 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
stream->recv_buf_nonflow = 0;
H3_STREAM_LCTX(data) = stream;
- DEBUGF(LOG_CF(data, cf, "data setup (easy %p)", (void *)data));
+ DEBUGF(LOG_CF(data, cf, "data setup"));
return CURLE_OK;
}
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
(void)cf;
if(stream) {
@@ -246,10 +248,37 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
the maximum packet burst to MAX_PKT_BURST packets. */
#define MAX_PKT_BURST 10
-static CURLcode cf_process_ingress(struct Curl_cfilter *cf,
- struct Curl_easy *data);
-static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
- struct Curl_easy *data);
+struct pkt_io_ctx {
+ struct Curl_cfilter *cf;
+ struct Curl_easy *data;
+ ngtcp2_tstamp ts;
+ size_t pkt_count;
+ ngtcp2_path_storage ps;
+};
+
+static ngtcp2_tstamp timestamp(void)
+{
+ struct curltime ct = Curl_now();
+ return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
+}
+
+static void pktx_init(struct pkt_io_ctx *pktx,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ pktx->cf = cf;
+ pktx->data = data;
+ pktx->ts = timestamp();
+ pktx->pkt_count = 0;
+ ngtcp2_path_storage_zero(&pktx->ps);
+}
+
+static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx);
+static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx);
static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
uint64_t datalen, void *user_data,
void *stream_user_data);
@@ -261,12 +290,6 @@ static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
return ctx->qconn;
}
-static ngtcp2_tstamp timestamp(void)
-{
- struct curltime ct = Curl_now();
- return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
-}
-
#ifdef DEBUG_NGTCP2
static void quic_printf(void *user_data, const char *fmt, ...)
{
@@ -300,7 +323,8 @@ static void qlog_callback(void *user_data, uint32_t flags,
}
static void quic_settings(struct cf_ngtcp2_ctx *ctx,
- struct Curl_easy *data)
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
ngtcp2_settings *s = &ctx->settings;
ngtcp2_transport_params *t = &ctx->transport_params;
@@ -314,7 +338,7 @@ static void quic_settings(struct cf_ngtcp2_ctx *ctx,
#endif
(void)data;
- s->initial_ts = timestamp();
+ s->initial_ts = pktx->ts;
s->handshake_timeout = QUIC_HANDSHAKE_TIMEOUT;
s->max_window = 100 * ctx->max_stream_window;
s->max_stream_window = ctx->max_stream_window;
@@ -327,7 +351,7 @@ static void quic_settings(struct cf_ngtcp2_ctx *ctx,
t->initial_max_streams_uni = QUIC_MAX_STREAMS;
t->max_idle_timeout = QUIC_IDLE_TIMEOUT;
if(ctx->qlogfd != -1) {
- s->qlog.write = qlog_callback;
+ s->qlog_write = qlog_callback;
}
}
@@ -383,8 +407,8 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
goto out;
}
#else
- if(ngtcp2_crypto_openssl_configure_client_context(ssl_ctx) != 0) {
- failf(data, "ngtcp2_crypto_openssl_configure_client_context failed");
+ if(ngtcp2_crypto_quictls_configure_client_context(ssl_ctx) != 0) {
+ failf(data, "ngtcp2_crypto_quictls_configure_client_context failed");
goto out;
}
#endif
@@ -686,7 +710,7 @@ static void report_consumed_data(struct Curl_cfilter *cf,
struct Curl_easy *data,
size_t consumed)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
struct cf_ngtcp2_ctx *ctx = cf->ctx;
if(!stream)
@@ -902,13 +926,13 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
return 0;
}
-static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_crypto_level level,
+static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_encryption_level level,
void *user_data)
{
struct Curl_cfilter *cf = user_data;
(void)tconn;
- if(level != NGTCP2_CRYPTO_LEVEL_APPLICATION) {
+ if(level != NGTCP2_ENCRYPTION_LEVEL_1RTT) {
return 0;
}
@@ -962,6 +986,61 @@ static ngtcp2_callbacks ng_callbacks = {
NULL, /* early_data_rejected */
};
+/**
+ * Connection maintenance like timeouts on packet ACKs etc. are done by us, not
+ * the OS like for TCP. POLL events on the socket therefore are not
+ * sufficient.
+ * ngtcp2 tells us when it wants to be invoked again. We handle that via
+ * the `Curl_expire()` mechanisms.
+ */
+static CURLcode check_and_set_expiry(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
+{
+ struct cf_ngtcp2_ctx *ctx = cf->ctx;
+ struct pkt_io_ctx local_pktx;
+ ngtcp2_tstamp expiry;
+
+ if(!pktx) {
+ pktx_init(&local_pktx, cf, data);
+ pktx = &local_pktx;
+ }
+ else {
+ pktx->ts = timestamp();
+ }
+
+ expiry = ngtcp2_conn_get_expiry(ctx->qconn);
+ if(expiry != UINT64_MAX) {
+ if(expiry <= pktx->ts) {
+ CURLcode result;
+ int rv = ngtcp2_conn_handle_expiry(ctx->qconn, pktx->ts);
+ if(rv) {
+ failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
+ ngtcp2_strerror(rv));
+ ngtcp2_ccerr_set_liberr(&ctx->last_error, rv, NULL, 0);
+ return CURLE_SEND_ERROR;
+ }
+ result = cf_progress_ingress(cf, data, pktx);
+ if(result)
+ return result;
+ result = cf_progress_egress(cf, data, pktx);
+ if(result)
+ return result;
+ /* ask again, things might have changed */
+ expiry = ngtcp2_conn_get_expiry(ctx->qconn);
+ }
+
+ if(expiry > pktx->ts) {
+ ngtcp2_duration timeout = expiry - pktx->ts;
+ if(timeout % NGTCP2_MILLISECONDS) {
+ timeout += NGTCP2_MILLISECONDS;
+ }
+ Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
+ }
+ }
+ return CURLE_OK;
+}
+
static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
@@ -969,7 +1048,7 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct SingleRequest *k = &data->req;
int rv = GETSOCK_BLANK;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
struct cf_call_data save;
CF_DATA_SAVE(save, cf, data);
@@ -991,15 +1070,15 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
return rv;
}
-static void drain_stream(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static void h3_drain_stream(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
unsigned char bits;
(void)cf;
bits = CURL_CSELECT_IN;
- if(stream && !stream->send_closed && stream->upload_left)
+ if(stream && stream->upload_left && !stream->send_closed)
bits |= CURL_CSELECT_OUT;
if(data->state.dselect_bits != bits) {
data->state.dselect_bits = bits;
@@ -1013,7 +1092,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
(void)conn;
(void)stream_id;
(void)app_error_code;
@@ -1031,7 +1110,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
stream->reset = TRUE;
stream->send_closed = TRUE;
}
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
return 0;
}
@@ -1045,7 +1124,7 @@ static CURLcode write_resp_raw(struct Curl_cfilter *cf,
const void *mem, size_t memlen,
bool flow)
{
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
CURLcode result = CURLE_OK;
ssize_t nwritten;
@@ -1085,7 +1164,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
(void)stream3_id;
result = write_resp_raw(cf, data, buf, buflen, TRUE);
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
return result? -1 : 0;
}
@@ -1110,7 +1189,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
CURLcode result = CURLE_OK;
(void)conn;
(void)stream_id;
@@ -1130,7 +1209,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
if(stream->status_code / 100 != 1) {
stream->resp_hds_complete = TRUE;
}
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
return 0;
}
@@ -1143,7 +1222,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
CURLcode result = CURLE_OK;
(void)conn;
(void)stream_id;
@@ -1207,7 +1286,8 @@ static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
(void)conn;
(void)stream_user_data;
- rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, stream_id, app_error_code);
+ rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, stream_id,
+ app_error_code);
if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -1225,7 +1305,7 @@ static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id,
(void)conn;
(void)data;
- rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, stream_id,
+ rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, 0, stream_id,
app_error_code);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] reset -> %d", stream_id, rv));
if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
@@ -1249,7 +1329,8 @@ static nghttp3_callbacks ngh3_callbacks = {
cb_h3_stop_sending,
NULL, /* end_stream */
cb_h3_reset_stream,
- NULL /* shutdown */
+ NULL, /* shutdown */
+ NULL /* recv_settings */
};
static int init_ngh3_conn(struct Curl_cfilter *cf)
@@ -1314,7 +1395,7 @@ fail:
static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
struct Curl_easy *data,
- struct stream_ctx *stream,
+ struct h3_stream_ctx *stream,
CURLcode *err)
{
ssize_t nread = -1;
@@ -1364,9 +1445,10 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
ssize_t nread = -1;
struct cf_call_data save;
+ struct pkt_io_ctx pktx;
(void)ctx;
@@ -1377,6 +1459,8 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
DEBUGASSERT(ctx->h3conn);
*err = CURLE_OK;
+ pktx_init(&pktx, cf, data);
+
if(!stream) {
*err = CURLE_RECV_ERROR;
goto out;
@@ -1392,7 +1476,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
report_consumed_data(cf, data, nread);
}
- if(cf_process_ingress(cf, data)) {
+ if(cf_progress_ingress(cf, data, &pktx)) {
*err = CURLE_RECV_ERROR;
nread = -1;
goto out;
@@ -1410,7 +1494,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
}
if(nread > 0) {
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
}
else {
if(stream->closed) {
@@ -1422,10 +1506,17 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
}
out:
- if(cf_flush_egress(cf, data)) {
+ if(cf_progress_egress(cf, data, &pktx)) {
*err = CURLE_SEND_ERROR;
nread = -1;
}
+ else {
+ CURLcode result2 = check_and_set_expiry(cf, data, &pktx);
+ if(result2) {
+ *err = result2;
+ nread = -1;
+ }
+ }
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_recv(len=%zu) -> %zd, %d",
stream? stream->id : -1, len, nread, *err));
CF_DATA_RESTORE(cf, save);
@@ -1438,7 +1529,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
size_t skiplen;
(void)cf;
@@ -1454,10 +1545,8 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
Curl_bufq_skip(&stream->sendbuf, skiplen);
stream->sendbuf_len_in_flight -= skiplen;
- /* `sendbuf` *might* now have more room. If so, resume this
- * possibly paused stream. And also tell our transfer engine that
- * it may continue KEEP_SEND if told to PAUSE. */
- if(!Curl_bufq_is_full(&stream->sendbuf)) {
+ /* Everything ACKed, we resume upload processing */
+ if(!stream->sendbuf_len_in_flight) {
int rv = nghttp3_conn_resume_stream(conn, stream_id);
if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
@@ -1465,7 +1554,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
if((data->req.keepon & KEEP_SEND_HOLD) &&
(data->req.keepon & KEEP_SEND)) {
data->req.keepon &= ~KEEP_SEND_HOLD;
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] unpausing acks",
stream_id));
}
@@ -1481,7 +1570,7 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_cfilter *cf = user_data;
struct Curl_easy *data = stream_user_data;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
ssize_t nwritten = 0;
size_t nvecs = 0;
(void)cf;
@@ -1530,8 +1619,10 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
}
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] read req body -> "
- "%d vecs%s with %zu (buffered=%zu, left=%zd)", stream->id,
- (int)nvecs, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
+ "%d vecs%s with %zu (buffered=%zu, left=%"
+ CURL_FORMAT_CURL_OFF_T ")",
+ stream->id, (int)nvecs,
+ *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
nwritten, Curl_bufq_len(&stream->sendbuf),
stream->upload_left));
return (nghttp3_ssize)nvecs;
@@ -1547,7 +1638,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
CURLcode *err)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = NULL;
+ struct h3_stream_ctx *stream = NULL;
struct h1_req_parser h1;
struct dynhds h2_headers;
size_t nheader;
@@ -1614,16 +1705,19 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
else
/* data sending without specifying the data amount up front */
stream->upload_left = -1; /* unknown */
- reader.read_data = cb_h3_read_req_body;
- preader = &reader;
break;
default:
/* there is not request body */
stream->upload_left = 0; /* no request body */
- preader = NULL;
break;
}
+ stream->send_closed = (stream->upload_left == 0);
+ if(!stream->send_closed) {
+ reader.read_data = cb_h3_read_req_body;
+ preader = &reader;
+ }
+
rc = nghttp3_conn_submit_request(ctx->h3conn, stream->id,
nva, nheader, preader, data);
if(rc) {
@@ -1642,8 +1736,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
goto out;
}
- infof(data, "Using HTTP/3 Stream ID: %" PRId64 " (easy handle %p)",
- stream->id, (void *)data);
+ infof(data, "Using HTTP/3 Stream ID: %" PRId64, stream->id);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] opened for %s",
stream->id, data->state.url));
@@ -1658,20 +1751,23 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
ssize_t sent = 0;
struct cf_call_data save;
+ struct pkt_io_ctx pktx;
+ CURLcode result;
CF_DATA_SAVE(save, cf, data);
DEBUGASSERT(cf->connected);
DEBUGASSERT(ctx->qconn);
DEBUGASSERT(ctx->h3conn);
+ pktx_init(&pktx, cf, data);
*err = CURLE_OK;
- if(stream && stream->closed) {
- *err = CURLE_HTTP3;
+ result = cf_progress_ingress(cf, data, &pktx);
+ if(result) {
+ *err = result;
sent = -1;
- goto out;
}
if(!stream || stream->id < 0) {
@@ -1681,32 +1777,64 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
goto out;
}
}
+ else if(stream->upload_blocked_len) {
+ /* the data in `buf` has alread been submitted or added to the
+ * buffers, but have been EAGAINed on the last invocation. */
+ DEBUGASSERT(len >= stream->upload_blocked_len);
+ if(len < stream->upload_blocked_len) {
+ /* Did we get called again with a smaller `len`? This should not
+ * happen. We are not prepared to handle that. */
+ failf(data, "HTTP/3 send again with decreased length");
+ *err = CURLE_HTTP3;
+ sent = -1;
+ goto out;
+ }
+ sent = (ssize_t)stream->upload_blocked_len;
+ stream->upload_blocked_len = 0;
+ }
+ else if(stream->closed) {
+ *err = CURLE_HTTP3;
+ sent = -1;
+ goto out;
+ }
else {
sent = Curl_bufq_write(&stream->sendbuf, buf, len, err);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_send, add to "
"sendbuf(len=%zu) -> %zd, %d",
stream->id, len, sent, *err));
if(sent < 0) {
- if(*err == CURLE_AGAIN) {
- /* Can't add more to the send buf, needs to drain first.
- * Pause the sending to avoid a busy loop. */
- data->req.keepon |= KEEP_SEND_HOLD;
- DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] pause send",
- stream->id));
- }
goto out;
}
(void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id);
}
- if(cf_flush_egress(cf, data)) {
- *err = CURLE_SEND_ERROR;
+ result = cf_progress_egress(cf, data, &pktx);
+ if(result) {
+ *err = result;
sent = -1;
- goto out;
+ }
+
+ if(stream && sent > 0 && stream->sendbuf_len_in_flight) {
+ /* We have unacknowledged DATA and cannot report success to our
+ * caller. Instead we EAGAIN and remember how much we have already
+ * "written" into our various internal connection buffers.
+ * We put the stream upload on HOLD, until this gets ACKed. */
+ stream->upload_blocked_len = sent;
+ DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] cf_send(len=%zu), "
+ "%zu bytes in flight -> EGAIN", stream->id, len,
+ stream->sendbuf_len_in_flight));
+ *err = CURLE_AGAIN;
+ sent = -1;
+ data->req.keepon |= KEEP_SEND_HOLD;
}
out:
+ result = check_and_set_expiry(cf, data, &pktx);
+ if(result) {
+ *err = result;
+ sent = -1;
+ }
CF_DATA_RESTORE(cf, save);
return sent;
}
@@ -1763,34 +1891,27 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
return result;
}
-struct recv_ctx {
- struct Curl_cfilter *cf;
- struct Curl_easy *data;
- ngtcp2_tstamp ts;
- size_t pkt_count;
-};
-
static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
struct sockaddr_storage *remote_addr,
socklen_t remote_addrlen, int ecn,
void *userp)
{
- struct recv_ctx *r = userp;
- struct cf_ngtcp2_ctx *ctx = r->cf->ctx;
+ struct pkt_io_ctx *pktx = userp;
+ struct cf_ngtcp2_ctx *ctx = pktx->cf->ctx;
ngtcp2_pkt_info pi;
ngtcp2_path path;
int rv;
- ++r->pkt_count;
+ ++pktx->pkt_count;
ngtcp2_addr_init(&path.local, (struct sockaddr *)&ctx->q.local_addr,
ctx->q.local_addrlen);
ngtcp2_addr_init(&path.remote, (struct sockaddr *)remote_addr,
remote_addrlen);
pi.ecn = (uint32_t)ecn;
- rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, pkt, pktlen, r->ts);
+ rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, pkt, pktlen, pktx->ts);
if(rv) {
- DEBUGF(LOG_CF(r->data, r->cf, "ingress, read_pkt -> %s",
+ DEBUGF(LOG_CF(pktx->data, pktx->cf, "ingress, read_pkt -> %s",
ngtcp2_strerror(rv)));
if(!ctx->last_error.error_code) {
if(rv == NGTCP2_ERR_CRYPTO) {
@@ -1813,41 +1934,40 @@ static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
return CURLE_OK;
}
-static CURLcode cf_process_ingress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- struct recv_ctx rctx;
+ struct pkt_io_ctx local_pktx;
size_t pkts_chunk = 128, i;
size_t pkts_max = 10 * pkts_chunk;
- CURLcode result;
+ CURLcode result = CURLE_OK;
- rctx.cf = cf;
- rctx.data = data;
- rctx.ts = timestamp();
- rctx.pkt_count = 0;
+ if(!pktx) {
+ pktx_init(&local_pktx, cf, data);
+ pktx = &local_pktx;
+ }
+ else {
+ pktx->ts = timestamp();
+ }
for(i = 0; i < pkts_max; i += pkts_chunk) {
- rctx.pkt_count = 0;
+ pktx->pkt_count = 0;
result = vquic_recv_packets(cf, data, &ctx->q, pkts_chunk,
- recv_pkt, &rctx);
+ recv_pkt, pktx);
if(result) /* error */
break;
- if(rctx.pkt_count < pkts_chunk) /* got less than we could */
+ if(pktx->pkt_count < pkts_chunk) /* got less than we could */
break;
/* give egress a chance before we receive more */
- result = cf_flush_egress(cf, data);
+ result = cf_progress_egress(cf, data, pktx);
+ if(result) /* error */
+ break;
}
return result;
}
-struct read_ctx {
- struct Curl_cfilter *cf;
- struct Curl_easy *data;
- ngtcp2_tstamp ts;
- ngtcp2_path_storage *ps;
-};
-
/**
* Read a network packet to send from ngtcp2 into `buf`.
* Return number of bytes written or -1 with *err set.
@@ -1856,7 +1976,7 @@ static ssize_t read_pkt_to_send(void *userp,
unsigned char *buf, size_t buflen,
CURLcode *err)
{
- struct read_ctx *x = userp;
+ struct pkt_io_ctx *x = userp;
struct cf_ngtcp2_ctx *ctx = x->cf->ctx;
nghttp3_vec vec[16];
nghttp3_ssize veccnt;
@@ -1896,7 +2016,7 @@ static ssize_t read_pkt_to_send(void *userp,
flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
(fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
- n = ngtcp2_conn_writev_stream(ctx->qconn, x->ps? &x->ps->path : NULL,
+ n = ngtcp2_conn_writev_stream(ctx->qconn, &x->ps.path,
NULL, buf, buflen,
&ndatalen, flags, stream_id,
(const ngtcp2_vec *)vec, veccnt, x->ts);
@@ -1955,28 +2075,25 @@ out:
return nwritten;
}
-static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static CURLcode cf_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- int rv;
ssize_t nread;
size_t max_payload_size, path_max_payload_size, max_pktcnt;
size_t pktcnt = 0;
size_t gsolen = 0; /* this disables gso until we have a clue */
- ngtcp2_path_storage ps;
- ngtcp2_tstamp ts = timestamp();
- ngtcp2_tstamp expiry;
- ngtcp2_duration timeout;
CURLcode curlcode;
- struct read_ctx readx;
+ struct pkt_io_ctx local_pktx;
- rv = ngtcp2_conn_handle_expiry(ctx->qconn, ts);
- if(rv) {
- failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
- ngtcp2_strerror(rv));
- ngtcp2_ccerr_set_liberr(&ctx->last_error, rv, NULL, 0);
- return CURLE_SEND_ERROR;
+ if(!pktx) {
+ pktx_init(&local_pktx, cf, data);
+ pktx = &local_pktx;
+ }
+ else {
+ pktx->ts = timestamp();
+ ngtcp2_path_storage_zero(&pktx->ps);
}
curlcode = vquic_flush(cf, data, &ctx->q);
@@ -1988,8 +2105,6 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
return curlcode;
}
- ngtcp2_path_storage_zero(&ps);
-
/* In UDP, there is a maximum theoretical packet paload length and
* a minimum payload length that is "guarantueed" to work.
* To detect if this minimum payload can be increased, ngtcp2 sends
@@ -2008,15 +2123,10 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
max_pktcnt = CURLMIN(MAX_PKT_BURST,
ctx->q.sendbuf.chunk_size / max_payload_size);
- readx.cf = cf;
- readx.data = data;
- readx.ts = ts;
- readx.ps = &ps;
-
for(;;) {
/* add the next packet to send, if any, to our buffer */
nread = Curl_bufq_sipn(&ctx->q.sendbuf, max_payload_size,
- read_pkt_to_send, &readx, &curlcode);
+ read_pkt_to_send, pktx, &curlcode);
/* DEBUGF(LOG_CF(data, cf, "sip packet(maxlen=%zu) -> %zd, %d",
max_payload_size, nread, curlcode)); */
if(nread < 0) {
@@ -2076,21 +2186,6 @@ static CURLcode cf_flush_egress(struct Curl_cfilter *cf,
}
out:
- /* non-errored exit. check when we should run again. */
- expiry = ngtcp2_conn_get_expiry(ctx->qconn);
- if(expiry != UINT64_MAX) {
- if(expiry <= ts) {
- timeout = 0;
- }
- else {
- timeout = expiry - ts;
- if(timeout % NGTCP2_MILLISECONDS) {
- timeout += NGTCP2_MILLISECONDS;
- }
- }
- Curl_expire(data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
- }
-
return CURLE_OK;
}
@@ -2101,7 +2196,7 @@ out:
static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
- const struct stream_ctx *stream = H3_STREAM_CTX(data);
+ const struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
(void)cf;
return stream && !Curl_bufq_is_empty(&stream->recvbuf);
}
@@ -2113,7 +2208,7 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
/* TODO: there seems right now no API in ngtcp2 to shrink/enlarge
* the streams windows. As we do in HTTP/2. */
if(!pause) {
- drain_stream(cf, data);
+ h3_drain_stream(cf, data);
Curl_expire(data, 0, EXPIRE_RUN_NOW);
}
return CURLE_OK;
@@ -2141,7 +2236,7 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
break;
}
case CF_CTRL_DATA_DONE_SEND: {
- struct stream_ctx *stream = H3_STREAM_CTX(data);
+ struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
if(stream && !stream->send_closed) {
stream->send_closed = TRUE;
stream->upload_left = Curl_bufq_len(&stream->sendbuf);
@@ -2150,11 +2245,7 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
break;
}
case CF_CTRL_DATA_IDLE:
- if(timestamp() >= ngtcp2_conn_get_expiry(ctx->qconn)) {
- if(cf_flush_egress(cf, data)) {
- result = CURLE_SEND_ERROR;
- }
- }
+ result = check_and_set_expiry(cf, data, NULL);
break;
default:
break;
@@ -2250,7 +2341,8 @@ static void cf_ngtcp2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
* Might be called twice for happy eyeballs.
*/
static CURLcode cf_connect_start(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data,
+ struct pkt_io_ctx *pktx)
{
struct cf_ngtcp2_ctx *ctx = cf->ctx;
int rc;
@@ -2294,7 +2386,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
(void)Curl_qlogdir(data, ctx->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
ctx->qlogfd = qfd; /* -1 if failure above */
- quic_settings(ctx, data);
+ quic_settings(ctx, data, pktx);
result = vquic_ctx_init(&ctx->q);
if(result)
@@ -2344,6 +2436,7 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
CURLcode result = CURLE_OK;
struct cf_call_data save;
struct curltime now;
+ struct pkt_io_ctx pktx;
if(cf->connected) {
*done = TRUE;
@@ -2359,6 +2452,7 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
*done = FALSE;
now = Curl_now();
+ pktx_init(&pktx, cf, data);
CF_DATA_SAVE(save, cf, data);
@@ -2370,19 +2464,19 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
if(!ctx->qconn) {
ctx->started_at = now;
- result = cf_connect_start(cf, data);
+ result = cf_connect_start(cf, data, &pktx);
if(result)
goto out;
- result = cf_flush_egress(cf, data);
+ result = cf_progress_egress(cf, data, &pktx);
/* we do not expect to be able to recv anything yet */
goto out;
}
- result = cf_process_ingress(cf, data);
+ result = cf_progress_ingress(cf, data, &pktx);
if(result)
goto out;
- result = cf_flush_egress(cf, data);
+ result = cf_progress_egress(cf, data, &pktx);
if(result)
goto out;
@@ -2402,7 +2496,7 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
out:
if(result == CURLE_RECV_ERROR && ctx->qconn &&
- ngtcp2_conn_is_in_draining_period(ctx->qconn)) {
+ ngtcp2_conn_in_draining_period(ctx->qconn)) {
/* When a QUIC server instance is shutting down, it may send us a
* CONNECTION_CLOSE right away. Our connection then enters the DRAINING
* state.
@@ -2439,6 +2533,9 @@ out:
r_ip, r_port, curl_easy_strerror(result));
}
#endif
+ if(!result && ctx->qconn) {
+ result = check_and_set_expiry(cf, data, &pktx);
+ }
DEBUGF(LOG_CF(data, cf, "connect -> %d, done=%d", result, *done));
CF_DATA_RESTORE(cf, save);
return result;
@@ -2510,13 +2607,11 @@ static bool cf_ngtcp2_conn_is_alive(struct Curl_cfilter *cf,
not in use by any other transfer, there shouldn't be any data here,
only "protocol frames" */
*input_pending = FALSE;
- Curl_attach_connection(data, cf->conn);
- if(cf_process_ingress(cf, data))
+ if(cf_progress_ingress(cf, data, NULL))
alive = FALSE;
else {
alive = TRUE;
}
- Curl_detach_connection(data);
}
return alive;
diff --git a/libs/libcurl/src/vquic/curl_quiche.c b/libs/libcurl/src/vquic/curl_quiche.c
index 1cf37f7a16..c587b13571 100644
--- a/libs/libcurl/src/vquic/curl_quiche.c
+++ b/libs/libcurl/src/vquic/curl_quiche.c
@@ -277,7 +277,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
stream->id = -1;
Curl_bufq_initp(&stream->recvbuf, &ctx->stream_bufcp,
H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
- DEBUGF(LOG_CF(data, cf, "data setup (easy %p)", (void *)data));
+ DEBUGF(LOG_CF(data, cf, "data setup"));
return CURLE_OK;
}
@@ -425,10 +425,6 @@ static ssize_t stream_resp_read(void *reader_ctx,
*err = CURLE_OK;
return nread;
}
- else if(nread < 0) {
- *err = CURLE_AGAIN;
- return -1;
- }
else {
*err = stream->resp_got_header? CURLE_PARTIAL_FILE : CURLE_RECV_ERROR;
return -1;
@@ -649,7 +645,7 @@ static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen,
}
}
else if((size_t)nread < pktlen) {
- DEBUGF(LOG_CF(r->data, r->cf, "ingress, quiche only read %zd/%zd bytes",
+ DEBUGF(LOG_CF(r->data, r->cf, "ingress, quiche only read %zd/%zu bytes",
nread, pktlen));
}
@@ -826,7 +822,7 @@ static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
if(!stream) {
*err = CURLE_RECV_ERROR;
- goto out;
+ return -1;
}
if(!Curl_bufq_is_empty(&stream->recvbuf)) {
@@ -883,8 +879,10 @@ out:
}
if(nread > 0)
ctx->data_recvd += nread;
- DEBUGF(LOG_CF(data, cf, "[h3sid=%"PRId64"] cf_recv(total=%zd) -> %zd, %d",
- stream->id, ctx->data_recvd, nread, *err));
+ DEBUGF(LOG_CF(data, cf, "[h3sid=%"PRId64"] cf_recv(total=%"
+ CURL_FORMAT_CURL_OFF_T ") -> %zd, %d",
+ stream ? stream->id : (int64_t)0,
+ ctx->data_recvd, nread, *err));
return nread;
}
@@ -909,8 +907,7 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf,
if(!stream) {
*err = h3_data_setup(cf, data);
if(*err) {
- nwritten = -1;
- goto out;
+ return -1;
}
stream = H3_STREAM_CTX(data);
DEBUGASSERT(stream);
@@ -995,8 +992,7 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf,
stream->closed = FALSE;
stream->reset = FALSE;
- infof(data, "Using HTTP/3 Stream ID: %" PRId64 " (easy handle %p)",
- stream3_id, (void *)data);
+ infof(data, "Using HTTP/3 Stream ID: %" PRId64, stream3_id);
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] opened for %s",
stream3_id, data->state.url));
@@ -1068,7 +1064,7 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data,
stream->send_closed = TRUE;
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] send body(len=%zu, "
- "left=%zd) -> %zd",
+ "left=%" CURL_FORMAT_CURL_OFF_T ") -> %zd",
stream->id, len, stream->upload_left, nwritten));
*err = CURLE_OK;
}
@@ -1555,13 +1551,11 @@ static bool cf_quiche_conn_is_alive(struct Curl_cfilter *cf,
not in use by any other transfer, there shouldn't be any data here,
only "protocol frames" */
*input_pending = FALSE;
- Curl_attach_connection(data, cf->conn);
if(cf_process_ingress(cf, data))
alive = FALSE;
else {
alive = TRUE;
}
- Curl_detach_connection(data);
}
return alive;
diff --git a/libs/libcurl/src/vquic/vquic.c b/libs/libcurl/src/vquic/vquic.c
index 0cb53f6b31..2cf802bd76 100644
--- a/libs/libcurl/src/vquic/vquic.c
+++ b/libs/libcurl/src/vquic/vquic.c
@@ -362,7 +362,7 @@ static CURLcode recvmmsg_packets(struct Curl_cfilter *cf,
}
out:
- DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zd bytes -> %d",
+ DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d",
pkts, total_nread, result));
return result;
}
@@ -425,7 +425,7 @@ static CURLcode recvmsg_packets(struct Curl_cfilter *cf,
}
out:
- DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zd bytes -> %d",
+ DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d",
pkts, total_nread, result));
return result;
}
@@ -482,7 +482,7 @@ static CURLcode recvfrom_packets(struct Curl_cfilter *cf,
}
out:
- DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zd bytes -> %d",
+ DEBUGF(LOG_CF(data, cf, "recvd %zu packets with %zu bytes -> %d",
pkts, total_nread, result));
return result;
}
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
index 115d90de89..0cb7a8b0a7 100644
--- a/libs/libcurl/src/vssh/libssh2.c
+++ b/libs/libcurl/src/vssh/libssh2.c
@@ -100,11 +100,9 @@
/* Local functions: */
static const char *sftp_libssh2_strerror(unsigned long err);
-#ifdef CURL_LIBSSH2_DEBUG
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
static LIBSSH2_FREE_FUNC(my_libssh2_free);
-#endif
static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data);
static CURLcode ssh_connect(struct Curl_easy *data, bool *done);
static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done);
@@ -284,8 +282,6 @@ static CURLcode libssh2_session_error_to_CURLE(int err)
return CURLE_SSH;
}
-#ifdef CURL_LIBSSH2_DEBUG
-
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
{
(void)abstract; /* arg not used */
@@ -305,8 +301,6 @@ static LIBSSH2_FREE_FUNC(my_libssh2_free)
free(ptr);
}
-#endif
-
/*
* SSH State machine related code
*/
@@ -895,6 +889,7 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data)
}
if(found) {
+ int rc;
infof(data, "Found host %s in %s",
conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
@@ -944,9 +939,15 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data)
}
infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method);
- result = libssh2_session_error_to_CURLE(
- libssh2_session_method_pref(
- sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method));
+ rc = libssh2_session_method_pref(sshc->ssh_session,
+ LIBSSH2_METHOD_HOSTKEY, hostkey_method);
+ if(rc) {
+ char *errmsg = NULL;
+ int errlen;
+ libssh2_session_last_error(sshc->ssh_session, &errmsg, &errlen, 0);
+ failf(data, "libssh2: %s", errmsg);
+ result = libssh2_session_error_to_CURLE(rc);
+ }
}
else {
infof(data, "Did not find host %s in %s",
@@ -3268,13 +3269,12 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
sock = conn->sock[FIRSTSOCKET];
#endif /* CURL_LIBSSH2_DEBUG */
-#ifdef CURL_LIBSSH2_DEBUG
+ /* libcurl MUST to set custom memory functions so that the kbd_callback
+ funciton's memory allocations can be properled freed */
sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
my_libssh2_free,
my_libssh2_realloc, data);
-#else
- sshc->ssh_session = libssh2_session_init_ex(NULL, NULL, NULL, data);
-#endif
+
if(!sshc->ssh_session) {
failf(data, "Failure initialising ssh session");
return CURLE_FAILED_INIT;
diff --git a/libs/libcurl/src/vssh/wolfssh.c b/libs/libcurl/src/vssh/wolfssh.c
index 269199c221..f0ea484e71 100644
--- a/libs/libcurl/src/vssh/wolfssh.c
+++ b/libs/libcurl/src/vssh/wolfssh.c
@@ -277,7 +277,7 @@ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex,
return -1;
}
DEBUGASSERT(rc == (int)len);
- infof(data, "sent %zd bytes SFTP from offset %zd",
+ infof(data, "sent %zu bytes SFTP from offset %" CURL_FORMAT_CURL_OFF_T,
len, sshc->offset);
sshc->offset += len;
return (ssize_t)rc;
diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c
index b273e493ea..648588069d 100644
--- a/libs/libcurl/src/vtls/bearssl.c
+++ b/libs/libcurl/src/vtls/bearssl.c
@@ -52,7 +52,7 @@ struct x509_context {
int cert_num;
};
-struct ssl_backend_data {
+struct bearssl_ssl_backend_data {
br_ssl_client_context ctx;
struct x509_context x509;
unsigned char buf[BR_SSL_BUFSIZE_BIDI];
@@ -574,7 +574,8 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
@@ -751,7 +752,8 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
unsigned target)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
unsigned state;
unsigned char *buf;
size_t len;
@@ -820,7 +822,8 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
CURLcode ret;
DEBUGASSERT(backend);
@@ -842,7 +845,8 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode ret;
@@ -889,7 +893,8 @@ static ssize_t bearssl_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
unsigned char *app;
size_t applen;
@@ -923,7 +928,8 @@ static ssize_t bearssl_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
unsigned char *app;
size_t applen;
@@ -1050,10 +1056,12 @@ static bool bearssl_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct bearssl_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- return br_ssl_engine_current_state(&ctx->backend->ctx.eng) & BR_SSL_RECVAPP;
+ backend = (struct bearssl_ssl_backend_data *)ctx->backend;
+ return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
}
static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
@@ -1101,7 +1109,8 @@ static CURLcode bearssl_connect_nonblocking(struct Curl_cfilter *cf,
static void *bearssl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
return &backend->ctx;
}
@@ -1109,7 +1118,8 @@ static void *bearssl_get_internals(struct ssl_connect_data *connssl,
static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
size_t i;
DEBUGASSERT(backend);
@@ -1147,7 +1157,7 @@ static CURLcode bearssl_sha256sum(const unsigned char *input,
const struct Curl_ssl Curl_ssl_bearssl = {
{ CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct bearssl_ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c
index 79d1851720..4af921092a 100644
--- a/libs/libcurl/src/vtls/gskit.c
+++ b/libs/libcurl/src/vtls/gskit.c
@@ -103,14 +103,14 @@
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
#define CURL_GSKPROTO_LAST 5
-struct ssl_backend_data {
+struct gskit_ssl_backend_data {
gsk_handle handle;
int iocport;
int localfd;
int remotefd;
};
-#define BACKEND connssl->backend
+#define BACKEND ((struct gskit_ssl_backend_data *)connssl->backend)
/* Supported ciphers. */
struct gskit_cipher {
@@ -518,6 +518,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
struct ssl_connect_data *connssl_next = cf_ssl_next?
cf_ssl_next->ctx : NULL;
+ struct gskit_ssl_backend_data *backend_next;
struct pollfd fds[2];
int n;
int m;
@@ -531,6 +532,8 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
return 0; /* No SSL over SSL: OK. */
DEBUGASSERT(connssl_next->backend);
+ backend_next = (struct gskit_ssl_backend_data *)connssl_next->backend;
+
n = 1;
fds[0].fd = BACKEND->remotefd;
fds[1].fd = Curl_conn_cf_get_socket(cf, data);
@@ -550,8 +553,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
if(fds[0].revents & POLLOUT) {
/* Try getting data from HTTPS proxy and pipe it upstream. */
n = 0;
- i = gsk_secure_soc_read(connssl_next->backend->handle,
- buf, sizeof(buf), &n);
+ i = gsk_secure_soc_read(backend_next->handle, buf, sizeof(buf), &n);
switch(i) {
case GSK_OK:
if(n) {
@@ -575,7 +577,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
if(n < 0)
return -1;
if(n) {
- i = gsk_secure_soc_write(connssl_next->backend->handle, buf, n, &m);
+ i = gsk_secure_soc_write(backend_next->handle, buf, n, &m);
if(i != GSK_OK || n != m)
return -1;
ret = 1;
@@ -1294,7 +1296,7 @@ const struct Curl_ssl Curl_ssl_gskit = {
SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct gskit_ssl_backend_data),
gskit_init, /* init */
gskit_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c
index c280cedc78..328e84a520 100644
--- a/libs/libcurl/src/vtls/gtls.c
+++ b/libs/libcurl/src/vtls/gtls.c
@@ -76,7 +76,7 @@ static bool gtls_inited = FALSE;
# include <gnutls/ocsp.h>
-struct ssl_backend_data {
+struct gtls_ssl_backend_data {
struct gtls_instance gtls;
};
@@ -91,7 +91,9 @@ static ssize_t gtls_push(void *s, const void *buf, size_t blen)
DEBUGASSERT(data);
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
if(nwritten < 0) {
- gnutls_transport_set_errno(connssl->backend->gtls.session,
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
+ gnutls_transport_set_errno(backend->gtls.session,
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
nwritten = -1;
}
@@ -109,7 +111,9 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen)
DEBUGASSERT(data);
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
if(nread < 0) {
- gnutls_transport_set_errno(connssl->backend->gtls.session,
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
+ gnutls_transport_set_errno(backend->gtls.session,
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
nread = -1;
}
@@ -212,7 +216,8 @@ static CURLcode handshake(struct Curl_cfilter *cf,
bool nonblocking)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
gnutls_session_t session;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
@@ -679,7 +684,8 @@ static CURLcode
gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
long * const pverifyresult = &ssl_config->certverifyresult;
@@ -1346,7 +1352,8 @@ gtls_connect_common(struct Curl_cfilter *cf,
/* Finish connecting once the handshake is done */
if(ssl_connect_1 == connssl->connecting_state) {
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
gnutls_session_t session;
DEBUGASSERT(backend);
session = backend->gtls.session;
@@ -1390,11 +1397,13 @@ static bool gtls_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct gtls_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->gtls.session &&
- 0 != gnutls_record_check_pending(ctx->backend->gtls.session))
+ backend = (struct gtls_ssl_backend_data *)ctx->backend;
+ if(backend->gtls.session &&
+ 0 != gnutls_record_check_pending(backend->gtls.session))
return TRUE;
return FALSE;
}
@@ -1406,7 +1415,8 @@ static ssize_t gtls_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
ssize_t rc;
(void)data;
@@ -1428,7 +1438,8 @@ static void gtls_close(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
(void) data;
DEBUGASSERT(backend);
@@ -1463,7 +1474,8 @@ static int gtls_shutdown(struct Curl_cfilter *cf,
{
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
int retval = 0;
DEBUGASSERT(backend);
@@ -1541,7 +1553,8 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
ssize_t ret;
(void)data;
@@ -1620,7 +1633,8 @@ static bool gtls_cert_status_request(void)
static void *gtls_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct gtls_ssl_backend_data *backend =
+ (struct gtls_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->gtls.session;
@@ -1634,7 +1648,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct gtls_ssl_backend_data),
gtls_init, /* init */
gtls_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index 7d084af412..4e4fe3f239 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -81,7 +81,7 @@
# endif
#endif
-struct ssl_backend_data {
+struct mbed_ssl_backend_data {
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
mbedtls_ssl_context ssl;
@@ -255,7 +255,8 @@ static CURLcode
set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3;
@@ -307,7 +308,8 @@ static CURLcode
mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
@@ -697,7 +699,8 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
int ret;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const mbedtls_x509_crt *peercert;
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
@@ -860,7 +863,8 @@ mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
CURLcode retcode = CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -915,7 +919,8 @@ static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
(void)data;
@@ -939,7 +944,8 @@ static void mbedtls_close_all(struct Curl_easy *data)
static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
char buf[32];
(void)data;
@@ -968,7 +974,8 @@ static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
ssize_t len = -1;
@@ -1204,10 +1211,12 @@ static bool mbedtls_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct mbed_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- return mbedtls_ssl_get_bytes_avail(&ctx->backend->ssl) != 0;
+ backend = (struct mbed_ssl_backend_data *)ctx->backend;
+ return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
}
static CURLcode mbedtls_sha256sum(const unsigned char *input,
@@ -1234,7 +1243,8 @@ static CURLcode mbedtls_sha256sum(const unsigned char *input,
static void *mbedtls_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct mbed_ssl_backend_data *backend =
+ (struct mbed_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return &backend->ssl;
@@ -1249,7 +1259,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
SSLSUPP_SSL_CTX |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct mbed_ssl_backend_data),
mbedtls_init, /* init */
mbedtls_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c
index 505853c61b..6c1df15ddb 100644
--- a/libs/libcurl/src/vtls/nss.c
+++ b/libs/libcurl/src/vtls/nss.c
@@ -81,7 +81,7 @@
/* enough to fit the string "PEM Token #[0|1]" */
#define SLOTSIZE 13
-struct ssl_backend_data {
+struct nss_ssl_backend_data {
PRFileDesc *handle;
char *client_nickname;
struct Curl_easy *data;
@@ -489,7 +489,8 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl,
const int slot_id = (cacert) ? 0 : 1;
char *slot_name = aprintf("PEM Token #%d", slot_id);
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -806,7 +807,9 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
- struct Curl_easy *data = connssl->backend->data;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ struct Curl_easy *data = backend->data;
DEBUGASSERT(data);
#ifdef SSL_ENABLE_OCSP_STAPLING
@@ -851,7 +854,9 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
struct ssl_connect_data *connssl = cf->ctx;
- struct Curl_easy *data = connssl->backend->data;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ struct Curl_easy *data = backend->data;
unsigned int buflenmax = 50;
unsigned char buf[50];
unsigned int buflen;
@@ -1055,7 +1060,9 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
struct ssl_connect_data *connssl = cf->ctx;
- struct Curl_easy *data = connssl->backend->data;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ struct Curl_easy *data = backend->data;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config;
PRErrorCode err = PR_GetError();
@@ -1117,7 +1124,8 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
const char *pinnedpubkey)
{
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = NULL;
CERTCertificate *cert;
@@ -1173,7 +1181,8 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
struct SECKEYPrivateKeyStr **pRetKey)
{
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = NULL;
const char *nickname = NULL;
static const char pem_slotname[] = "PEM Token #1";
@@ -1538,7 +1547,8 @@ static void nss_cleanup(void)
static void close_one(struct ssl_connect_data *connssl)
{
/* before the cleanup, check whether we are using a client certificate */
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
bool client_cert = true;
DEBUGASSERT(backend);
@@ -1580,7 +1590,8 @@ static void close_one(struct ssl_connect_data *connssl)
static void nss_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -1796,7 +1807,8 @@ static CURLcode nss_fail_connect(struct Curl_cfilter *cf,
CURLcode curlerr)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -1826,7 +1838,8 @@ static CURLcode nss_set_blocking(struct Curl_cfilter *cf,
{
struct ssl_connect_data *connssl = cf->ctx;
PRSocketOptionData sock_opt;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -1849,7 +1862,8 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
PRBool ssl_cbc_random_iv;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
@@ -2031,14 +2045,16 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
/* Is there an SSL filter "in front" of us or are we writing directly
* to the socket? */
if(connssl_next) {
+ struct nss_ssl_backend_data *backend_next =
+ (struct nss_ssl_backend_data *)connssl_next->backend;
/* The filter should be connected by now, with full handshake */
- DEBUGASSERT(connssl_next->backend->handle);
+ DEBUGASSERT(backend_next->handle);
DEBUGASSERT(ssl_connection_complete == connssl_next->state);
/* We tell our NSS instance to use do IO with the 'next' NSS
* instance. This NSS instance will take ownership of the next
* one, including its destruction. We therefore need to `disown`
* the next filter's handle, once import succeeds. */
- nspr_io = connssl_next->backend->handle;
+ nspr_io = backend->handle;
second_layer = TRUE;
}
else {
@@ -2077,8 +2093,11 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
PR_Close(model); /* We don't need this any more */
model = NULL;
- if(connssl_next) /* steal the NSS handle we just imported successfully */
- connssl_next->backend->handle = NULL;
+ if(connssl_next) { /* steal the NSS handle we just imported successfully */
+ struct nss_ssl_backend_data *backend_next =
+ (struct nss_ssl_backend_data *)connssl_next->backend;
+ backend_next->handle = NULL;
+ }
/* This is the password associated with the cert that we're using */
if(ssl_config->key_passwd) {
@@ -2154,7 +2173,8 @@ static CURLcode nss_do_connect(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_SSL_CONNECT_ERROR;
@@ -2299,7 +2319,8 @@ static ssize_t nss_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
ssize_t rc;
(void)data;
@@ -2337,7 +2358,9 @@ static bool
nss_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- PRFileDesc *fd = connssl->backend->handle->lower;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
+ PRFileDesc *fd = backend->handle->lower;
char buf;
(void) data;
@@ -2353,7 +2376,8 @@ static ssize_t nss_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
ssize_t nread;
(void)data;
@@ -2455,7 +2479,8 @@ static bool nss_false_start(void)
static void *nss_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->handle;
@@ -2465,9 +2490,11 @@ static bool nss_attach_data(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
- if(!connssl->backend->data)
- connssl->backend->data = data;
+ if(!backend->data)
+ backend->data = data;
return TRUE;
}
@@ -2475,9 +2502,11 @@ static void nss_detach_data(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
+ struct nss_ssl_backend_data *backend =
+ (struct nss_ssl_backend_data *)connssl->backend;
- if(connssl->backend->data == data)
- connssl->backend->data = NULL;
+ if(backend->data == data)
+ backend->data = NULL;
}
const struct Curl_ssl Curl_ssl_nss = {
@@ -2488,7 +2517,7 @@ const struct Curl_ssl Curl_ssl_nss = {
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct nss_ssl_backend_data),
nss_init, /* init */
nss_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 470daedb2c..1b48688d1c 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -288,7 +288,7 @@ typedef unsigned long sslerr_t;
#define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
#endif /* !LIBRESSL_VERSION_NUMBER */
-struct ssl_backend_data {
+struct ossl_ssl_backend_data {
/* these ones requires specific SSL-types */
SSL_CTX* ctx;
SSL* handle;
@@ -714,6 +714,8 @@ static int bio_cf_out_write(BIO *bio, const char *buf, int blen)
{
struct Curl_cfilter *cf = BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
CURLcode result = CURLE_SEND_ERROR;
@@ -723,7 +725,7 @@ static int bio_cf_out_write(BIO *bio, const char *buf, int blen)
DEBUGF(LOG_CF(data, cf, "bio_cf_out_write(len=%d) -> %d, err=%d",
blen, (int)nwritten, result));
BIO_clear_retry_flags(bio);
- connssl->backend->io_result = result;
+ backend->io_result = result;
if(nwritten < 0) {
if(CURLE_AGAIN == result)
BIO_set_retry_write(bio);
@@ -735,6 +737,8 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
{
struct Curl_cfilter *cf = BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
CURLcode result = CURLE_RECV_ERROR;
@@ -748,7 +752,7 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
DEBUGF(LOG_CF(data, cf, "bio_cf_in_read(len=%d) -> %d, err=%d",
blen, (int)nread, result));
BIO_clear_retry_flags(bio);
- connssl->backend->io_result = result;
+ backend->io_result = result;
if(nread < 0) {
if(CURLE_AGAIN == result)
BIO_set_retry_read(bio);
@@ -756,13 +760,13 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
/* Before returning server replies to the SSL instance, we need
* to have setup the x509 store or verification will fail. */
- if(!connssl->backend->x509_store_setup) {
- result = Curl_ssl_setup_x509_store(cf, data, connssl->backend->ctx);
+ if(!backend->x509_store_setup) {
+ result = Curl_ssl_setup_x509_store(cf, data, backend->ctx);
if(result) {
- connssl->backend->io_result = result;
+ backend->io_result = result;
return -1;
}
- connssl->backend->x509_store_setup = TRUE;
+ backend->x509_store_setup = TRUE;
}
return (int)nread;
@@ -1877,7 +1881,8 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data)
static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -1923,7 +1928,8 @@ static int ossl_shutdown(struct Curl_cfilter *cf,
int buffsize;
int err;
bool done = FALSE;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
int loop = 10;
DEBUGASSERT(backend);
@@ -2321,7 +2327,8 @@ static CURLcode verifystatus(struct Curl_cfilter *cf,
OCSP_BASICRESP *br = NULL;
X509_STORE *st = NULL;
STACK_OF(X509) *ch = NULL;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
X509 *cert;
OCSP_CERTID *id = NULL;
int cert_status, crl_reason;
@@ -2713,7 +2720,7 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
static CURLcode
-set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
+ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
/* first, TLS min version... */
@@ -2810,9 +2817,9 @@ typedef long ctx_option_t;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
static CURLcode
-set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
- struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ossl_set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
@@ -2825,8 +2832,10 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
#ifdef TLS1_3_VERSION
{
struct ssl_connect_data *connssl = cf->ctx;
- DEBUGASSERT(connssl->backend);
- SSL_CTX_set_max_proto_version(connssl->backend->ctx, TLS1_3_VERSION);
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
+ DEBUGASSERT(backend);
+ SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2;
}
#else
@@ -3431,7 +3440,8 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
const char * const ssl_cert_type = ssl_config->cert_type;
const bool verifypeer = conn_config->verifypeer;
char error_buffer[256];
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
DEBUGASSERT(backend);
@@ -3573,9 +3583,9 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
ctx_options |= SSL_OP_NO_SSLv3;
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
- result = set_ssl_version_min_max(cf, backend->ctx);
+ result = ossl_set_ssl_version_min_max(cf, backend->ctx);
#else
- result = set_ssl_version_min_max_legacy(&ctx_options, cf, data);
+ result = ossl_set_ssl_version_min_max_legacy(&ctx_options, cf, data);
#endif
if(result != CURLE_OK)
return result;
@@ -3804,7 +3814,8 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
{
int err;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -3967,8 +3978,8 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
*/
-static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
- const char *pinnedpubkey)
+static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
+ const char *pinnedpubkey)
{
/* Scratch */
int len1 = 0, len2 = 0;
@@ -4046,7 +4057,8 @@ static CURLcode servercert(struct Curl_cfilter *cf,
char buffer[2048];
const char *ptr;
BIO *mem = BIO_new(BIO_s_mem());
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -4061,7 +4073,7 @@ static CURLcode servercert(struct Curl_cfilter *cf,
if(data->set.ssl.certinfo)
/* asked to gather certificate info */
- (void)Curl_ossl_certchain(data, connssl->backend->handle);
+ (void)Curl_ossl_certchain(data, backend->handle);
backend->server_cert = SSL_get1_peer_certificate(backend->handle);
if(!backend->server_cert) {
@@ -4229,7 +4241,7 @@ static CURLcode servercert(struct Curl_cfilter *cf,
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
- result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
+ result = ossl_pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result)
failf(data, "SSL: public key does not match pinned public key");
}
@@ -4398,11 +4410,13 @@ static CURLcode ossl_connect(struct Curl_cfilter *cf,
static bool ossl_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
- struct ssl_connect_data *ctx = cf->ctx;
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
- DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->handle && SSL_pending(ctx->backend->handle))
+ DEBUGASSERT(connssl && backend);
+ if(backend->handle && SSL_pending(backend->handle))
return TRUE;
return FALSE;
}
@@ -4421,7 +4435,8 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
int memlen;
int rc;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -4517,7 +4532,8 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
int buffsize;
struct connectdata *conn = cf->conn;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
@@ -4740,7 +4756,8 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info)
{
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
- struct ssl_backend_data *backend = connssl->backend;
+ struct ossl_ssl_backend_data *backend =
+ (struct ossl_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
return info == CURLINFO_TLS_SESSION ?
(void *)backend->ctx : (void *)backend->handle;
@@ -4773,7 +4790,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
#endif
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct ossl_ssl_backend_data),
ossl_init, /* init */
ossl_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c
index 36e966eec5..d928b9d08a 100644
--- a/libs/libcurl/src/vtls/rustls.c
+++ b/libs/libcurl/src/vtls/rustls.c
@@ -40,7 +40,7 @@
#include "strerror.h"
#include "multiif.h"
-struct ssl_backend_data
+struct rustls_ssl_backend_data
{
const struct rustls_client_config *config;
struct rustls_connection *conn;
@@ -67,10 +67,12 @@ static bool
cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct rustls_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- return ctx->backend->data_pending;
+ backend = (struct rustls_ssl_backend_data *)ctx->backend;
+ return backend->data_pending;
}
static CURLcode
@@ -136,7 +138,8 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf,
struct Curl_easy *data, CURLcode *err)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct io_ctx io_ctx;
size_t tls_bytes_read = 0;
rustls_io_result io_error;
@@ -191,7 +194,8 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *plainbuf, size_t plainlen, CURLcode *err)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
size_t n = 0;
size_t plain_bytes_copied = 0;
@@ -283,7 +287,8 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *plainbuf, size_t plainlen, CURLcode *err)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
struct io_ctx io_ctx;
size_t plainwritten = 0;
@@ -373,7 +378,7 @@ cr_hostname_is_ip(const char *hostname)
static CURLcode
cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
- struct ssl_backend_data *const backend)
+ struct rustls_ssl_backend_data *const backend)
{
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
@@ -491,7 +496,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
{
struct ssl_connect_data *const connssl = cf->ctx;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
CURLcode tmperr = CURLE_OK;
int result;
@@ -504,7 +510,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
DEBUGASSERT(backend);
if(ssl_connection_none == connssl->state) {
- result = cr_init_backend(cf, data, connssl->backend);
+ result = cr_init_backend(cf, data,
+ (struct rustls_ssl_backend_data *)connssl->backend);
if(result != CURLE_OK) {
return result;
}
@@ -594,7 +601,8 @@ cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
{
struct ssl_connect_data *const connssl = cf->ctx;
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
- struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_ssl_backend_data *const backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
(void)data;
@@ -617,7 +625,8 @@ static void *
cr_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct rustls_ssl_backend_data *backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
return &backend->conn;
}
@@ -626,7 +635,8 @@ static void
cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct rustls_ssl_backend_data *backend =
+ (struct rustls_ssl_backend_data *)connssl->backend;
CURLcode tmperr = CURLE_OK;
ssize_t n = 0;
@@ -659,7 +669,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
SSLSUPP_CAINFO_BLOB | /* supports */
SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct rustls_ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 68cead586b..d1b372ba47 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -33,13 +33,12 @@
#ifdef USE_SCHANNEL
-#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
-
#ifndef USE_WINDOWS_SSPI
# error "Can't compile SCHANNEL support without SSPI."
#endif
#include "schannel.h"
+#include "schannel_int.h"
#include "vtls.h"
#include "vtls_int.h"
#include "strcase.h"
@@ -186,9 +185,9 @@
#define PKCS12_NO_PERSIST_KEY 0x00008000
#endif
-static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char *pinnedpubkey);
+static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char *pinnedpubkey);
static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
void *BufDataPtr, unsigned long BufByteSize)
@@ -207,9 +206,9 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
}
static CURLcode
-set_ssl_version_min_max(DWORD *enabled_protocols,
- struct Curl_cfilter *cf,
- struct Curl_easy *data)
+schannel_set_ssl_version_min_max(DWORD *enabled_protocols,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
@@ -500,7 +499,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
DWORD flags = 0;
DWORD enabled_protocols = 0;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)(connssl->backend);
DEBUGASSERT(backend);
@@ -563,7 +563,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- result = set_ssl_version_min_max(&enabled_protocols, cf, data);
+ result = schannel_set_ssl_version_min_max(&enabled_protocols, cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -1075,7 +1075,8 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
ssize_t written = -1;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SecBuffer outbuf;
@@ -1349,7 +1350,8 @@ static CURLcode
schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
int i;
ssize_t nread = -1, written = -1;
@@ -1607,7 +1609,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(pubkey_ptr) {
- result = pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
+ result = schannel_pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
if(result) {
failf(data, "SSL: public key does not match pinned public key");
return result;
@@ -1686,7 +1688,8 @@ static CURLcode
schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_OK;
SECURITY_STATUS sspi_status = SEC_E_OK;
@@ -1931,7 +1934,8 @@ schannel_connect_common(struct Curl_cfilter *cf,
* Available on Windows 7 or later.
*/
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
cf->conn->sslContext = &backend->ctxt->ctxt_handle;
}
@@ -1960,7 +1964,8 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -2110,7 +2115,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
/* we want the length of the encrypted buffer to be at least large enough
that it can hold all the bytes requested and some TLS record overhead. */
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
@@ -2443,12 +2449,13 @@ static bool schannel_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
const struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
(void)data;
DEBUGASSERT(backend);
- if(connssl->backend->ctxt) /* SSL/TLS is in use */
+ if(backend->ctxt) /* SSL/TLS is in use */
return (backend->decdata_offset > 0 ||
(backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
else
@@ -2486,12 +2493,13 @@ static int schannel_shutdown(struct Curl_cfilter *cf,
* Shutting Down an Schannel Connection
*/
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(data);
DEBUGASSERT(backend);
- if(connssl->backend->ctxt) {
+ if(backend->ctxt) {
infof(data, "schannel: shutting down SSL/TLS connection with %s port %d",
connssl->hostname, connssl->port);
}
@@ -2611,12 +2619,13 @@ static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM,
return Curl_win32_random(entropy, length);
}
-static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- const char *pinnedpubkey)
+static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char *pinnedpubkey)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
CERT_CONTEXT *pCertContextServer = NULL;
/* Result is returned to caller */
@@ -2742,7 +2751,8 @@ static CURLcode schannel_sha256sum(const unsigned char *input,
static void *schannel_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct schannel_ssl_backend_data *backend =
+ (struct schannel_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return &backend->ctxt->ctxt_handle;
@@ -2759,7 +2769,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct schannel_ssl_backend_data),
schannel_init, /* init */
schannel_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h
index 1cdb659d1d..b6b9101c78 100644
--- a/libs/libcurl/src/vtls/schannel.h
+++ b/libs/libcurl/src/vtls/schannel.h
@@ -28,8 +28,6 @@
#ifdef USE_SCHANNEL
-#define SCHANNEL_USE_BLACKLISTS 1
-
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4201)
@@ -81,119 +79,5 @@ extern const struct Curl_ssl Curl_ssl_schannel;
CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
struct Curl_easy *data);
-/* structs to expose only in schannel.c and schannel_verify.c */
-#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
-
-#ifdef __MINGW32__
-#ifdef __MINGW64_VERSION_MAJOR
-#define HAS_MANUAL_VERIFY_API
-#endif
-#else
-#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
-#define HAS_MANUAL_VERIFY_API
-#endif
-#endif
-
-#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
- && !defined(DISABLE_SCHANNEL_CLIENT_CERT)
-#define HAS_CLIENT_CERT_PATH
-#endif
-
-#ifndef SCH_CREDENTIALS_VERSION
-
-#define SCH_CREDENTIALS_VERSION 0x00000005
-
-typedef enum _eTlsAlgorithmUsage
-{
- TlsParametersCngAlgUsageKeyExchange,
- TlsParametersCngAlgUsageSignature,
- TlsParametersCngAlgUsageCipher,
- TlsParametersCngAlgUsageDigest,
- TlsParametersCngAlgUsageCertSig
-} eTlsAlgorithmUsage;
-
-typedef struct _CRYPTO_SETTINGS
-{
- eTlsAlgorithmUsage eAlgorithmUsage;
- UNICODE_STRING strCngAlgId;
- DWORD cChainingModes;
- PUNICODE_STRING rgstrChainingModes;
- DWORD dwMinBitLength;
- DWORD dwMaxBitLength;
-} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
-
-typedef struct _TLS_PARAMETERS
-{
- DWORD cAlpnIds;
- PUNICODE_STRING rgstrAlpnIds;
- DWORD grbitDisabledProtocols;
- DWORD cDisabledCrypto;
- PCRYPTO_SETTINGS pDisabledCrypto;
- DWORD dwFlags;
-} TLS_PARAMETERS, * PTLS_PARAMETERS;
-
-typedef struct _SCH_CREDENTIALS
-{
- DWORD dwVersion;
- DWORD dwCredFormat;
- DWORD cCreds;
- PCCERT_CONTEXT* paCred;
- HCERTSTORE hRootStore;
-
- DWORD cMappers;
- struct _HMAPPER **aphMappers;
-
- DWORD dwSessionLifespan;
- DWORD dwFlags;
- DWORD cTlsParameters;
- PTLS_PARAMETERS pTlsParameters;
-} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
-
-#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
-#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
-#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
-#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
-
-#endif
-
-struct Curl_schannel_cred {
- CredHandle cred_handle;
- TimeStamp time_stamp;
- TCHAR *sni_hostname;
-#ifdef HAS_CLIENT_CERT_PATH
- HCERTSTORE client_cert_store;
-#endif
- int refcount;
-};
-
-struct Curl_schannel_ctxt {
- CtxtHandle ctxt_handle;
- TimeStamp time_stamp;
-};
-
-struct ssl_backend_data {
- struct Curl_schannel_cred *cred;
- struct Curl_schannel_ctxt *ctxt;
- SecPkgContext_StreamSizes stream_sizes;
- size_t encdata_length, decdata_length;
- size_t encdata_offset, decdata_offset;
- unsigned char *encdata_buffer, *decdata_buffer;
- /* encdata_is_incomplete: if encdata contains only a partial record that
- can't be decrypted without another recv() (that is, status is
- SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
- more bytes into encdata then set this back to false. */
- bool encdata_is_incomplete;
- unsigned long req_flags, ret_flags;
- CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
- bool recv_sspi_close_notify; /* true if connection closed by close_notify */
- bool recv_connection_closed; /* true if connection closed, regardless how */
- bool recv_renegotiating; /* true if recv is doing renegotiation */
- bool use_alpn; /* true if ALPN is used for this connection */
-#ifdef HAS_MANUAL_VERIFY_API
- bool use_manual_cred_validation; /* true if manual cred validation is used */
-#endif
-};
-#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
-
#endif /* USE_SCHANNEL */
#endif /* HEADER_CURL_SCHANNEL_H */
diff --git a/libs/libcurl/src/vtls/schannel_int.h b/libs/libcurl/src/vtls/schannel_int.h
new file mode 100644
index 0000000000..e158cadc86
--- /dev/null
+++ b/libs/libcurl/src/vtls/schannel_int.h
@@ -0,0 +1,142 @@
+#ifndef HEADER_CURL_SCHANNEL_INT_H
+#define HEADER_CURL_SCHANNEL_INT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Marc Hoersken, <info@marc-hoersken.de>, et al.
+ * Copyright (C) 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
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#ifdef __MINGW32__
+#ifdef __MINGW64_VERSION_MAJOR
+#define HAS_MANUAL_VERIFY_API
+#endif
+#else
+#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
+#define HAS_MANUAL_VERIFY_API
+#endif
+#endif
+
+#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
+ && !defined(DISABLE_SCHANNEL_CLIENT_CERT)
+#define HAS_CLIENT_CERT_PATH
+#endif
+
+#ifndef SCH_CREDENTIALS_VERSION
+
+#define SCH_CREDENTIALS_VERSION 0x00000005
+
+typedef enum _eTlsAlgorithmUsage
+{
+ TlsParametersCngAlgUsageKeyExchange,
+ TlsParametersCngAlgUsageSignature,
+ TlsParametersCngAlgUsageCipher,
+ TlsParametersCngAlgUsageDigest,
+ TlsParametersCngAlgUsageCertSig
+} eTlsAlgorithmUsage;
+
+typedef struct _CRYPTO_SETTINGS
+{
+ eTlsAlgorithmUsage eAlgorithmUsage;
+ UNICODE_STRING strCngAlgId;
+ DWORD cChainingModes;
+ PUNICODE_STRING rgstrChainingModes;
+ DWORD dwMinBitLength;
+ DWORD dwMaxBitLength;
+} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
+
+typedef struct _TLS_PARAMETERS
+{
+ DWORD cAlpnIds;
+ PUNICODE_STRING rgstrAlpnIds;
+ DWORD grbitDisabledProtocols;
+ DWORD cDisabledCrypto;
+ PCRYPTO_SETTINGS pDisabledCrypto;
+ DWORD dwFlags;
+} TLS_PARAMETERS, * PTLS_PARAMETERS;
+
+typedef struct _SCH_CREDENTIALS
+{
+ DWORD dwVersion;
+ DWORD dwCredFormat;
+ DWORD cCreds;
+ PCCERT_CONTEXT* paCred;
+ HCERTSTORE hRootStore;
+
+ DWORD cMappers;
+ struct _HMAPPER **aphMappers;
+
+ DWORD dwSessionLifespan;
+ DWORD dwFlags;
+ DWORD cTlsParameters;
+ PTLS_PARAMETERS pTlsParameters;
+} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
+
+#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
+#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
+#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
+#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
+
+#endif /* SCH_CREDENTIALS_VERSION */
+
+struct Curl_schannel_cred {
+ CredHandle cred_handle;
+ TimeStamp time_stamp;
+ TCHAR *sni_hostname;
+#ifdef HAS_CLIENT_CERT_PATH
+ HCERTSTORE client_cert_store;
+#endif
+ int refcount;
+};
+
+struct Curl_schannel_ctxt {
+ CtxtHandle ctxt_handle;
+ TimeStamp time_stamp;
+};
+
+struct schannel_ssl_backend_data {
+ struct Curl_schannel_cred *cred;
+ struct Curl_schannel_ctxt *ctxt;
+ SecPkgContext_StreamSizes stream_sizes;
+ size_t encdata_length, decdata_length;
+ size_t encdata_offset, decdata_offset;
+ unsigned char *encdata_buffer, *decdata_buffer;
+ /* encdata_is_incomplete: if encdata contains only a partial record that
+ can't be decrypted without another recv() (that is, status is
+ SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
+ more bytes into encdata then set this back to false. */
+ bool encdata_is_incomplete;
+ unsigned long req_flags, ret_flags;
+ CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
+ bool recv_sspi_close_notify; /* true if connection closed by close_notify */
+ bool recv_connection_closed; /* true if connection closed, regardless how */
+ bool recv_renegotiating; /* true if recv is doing renegotiation */
+ bool use_alpn; /* true if ALPN is used for this connection */
+#ifdef HAS_MANUAL_VERIFY_API
+ bool use_manual_cred_validation; /* true if manual cred validation is used */
+#endif
+};
+
+#endif /* USE_SCHANNEL */
+#endif /* HEADER_CURL_SCHANNEL_INT_H */
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index 662dfbaff0..c8a589948a 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -36,8 +36,8 @@
# error "Can't compile SCHANNEL support without SSPI."
#endif
-#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
#include "schannel.h"
+#include "schannel_int.h"
#ifdef HAS_MANUAL_VERIFY_API
@@ -54,7 +54,7 @@
#include "curl_memory.h"
#include "memdebug.h"
-#define BACKEND connssl->backend
+#define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend)
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index b718c84adf..23dc830b82 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -146,7 +146,7 @@
#define ioErr -36
#define paramErr -50
-struct ssl_backend_data {
+struct st_ssl_backend_data {
SSLContextRef ssl_ctx;
bool ssl_direction; /* true if writing, false if reading */
size_t ssl_write_buffered_length;
@@ -836,7 +836,8 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
CURLcode result;
@@ -859,6 +860,9 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
}
nread = 0;
}
+ else if(nread == 0) {
+ rtn = errSSLClosedGraceful;
+ }
else if((size_t)nread < *dataLength) {
rtn = errSSLWouldBlock;
}
@@ -872,7 +876,8 @@ static OSStatus bio_cf_out_write(SSLConnectionRef connection,
{
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
CURLcode result;
@@ -1338,7 +1343,8 @@ static CURLcode set_ssl_version_min_max(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
long ssl_version = conn_config->version;
long ssl_version_max = conn_config->version_max;
@@ -1633,7 +1639,8 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
const struct curl_blob *ssl_cablob = conn_config->ca_info_blob;
@@ -2515,7 +2522,8 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
OSStatus err;
SSLCipherSuite cipher;
@@ -2896,7 +2904,8 @@ static CURLcode collect_server_cert(struct Curl_cfilter *cf,
CURLcode result = ssl_config->certinfo ?
CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
OSStatus err;
@@ -3139,7 +3148,8 @@ static CURLcode sectransp_connect(struct Curl_cfilter *cf,
static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
(void) data;
@@ -3166,7 +3176,8 @@ static int sectransp_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
ssize_t nread;
int what;
int rc;
@@ -3244,7 +3255,8 @@ static bool sectransp_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
const struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
OSStatus err;
size_t buffer;
@@ -3308,7 +3320,8 @@ static ssize_t sectransp_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
size_t processed = 0UL;
OSStatus err;
@@ -3376,7 +3389,8 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
size_t processed = 0UL;
OSStatus err;
@@ -3434,7 +3448,8 @@ again:
static void *sectransp_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct st_ssl_backend_data *backend =
+ (struct st_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->ssl_ctx;
@@ -3450,7 +3465,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
#endif /* SECTRANSP_PINNEDPUBKEY */
SSLSUPP_HTTPS_PROXY,
- sizeof(struct ssl_backend_data),
+ sizeof(struct st_ssl_backend_data),
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c
index 5068bc2aaf..20beeacb02 100644
--- a/libs/libcurl/src/vtls/vtls.c
+++ b/libs/libcurl/src/vtls/vtls.c
@@ -453,7 +453,7 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf,
}
}
- DEBUGF(infof(data, DMSG(data, "%s Session ID in cache for %s %s://%s:%d"),
+ DEBUGF(infof(data, "%s Session ID in cache for %s %s://%s:%d",
no_match? "Didn't find": "Found",
Curl_ssl_cf_is_proxy(cf) ? "proxy" : "host",
cf->conn->handler->scheme, connssl->hostname, connssl->port));
@@ -601,8 +601,8 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
if(added)
*added = TRUE;
- DEBUGF(infof(data, DMSG(data, "Added Session ID to cache for %s://%s:%d"
- " [%s]"), store->scheme, store->name, store->remote_port,
+ DEBUGF(infof(data, "Added Session ID to cache for %s://%s:%d [%s]",
+ store->scheme, store->name, store->remote_port,
Curl_ssl_cf_is_proxy(cf) ? "PROXY" : "server"));
return CURLE_OK;
}
@@ -893,8 +893,8 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
/* only do this if pinnedpubkey starts with "sha256//", length 8 */
if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
CURLcode encode;
- size_t encodedlen, pinkeylen;
- char *encoded, *pinkeycopy, *begin_pos, *end_pos;
+ size_t encodedlen = 0, pinkeylen;
+ char *encoded = NULL, *pinkeycopy, *begin_pos, *end_pos;
unsigned char *sha256sumdigest;
if(!Curl_ssl->sha256sum) {
@@ -907,14 +907,12 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
if(!sha256sumdigest)
return CURLE_OUT_OF_MEMORY;
encode = Curl_ssl->sha256sum(pubkey, pubkeylen,
- sha256sumdigest, CURL_SHA256_DIGEST_LENGTH);
+ sha256sumdigest, CURL_SHA256_DIGEST_LENGTH);
- if(encode != CURLE_OK)
- return encode;
-
- encode = Curl_base64_encode((char *)sha256sumdigest,
- CURL_SHA256_DIGEST_LENGTH, &encoded,
- &encodedlen);
+ if(!encode)
+ encode = Curl_base64_encode((char *)sha256sumdigest,
+ CURL_SHA256_DIGEST_LENGTH, &encoded,
+ &encodedlen);
Curl_safefree(sha256sumdigest);
if(encode)
@@ -1594,6 +1592,7 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
ssize_t nread;
CF_DATA_SAVE(save, cf, data);
+ *err = CURLE_OK;
nread = Curl_ssl->recv_plain(cf, data, buf, len, err);
if(nread > 0) {
DEBUGASSERT((size_t)nread <= len);
diff --git a/libs/libcurl/src/vtls/vtls_int.h b/libs/libcurl/src/vtls/vtls_int.h
index 31b57fd37a..cdfca617a3 100644
--- a/libs/libcurl/src/vtls/vtls_int.h
+++ b/libs/libcurl/src/vtls/vtls_int.h
@@ -73,7 +73,7 @@ struct ssl_connect_data {
char *hostname; /* hostname for verification */
char *dispname; /* display version of hostname */
const struct alpn_spec *alpn; /* ALPN to use or NULL for none */
- struct ssl_backend_data *backend; /* vtls backend specific props */
+ void *backend; /* vtls backend specific props */
struct cf_call_data call_data; /* data handle used in current call */
struct curltime handshake_done; /* time when handshake finished */
int port; /* remote port at origin */
@@ -81,6 +81,7 @@ struct ssl_connect_data {
};
+#undef CF_CTX_CALL_DATA
#define CF_CTX_CALL_DATA(cf) \
((struct ssl_connect_data *)(cf)->ctx)->call_data
diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c
index 5ed483815b..fc4843790a 100644
--- a/libs/libcurl/src/vtls/wolfssl.c
+++ b/libs/libcurl/src/vtls/wolfssl.c
@@ -91,7 +91,7 @@
#undef USE_BIO_CHAIN
#endif
-struct ssl_backend_data {
+struct wolfssl_ssl_backend_data {
SSL_CTX* ctx;
SSL* handle;
CURLcode io_result; /* result of last BIO cfilter operation */
@@ -281,13 +281,15 @@ static int bio_cf_out_write(WOLFSSL_BIO *bio, const char *buf, int blen)
{
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nwritten;
CURLcode result = CURLE_OK;
DEBUGASSERT(data);
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
- connssl->backend->io_result = result;
+ backend->io_result = result;
DEBUGF(LOG_CF(data, cf, "bio_write(len=%d) -> %zd, %d",
blen, nwritten, result));
wolfSSL_BIO_clear_retry_flags(bio);
@@ -300,6 +302,8 @@ static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
{
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
struct ssl_connect_data *connssl = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct Curl_easy *data = CF_DATA_CURRENT(cf);
ssize_t nread;
CURLcode result = CURLE_OK;
@@ -310,7 +314,7 @@ static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
return 0;
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
- connssl->backend->io_result = result;
+ backend->io_result = result;
DEBUGF(LOG_CF(data, cf, "bio_read(len=%d) -> %zd, %d",
blen, nread, result));
wolfSSL_BIO_clear_retry_flags(bio);
@@ -352,8 +356,10 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
char *ciphers, *curves;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SSL_METHOD* req_method = NULL;
#ifdef HAVE_LIBOQS
@@ -366,6 +372,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
#else
#define use_sni(x) Curl_nop_stmt
#endif
+ bool imported_ca_info_blob = false;
DEBUGASSERT(backend);
@@ -410,8 +417,13 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
#endif
break;
case CURL_SSLVERSION_TLSv1_2:
+#ifndef WOLFSSL_NO_TLS12
req_method = TLSv1_2_client_method();
use_sni(TRUE);
+#else
+ failf(data, "wolfSSL does not support TLS 1.2");
+ return CURLE_NOT_BUILT_IN;
+#endif
break;
case CURL_SSLVERSION_TLSv1_3:
#ifdef WOLFSSL_TLS13
@@ -494,13 +506,28 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
}
}
}
+
+ if(ca_info_blob) {
+ if(wolfSSL_CTX_load_verify_buffer(
+ backend->ctx, ca_info_blob->data, ca_info_blob->len,
+ SSL_FILETYPE_PEM
+ ) != SSL_SUCCESS) {
+ failf(data, "error importing CA certificate blob");
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else {
+ imported_ca_info_blob = true;
+ infof(data, "successfully imported CA certificate blob");
+ }
+ }
+
#ifndef NO_FILESYSTEM
/* load trusted cacert */
if(conn_config->CAfile) {
if(1 != SSL_CTX_load_verify_locations(backend->ctx,
conn_config->CAfile,
conn_config->CApath)) {
- if(conn_config->verifypeer) {
+ if(conn_config->verifypeer && !imported_ca_info_blob) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:"
" CAfile: %s CApath: %s",
@@ -699,7 +726,8 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
int ret = -1;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
@@ -892,7 +920,8 @@ wolfssl_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -950,7 +979,8 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
int rc;
@@ -992,7 +1022,8 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf,
static void wolfssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
(void) data;
@@ -1019,7 +1050,8 @@ static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int buffsize = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
int nread;
@@ -1108,11 +1140,14 @@ static bool wolfssl_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->handle) /* SSL is in use */
- return (0 != SSL_pending(ctx->backend->handle)) ? TRUE : FALSE;
+
+ backend = (struct wolfssl_ssl_backend_data *)ctx->backend;
+ if(backend->handle) /* SSL is in use */
+ return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
else
return FALSE;
}
@@ -1126,15 +1161,17 @@ static int wolfssl_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct ssl_connect_data *ctx = cf->ctx;
+ struct wolfssl_ssl_backend_data *backend;
int retval = 0;
(void)data;
DEBUGASSERT(ctx && ctx->backend);
- if(ctx->backend->handle) {
+ backend = (struct wolfssl_ssl_backend_data *)ctx->backend;
+ if(backend->handle) {
ERR_clear_error();
- SSL_free(ctx->backend->handle);
- ctx->backend->handle = NULL;
+ SSL_free(backend->handle);
+ backend->handle = NULL;
}
return retval;
}
@@ -1305,7 +1342,8 @@ static CURLcode wolfssl_sha256sum(const unsigned char *tmp, /* input */
static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
- struct ssl_backend_data *backend = connssl->backend;
+ struct wolfssl_ssl_backend_data *backend =
+ (struct wolfssl_ssl_backend_data *)connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->handle;
@@ -1320,9 +1358,10 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
#ifdef USE_BIO_CHAIN
SSLSUPP_HTTPS_PROXY |
#endif
+ SSLSUPP_CAINFO_BLOB |
SSLSUPP_SSL_CTX,
- sizeof(struct ssl_backend_data),
+ sizeof(struct wolfssl_ssl_backend_data),
wolfssl_init, /* init */
wolfssl_cleanup, /* cleanup */
diff --git a/libs/libcurl/src/warnless.c b/libs/libcurl/src/warnless.c
index 0ded8c2391..1424745edd 100644
--- a/libs/libcurl/src/warnless.c
+++ b/libs/libcurl/src/warnless.c
@@ -35,10 +35,13 @@
#endif /* __INTEL_COMPILER && __unix__ */
-#define BUILDING_WARNLESS_C 1
-
#include "warnless.h"
+#ifdef WIN32
+#undef read
+#undef write
+#endif
+
#include <limits.h>
#define CURL_MASK_UCHAR ((unsigned char)~0)
@@ -376,6 +379,9 @@ ssize_t curlx_write(int fd, const void *buf, size_t count)
return (ssize_t)write(fd, buf, curlx_uztoui(count));
}
+/* Ensure that warnless.h continues to have an effect in "unity" builds. */
+#undef HEADER_CURL_WARNLESS_H
+
#endif /* WIN32 */
#if defined(__INTEL_COMPILER) && defined(__unix__)
diff --git a/libs/libcurl/src/warnless.h b/libs/libcurl/src/warnless.h
index 43d15b946b..02301db792 100644
--- a/libs/libcurl/src/warnless.h
+++ b/libs/libcurl/src/warnless.h
@@ -75,12 +75,10 @@ ssize_t curlx_read(int fd, void *buf, size_t count);
ssize_t curlx_write(int fd, const void *buf, size_t count);
-#ifndef BUILDING_WARNLESS_C
-# undef read
-# define read(fd, buf, count) curlx_read(fd, buf, count)
-# undef write
-# define write(fd, buf, count) curlx_write(fd, buf, count)
-#endif
+#undef read
+#define read(fd, buf, count) curlx_read(fd, buf, count)
+#undef write
+#define write(fd, buf, count) curlx_write(fd, buf, count)
#endif /* WIN32 */
diff --git a/libs/libcurl/src/ws.c b/libs/libcurl/src/ws.c
index 2d3b3bcf53..47f26be9e6 100644
--- a/libs/libcurl/src/ws.c
+++ b/libs/libcurl/src/ws.c
@@ -126,8 +126,9 @@ static void ws_dec_info(struct ws_decoder *dec, struct Curl_easy *data,
dec->head_len, dec->head_total);
}
else {
- infof(data, "WS-DEC: %s [%s%s payload=%zd/%zd]", msg,
- ws_frame_name_of_op(dec->head[0]),
+ infof(data, "WS-DEC: %s [%s%s payload=%" CURL_FORMAT_CURL_OFF_T
+ "/%" CURL_FORMAT_CURL_OFF_T "]",
+ msg, ws_frame_name_of_op(dec->head[0]),
(dec->head[0] & WSBIT_FIN)? "" : " NON-FINAL",
dec->payload_offset, dec->payload_len);
}
@@ -272,7 +273,8 @@ static CURLcode ws_dec_pass_payload(struct ws_decoder *dec,
Curl_bufq_skip(inraw, (size_t)nwritten);
dec->payload_offset += (curl_off_t)nwritten;
remain = dec->payload_len - dec->payload_offset;
- /* infof(data, "WS-DEC: passed %zd bytes payload, %zd remain",
+ /* infof(data, "WS-DEC: passed %zd bytes payload, %"
+ CURL_FORMAT_CURL_OFF_T " remain",
nwritten, remain); */
}
@@ -351,8 +353,9 @@ static void update_meta(struct websocket *ws,
static void ws_enc_info(struct ws_encoder *enc, struct Curl_easy *data,
const char *msg)
{
- infof(data, "WS-ENC: %s [%s%s%s payload=%zd/%zd]", msg,
- ws_frame_name_of_op(enc->firstbyte),
+ infof(data, "WS-ENC: %s [%s%s%s payload=%" CURL_FORMAT_CURL_OFF_T
+ "/%" CURL_FORMAT_CURL_OFF_T "]",
+ msg, ws_frame_name_of_op(enc->firstbyte),
(enc->firstbyte & WSBIT_OPCODE_MASK) == WSBIT_OPCODE_CONT ?
" CONT" : "",
(enc->firstbyte & WSBIT_FIN)? "" : " NON-FIN",
@@ -839,7 +842,7 @@ static ssize_t nw_in_recv(void *reader_ctx,
CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer,
size_t buflen, size_t *nread,
- struct curl_ws_frame **metap)
+ const struct curl_ws_frame **metap)
{
struct connectdata *conn = data->conn;
struct websocket *ws;
@@ -921,7 +924,8 @@ CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer,
ctx.payload_len, ctx.bufidx);
*metap = &ws->frame;
*nread = ws->frame.len;
- /* infof(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %zd, %zd left)",
+ /* infof(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %"
+ CURL_FORMAT_CURL_OFF_T ", %" CURL_FORMAT_CURL_OFF_T " left)",
buflen, *nread, ws->frame.offset, ws->frame.bytesleft); */
return CURLE_OK;
}
@@ -987,8 +991,7 @@ CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer,
return CURLE_SEND_ERROR;
}
if(!data->conn->proto.ws) {
- failf(data, "Not a websocket transfer on connection #%ld",
- data->conn->connection_id);
+ failf(data, "Not a websocket transfer");
return CURLE_SEND_ERROR;
}
ws = data->conn->proto.ws;
@@ -1037,7 +1040,8 @@ CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer,
}
else {
if((curl_off_t)buflen > ws->enc.payload_remain) {
- infof(data, "WS: unaligned frame size (sending %zu instead of %zd)",
+ infof(data, "WS: unaligned frame size (sending %zu instead of %"
+ CURL_FORMAT_CURL_OFF_T ")",
buflen, ws->enc.payload_remain);
}
}
@@ -1082,7 +1086,7 @@ CURLcode Curl_ws_disconnect(struct Curl_easy *data,
return CURLE_OK;
}
-CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
{
/* we only return something for websocket, called from within the callback
when not using raw mode */
@@ -1096,7 +1100,7 @@ CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
size_t *nread,
- struct curl_ws_frame **metap)
+ const struct curl_ws_frame **metap)
{
(void)curl;
(void)buffer;
@@ -1120,7 +1124,7 @@ CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
return CURLE_NOT_BUILT_IN;
}
-CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
+CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
{
(void)data;
return NULL;