summaryrefslogtreecommitdiff
path: root/libs/libcurl
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2020-06-25 10:07:52 +0300
committerdartraiden <wowemuh@gmail.com>2020-06-25 10:07:52 +0300
commit133594758488f47f6d1d6d01fcb95483526df40b (patch)
tree401bd12c0209f680812d233a87561dd65e107288 /libs/libcurl
parent5104e6639791e5bdc688eb325550d82f05e1e8db (diff)
libcurl: update to 7.71.0
Diffstat (limited to 'libs/libcurl')
-rw-r--r--libs/libcurl/docs/CHANGES3540
-rw-r--r--libs/libcurl/docs/THANKS33
-rw-r--r--libs/libcurl/include/curl/curl.h30
-rw-r--r--libs/libcurl/include/curl/curlver.h10
-rw-r--r--libs/libcurl/include/curl/easy.h13
-rw-r--r--libs/libcurl/include/curl/multi.h6
-rw-r--r--libs/libcurl/include/curl/typecheck-gcc.h9
-rw-r--r--libs/libcurl/src/Makefile.in113
-rw-r--r--libs/libcurl/src/Makefile.inc22
-rw-r--r--libs/libcurl/src/altsvc.c19
-rw-r--r--libs/libcurl/src/altsvc.h1
-rw-r--r--libs/libcurl/src/asyn-ares.c57
-rw-r--r--libs/libcurl/src/asyn-thread.c43
-rw-r--r--libs/libcurl/src/asyn.h10
-rw-r--r--libs/libcurl/src/checksrc.pl41
-rw-r--r--libs/libcurl/src/config-win32.h8
-rw-r--r--libs/libcurl/src/conncache.c100
-rw-r--r--libs/libcurl/src/conncache.h9
-rw-r--r--libs/libcurl/src/connect.c124
-rw-r--r--libs/libcurl/src/connect.h4
-rw-r--r--libs/libcurl/src/content_encoding.c130
-rw-r--r--libs/libcurl/src/content_encoding.h26
-rw-r--r--libs/libcurl/src/curl_addrinfo.c97
-rw-r--r--libs/libcurl/src/curl_addrinfo.h19
-rw-r--r--libs/libcurl/src/curl_config.h.cmake21
-rw-r--r--libs/libcurl/src/curl_config.h.in9
-rw-r--r--libs/libcurl/src/curl_hmac.h28
-rw-r--r--libs/libcurl/src/curl_md5.h20
-rw-r--r--libs/libcurl/src/curl_multibyte.c99
-rw-r--r--libs/libcurl/src/curl_multibyte.h49
-rw-r--r--libs/libcurl/src/curl_ntlm_core.c17
-rw-r--r--libs/libcurl/src/curl_ntlm_core.h6
-rw-r--r--libs/libcurl/src/curl_ntlm_wb.c67
-rw-r--r--libs/libcurl/src/curl_sasl.c18
-rw-r--r--libs/libcurl/src/curl_setup.h23
-rw-r--r--libs/libcurl/src/curl_setup_once.h4
-rw-r--r--libs/libcurl/src/curl_sspi.c16
-rw-r--r--libs/libcurl/src/curl_threads.c4
-rw-r--r--libs/libcurl/src/curlx.h12
-rw-r--r--libs/libcurl/src/doh.c128
-rw-r--r--libs/libcurl/src/doh.h21
-rw-r--r--libs/libcurl/src/dynbuf.c227
-rw-r--r--libs/libcurl/src/dynbuf.h63
-rw-r--r--libs/libcurl/src/easy.c50
-rw-r--r--libs/libcurl/src/easyif.h2
-rw-r--r--libs/libcurl/src/escape.c56
-rw-r--r--libs/libcurl/src/formdata.c16
-rw-r--r--libs/libcurl/src/formdata.h6
-rw-r--r--libs/libcurl/src/ftp.c64
-rw-r--r--libs/libcurl/src/getinfo.c8
-rw-r--r--libs/libcurl/src/hmac.c17
-rw-r--r--libs/libcurl/src/hostasyn.c10
-rw-r--r--libs/libcurl/src/hostip.c100
-rw-r--r--libs/libcurl/src/hostip.h22
-rw-r--r--libs/libcurl/src/hostip4.c16
-rw-r--r--libs/libcurl/src/hostip6.c22
-rw-r--r--libs/libcurl/src/http.c801
-rw-r--r--libs/libcurl/src/http.h48
-rw-r--r--libs/libcurl/src/http2.c179
-rw-r--r--libs/libcurl/src/http2.h2
-rw-r--r--libs/libcurl/src/http_chunks.c49
-rw-r--r--libs/libcurl/src/http_digest.c10
-rw-r--r--libs/libcurl/src/http_digest.h2
-rw-r--r--libs/libcurl/src/http_negotiate.c19
-rw-r--r--libs/libcurl/src/http_negotiate.h6
-rw-r--r--libs/libcurl/src/http_ntlm.c14
-rw-r--r--libs/libcurl/src/http_ntlm.h6
-rw-r--r--libs/libcurl/src/http_proxy.c173
-rw-r--r--libs/libcurl/src/http_proxy.h3
-rw-r--r--libs/libcurl/src/idn_win32.c10
-rw-r--r--libs/libcurl/src/imap.c6
-rw-r--r--libs/libcurl/src/ldap.c60
-rw-r--r--libs/libcurl/src/libcurl.plist6
-rw-r--r--libs/libcurl/src/md4.c15
-rw-r--r--libs/libcurl/src/md5.c22
-rw-r--r--libs/libcurl/src/mime.c28
-rw-r--r--libs/libcurl/src/mime.h44
-rw-r--r--libs/libcurl/src/mprintf.c85
-rw-r--r--libs/libcurl/src/mqtt.c2
-rw-r--r--libs/libcurl/src/multi.c273
-rw-r--r--libs/libcurl/src/multihandle.h4
-rw-r--r--libs/libcurl/src/multiif.h2
-rw-r--r--libs/libcurl/src/nwlib.c39
-rw-r--r--libs/libcurl/src/openldap.c14
-rw-r--r--libs/libcurl/src/pingpong.c18
-rw-r--r--libs/libcurl/src/pingpong.h9
-rw-r--r--libs/libcurl/src/pop3.c8
-rw-r--r--libs/libcurl/src/progress.c6
-rw-r--r--libs/libcurl/src/quic.h4
-rw-r--r--libs/libcurl/src/rtsp.c135
-rw-r--r--libs/libcurl/src/select.c136
-rw-r--r--libs/libcurl/src/select.h8
-rw-r--r--libs/libcurl/src/sendf.c36
-rw-r--r--libs/libcurl/src/setopt.c128
-rw-r--r--libs/libcurl/src/setopt.h4
-rw-r--r--libs/libcurl/src/setup-os400.h8
-rw-r--r--libs/libcurl/src/setup-vms.h8
-rw-r--r--libs/libcurl/src/sha256.c12
-rw-r--r--libs/libcurl/src/share.c8
-rw-r--r--libs/libcurl/src/smtp.c4
-rw-r--r--libs/libcurl/src/socks.c63
-rw-r--r--libs/libcurl/src/socks_gssapi.c4
-rw-r--r--libs/libcurl/src/socks_sspi.c6
-rw-r--r--libs/libcurl/src/telnet.c4
-rw-r--r--libs/libcurl/src/tftp.c72
-rw-r--r--libs/libcurl/src/transfer.c98
-rw-r--r--libs/libcurl/src/url.c436
-rw-r--r--libs/libcurl/src/url.h7
-rw-r--r--libs/libcurl/src/urlapi.c2
-rw-r--r--libs/libcurl/src/urldata.h188
-rw-r--r--libs/libcurl/src/vauth/cleartext.c5
-rw-r--r--libs/libcurl/src/vauth/cram.c4
-rw-r--r--libs/libcurl/src/vauth/digest.c2
-rw-r--r--libs/libcurl/src/vauth/digest_sspi.c21
-rw-r--r--libs/libcurl/src/vauth/krb5_sspi.c11
-rw-r--r--libs/libcurl/src/vauth/ntlm.c5
-rw-r--r--libs/libcurl/src/vauth/ntlm_sspi.c8
-rw-r--r--libs/libcurl/src/vauth/spnego_sspi.c8
-rw-r--r--libs/libcurl/src/vauth/vauth.c6
-rw-r--r--libs/libcurl/src/vquic/ngtcp2.c370
-rw-r--r--libs/libcurl/src/vquic/ngtcp2.h1
-rw-r--r--libs/libcurl/src/vquic/quiche.c70
-rw-r--r--libs/libcurl/src/vquic/vquic.c85
-rw-r--r--libs/libcurl/src/vquic/vquic.h34
-rw-r--r--libs/libcurl/src/vssh/libssh2.c299
-rw-r--r--libs/libcurl/src/vssh/ssh.h6
-rw-r--r--libs/libcurl/src/vssh/wolfssh.c8
-rw-r--r--libs/libcurl/src/vtls/bearssl.c2
-rw-r--r--libs/libcurl/src/vtls/gskit.c12
-rw-r--r--libs/libcurl/src/vtls/gtls.c25
-rw-r--r--libs/libcurl/src/vtls/keylog.c156
-rw-r--r--libs/libcurl/src/vtls/keylog.h56
-rw-r--r--libs/libcurl/src/vtls/mbedtls.c6
-rw-r--r--libs/libcurl/src/vtls/mesalink.c7
-rw-r--r--libs/libcurl/src/vtls/nss.c6
-rw-r--r--libs/libcurl/src/vtls/openssl.c697
-rw-r--r--libs/libcurl/src/vtls/schannel.c465
-rw-r--r--libs/libcurl/src/vtls/schannel_verify.c22
-rw-r--r--libs/libcurl/src/vtls/sectransp.c70
-rw-r--r--libs/libcurl/src/vtls/vtls.c40
-rw-r--r--libs/libcurl/src/vtls/vtls.h35
-rw-r--r--libs/libcurl/src/vtls/wolfssl.c174
-rw-r--r--libs/libcurl/src/x509asn1.c75
-rw-r--r--libs/libcurl/src/x509asn1.h71
144 files changed, 6813 insertions, 5068 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES
index de44c16641..5061b40139 100644
--- a/libs/libcurl/docs/CHANGES
+++ b/libs/libcurl/docs/CHANGES
@@ -6,6 +6,1916 @@
Changelog
+Version 7.71.0 (23 Jun 2020)
+
+Daniel Stenberg (23 Jun 2020)
+- RELEASE-NOTES: curl 7.71.0 release
+
+- THANKS: curl 7.71.0 additions
+
+- url: make sure pushed streams get an allocated download buffer
+
+ Follow-up to c4e6968127e876b0
+
+ When a new transfer is created, as a resuly of an acknowledged push,
+ that transfer needs a download buffer allocated.
+
+ Closes #5590
+
+Jay Satiro (22 Jun 2020)
+- openssl: Don't ignore CA paths when using Windows CA store
+
+ This commit changes the behavior of CURLSSLOPT_NATIVE_CA so that it does
+ not override CURLOPT_CAINFO / CURLOPT_CAPATH, or the hardcoded default
+ locations. Instead the CA store can now be used at the same time.
+
+ The change is due to the impending release. The issue is still being
+ discussed. The behavior of CURLSSLOPT_NATIVE_CA is subject to change and
+ is now documented as experimental.
+
+ Ref: bc052cc (parent commit)
+ Ref: https://github.com/curl/curl/issues/5585
+
+- tool_operate: Don't use Windows CA store as a fallback
+
+ Background:
+
+ 148534d added CURLSSLOPT_NATIVE_CA to use the Windows OS certificate
+ store in libcurl w/ OpenSSL on Windows. CURLSSLOPT_NATIVE_CA overrides
+ CURLOPT_CAINFO if both are set. The curl tool will fall back to
+ CURLSSLOPT_NATIVE_CA if it could not find a certificate bundle to set
+ via CURLOPT_CAINFO.
+
+ Problem:
+
+ libcurl may be built with hardcoded paths to a certificate bundle or
+ directory, and if CURLSSLOPT_NATIVE_CA is used then those paths are
+ ignored.
+
+ Solution:
+
+ A solution is still being discussed but since there's an impending
+ release this commit removes using CURLSSLOPT_NATIVE_CA in the curl tool.
+
+ Ref: https://github.com/curl/curl/issues/5585
+
+- openssl: Fix CA fallback logic for OpenSSL 3.0 build
+
+ Prior to this change I assume a build error would occur when
+ CURL_CA_FALLBACK was used.
+
+ Closes https://github.com/curl/curl/pull/5587
+
+Daniel Stenberg (22 Jun 2020)
+- copyright: update mismatched copyright years
+
+- test1460: verify that -Ji is not ok
+
+- tool_getparam: -i is not OK if -J is used
+
+ Reported-by: sn on hackerone
+ Bug: https://curl.haxx.se/docs/CVE-2020-8177.html
+
+- [Peter Wu brought this change]
+
+ CMake: ignore INTERFACE_LIBRARY targets for pkg-config file
+
+ Reviewed-by: Marcel Raad
+ Fixes #5512
+ Closes #5517
+
+- [Valentyn Korniienko brought this change]
+
+ multibyte: Fixed access-> waccess to file for Windows Plarform
+
+ Reviewed-by: Marcel Raad
+ Closes #5580
+
+- altsvc: bump to h3-29
+
+ Closes #5584
+
+- urlglob: treat literal IPv6 addresses with zone IDs as a host name
+
+ ... and not as a "glob". Now done by passing the supposed host to the
+ URL parser which supposedly will do a better job at identifying "real"
+ numerical IPv6 addresses.
+
+ Reported-by: puckipedia on github
+ Fixes #5576
+ Closes #5579
+
+- test1179: verify error message for non-existing cmdline option
+
+- tool_getparam: repair the error message for unknown flag
+
+ Follow-up to 9e5669f3880674
+ Detected by Coverity CID 1464582 ("Logically dead code")
+
+ Closes #5577
+
+- FILEFORMAT: describe verify/stderr
+
+- connect: improve happy eyeballs handling
+
+ For QUIC but also for regular TCP when the second family runs out of IPs
+ with a failure while the first family is still trying to connect.
+
+ Separated the timeout handling for IPv4 and IPv6 connections when they
+ both have a number of addresses to iterate over.
+
+- ngtcp2: never call fprintf() in lib code in release version
+
+- ngtcp2: fix happy eyeballs quic connect crash
+
+ Reported-by: Peter Wu
+ Fixes #5565
+ Closes #5568
+
+- select: remove the unused ELAPSED_MS() macro
+
+ Closes #5573
+
+Marc Hoersken (17 Jun 2020)
+- [rcombs brought this change]
+
+ multi: implement wait using winsock events
+
+ This avoids using a pair of TCP ports to provide wakeup functionality
+ for every multi instance on Windows, where socketpair() is emulated
+ using a TCP socket on loopback which could in turn lead to socket
+ resource exhaustion.
+
+ Reviewed-by: Gergely Nagy
+ Reviewed-by: Marc Hörsken
+
+ Closes #5397
+
+Daniel Stenberg (17 Jun 2020)
+- manpage: add three missing environment variables
+
+ CURL_SSL_BACKEND, QLOGDIR and SSLKEYLOGFILE
+
+ Closes #5571
+
+- RELEASE-NOTES: synced
+
+- configure: for wolfSSL, check for the DES func needed for NTLM
+
+ Also adds pkg-config support for the wolfSSL detection.
+
+- [Ruurd Beerstra brought this change]
+
+ ntlm: enable NTLM support with wolfSSL
+
+ When wolfSSL is built with its OpenSSL API layer, it fetures the same DES*
+ functions that OpenSSL has. This change take advantage of that.
+
+ Co-authored-by: Daniel Stenberg
+ Closes #5556
+ Fixes #5548
+
+- http: move header storage to Curl_easy from connectdata
+
+ Since the connection can be used by many independent requests (using
+ HTTP/2 or HTTP/3), things like user-agent and other transfer-specific
+ data MUST NOT be kept connection oriented as it could lead to requests
+ getting the wrong string for their requests. This struct data was
+ lingering like this due to old HTTP1 legacy thinking where it didn't
+ mattered..
+
+ Fixes #5566
+ Closes #5567
+
+- CODE_REVIEW.md: how to do code reviews in curl
+
+ Assisted-by: Daniel Gustafsson
+ Assisted-by: Rich Salz
+ Assisted-by: Hugo van Kemenade
+ Assisted-by: James Fuller
+ Assisted-by: Marc Hörsken
+ Assisted-by: Jay Satiro
+
+ Closes #5555
+
+- altsvc: remove the num field from the altsvc struct
+
+ It was superfluous since we have the list.size alredy
+
+ Reported-by: Jay Satiro
+ Fixes #5553
+ Closes #5563
+
+- version.d: expanded and alpha-sorted
+
+ Added a few missing features not previously mentioned. Ordered them
+ alphabetically.
+
+ Closes #5558
+
+- ABI.md: rename to .md and polish the markdown
+
+ Closes #5562
+
+- HELP-US: add a section for "smaller tasks"
+
+ The point of this section is to meet the CII Best Practices gold level
+ critera:
+
+ "The project MUST clearly identify small tasks that can be performed by
+ new or casual contributors"
+
+ Closes #5560
+
+- TODO: retry on the redirected-to URL
+
+ Closes #5462
+
+- mailmap: Nicolas Sterchele
+
+- [Nicolas Sterchele brought this change]
+
+ TODO: remove 19.3 section title
+
+ Follow-up to ad6416986755e417c66e2c6, which caused wrong formatting on
+ curl documentation website
+
+ Closes #5561
+
+- [Martin V brought this change]
+
+ test1560: avoid possibly negative association in wording
+
+ Closes #5549
+
+- share: don't set the share flag it something fails
+
+ When asking for a specific feature to be shared in the share object,
+ that bit was previously set unconditionally even if the shared feature
+ failed or otherwise wouldn't work.
+
+ Closes #5554
+
+- buildconf: remove -print from the find command that removes files
+
+ It's just too annoying and unnecessary to get a long list of files shown
+
+- RELEASE-NOTES: synced
+
+- wording: avoid blacklist/whitelist stereotypes
+
+ Instead of discussing if there's value or meaning (implied or not) in
+ the colors, let's use words without the same possibly negative
+ associations.
+
+ Closes #5546
+
+Jay Satiro (9 Jun 2020)
+- tool_getparam: fix memory leak in parse_args
+
+ Prior to this change in Windows Unicode builds most parsed options would
+ not be freed.
+
+ Found using _CrtDumpMemoryLeaks().
+
+ Ref: https://github.com/curl/curl/issues/5545
+
+Daniel Stenberg (8 Jun 2020)
+- socks: detect connection close during handshake
+
+ The SOCKS4/5 state machines weren't properly terminated when the proxy
+ connection got closed, leading to a busy-loop.
+
+ Reported-By: zloi-user on github
+ Fixes #5532
+ Closes #5542
+
+- [James Fuller brought this change]
+
+ multi: add defensive check on data->multi->num_alive
+
+ Closes #5540
+
+- Curl_addrinfo: use one malloc instead of three
+
+ To reduce the amount of allocations needed for creating a Curl_addrinfo
+ struct, make a single larger malloc instead of three separate smaller
+ ones.
+
+ Closes #5533
+
+- [Alessandro Ghedini brought this change]
+
+ quiche: update SSLKEYLOGFILE support
+
+ quiche now requires the application to explicitly set the keylog path
+ for each connection, rather than reading the environment variable
+ itself.
+
+ Closes #5541
+
+- tests: add two simple tests for --login-options
+
+ Test 895 and 896 - as a follow-up to a3e972313b
+
+ Closes #5539
+
+- ngtcp2: update with recent API changes
+
+ Syncs with ngtcp2 commit 7e9a917d386d98 merged June 7 2020.
+
+ Assisted-by: Tatsuhiro Tsujikawa
+ Closes #5538
+
+- [James Fuller brought this change]
+
+ socks: remove unreachable breaks in socks.c and mime.c
+
+ Closes #5537
+
+- tool_cfgable: free login_options at exit
+
+ Memory leak
+ Reported-by: Geeknik Labs
+ Fixes #5535
+ Closes #5536
+
+- libssh2: keep sftp errors as 'unsigned long'
+
+ Remove weird work-around for storing the SFTP errors as int instead of
+ the "unsigned long" that libssh2 actually returns for SFTP errors.
+
+ Closes #5534
+
+Marc Hoersken (6 Jun 2020)
+- timeouts: move ms timeouts to timediff_t from int and long
+
+ Now that all functions in select.[ch] take timediff_t instead
+ of the limited int or long, we can remove type conversions
+ and related preprocessor checks to silence compiler warnings.
+
+ Avoiding conversions from time_t was already done in 842f73de.
+
+ Based upon #5262
+ Supersedes #5214, #5220 and #5221
+ Follow up to #5343 and #5479
+ Closes #5490
+
+Daniel Stenberg (6 Jun 2020)
+- [François Rigault brought this change]
+
+ openssl: set FLAG_TRUSTED_FIRST unconditionally
+
+ On some systems, openssl 1.0.x is still the default, but it has been
+ patched to contain all the recent security fixes. As a result of this
+ patching, it is possible for macro X509_V_FLAG_NO_ALT_CHAINS to be
+ defined, while the previous behavior of openssl to not look at trusted
+ chains first, remains.
+
+ Fix it: ensure X509_V_FLAG_TRUSTED_FIRST is always set, do not try to
+ probe for the behavior of openssl based on the existence ofmacros.
+
+ Closes #5530
+
+- server/util: fix logmsg format using curl_off_t argument
+
+ ... this caused segfaults on armv7.
+
+ Regression added in dd0365d560aea5a (7.70.0)
+
+ Reviewed-by: Jay Satiro
+ Closes #5529
+
+- RELEASE-NOTES: synced
+
+- [Cherish98 brought this change]
+
+ socks: fix expected length of SOCKS5 reply
+
+ Commit 4a4b63d forgot to set the expected SOCKS5 reply length when the
+ reply ATYP is X'01'. This resulted in erroneously expecting more bytes
+ when the request length is greater than the reply length (e.g., when
+ remotely resolving the hostname).
+
+ Closes #5527
+
+Marc Hoersken (5 Jun 2020)
+- .gitignore: add directory containing the stats repo
+
+ Since the new curl/stats repository is designed to be
+ checked out into the curl repository working tree as stats/
+ it should be on the ignore list to aid in commit staging.
+
+Daniel Stenberg (5 Jun 2020)
+- [Adnan Khan brought this change]
+
+ HTTP3.md: clarify cargo build directory
+
+ Cargo needs to be called from within the 'quiche' directory.
+
+ Closes #5522
+
+- user-agent.d: spell out what happens given a blank argument
+
+ Closes #5525
+
+- trailers: switch h1-trailer logic to use dynbuf
+
+ In the continued effort to remove "manual" realloc schemes.
+
+ Closes #5524
+
+- CURLINFO_ACTIVESOCKET.3: clarify the description
+
+ Reported-by: Jay Satiro
+ Fixes #5299
+ Closes #5520
+
+- mailmap: Don J Olmstead
+
+- configure: only strip first -L from LDFLAGS
+
+ In the logic that works out if a given OpenSSL path works, it stripped
+ off a possibly leading -L flag using an incorrect sed pattern which
+ would remove all instances of -L in the string, including if the path
+ itself contained that two-letter sequence!
+
+ The same pattern was used and is now updated in multiple places. Now it
+ only removes -L if it starts the strings.
+
+ Reported-by: Mohamed Osama
+ Fixes #5519
+ Closes #5521
+
+Peter Wu (4 Jun 2020)
+- quiche: advertise draft 28 support
+
+ Fix the verbose message while at it, quiche currently supports draft
+ 27 and draft 28 simultaneously.
+
+ Closes #5518
+
+Daniel Stenberg (4 Jun 2020)
+- KNOWN_BUGS: RTSP authentication breaks without redirect support
+
+ Closes #4750
+
+Jay Satiro (4 Jun 2020)
+- projects: Add crypt32.lib to dependencies for all OpenSSL configs
+
+ Windows project configurations that use OpenSSL with USE_WIN32_CRYPTO
+ need crypt32.
+
+ Follow-up to 148534d which added CURLSSLOPT_NATIVE_CA for 7.71.0.
+
+ The changes that are in this commit were made by script.
+
+ Ref: https://gist.github.com/jay/a1861b50ecce2b32931237180f856e28
+
+ Closes https://github.com/curl/curl/pull/5516
+
+Marc Hoersken (3 Jun 2020)
+- CI/macos: fix 'is already installed' errors by using bundle
+
+ Avoid failing CI builds due to nghttp2 being already installed.
+
+ Closes #5513
+
+Daniel Stenberg (3 Jun 2020)
+- altsvc: fix 'dsthost' may be used uninitialized in this function
+
+- RELEASE-NOTES: synced
+
+- urldata: let the HTTP method be in the set.* struct
+
+ When the method is updated inside libcurl we must still not change the
+ method as set by the user as then repeated transfers with that same
+ handle might not execute the same operation anymore!
+
+ This fixes the libcurl part of #5462
+
+ Test 1633 added to verify.
+
+ Closes #5499
+
+- hostip: fix the memory-leak introduced in 67d2802
+
+ Fixes #5503
+ Closes #5504
+
+- test970: make it require proxy support
+
+ This test verifies the -w %json output and the test case includes a full
+ generated "blob". If there's no proxy support built into libcurl, it
+ will return an error for proxy related info variables and they will not
+ be included in the json, thus causing a mismatch and this test fails.
+
+ Reported-by: Marc Hörsken
+ Fixes #5501
+ Closes #5502
+
+- [Radoslav Georgiev brought this change]
+
+ examples/http2-down/upload: add error checks
+
+ If `index.html` does not exist in the directory from which the example
+ is invoked, the fopen(upload, "rb") invocation in `setup` would fail,
+ returning NULL. This value is subsequently passed as the FILE* argument
+ of the `fread` invocation in the `read_callback` function, which is the
+ actual cause of the crash (apparently `fread` assumes that argument to
+ be non-null).
+
+ In addition, mitigate some possible crashes of similar origin.
+
+ Closes #5463
+
+- [kotoriのねこ brought this change]
+
+ examples/ephiperfifo: turn off interval when setting timerfd
+
+ Reported-by: therealhirudo on github
+ Fixes #5485
+ Closes #5497
+
+- [Saleem Abdulrasool brought this change]
+
+ vtls: repair the build with `CURL_DISABLE_PROXY`
+
+ `http_proxy` will not be available in `conndata` if `CURL_DISABLE_PROXY`
+ is enabled. Repair the build with that configuration.
+
+ Follow-up to f3d501dc67
+
+ Closes #5498
+
+- transfer: remove k->str NULL check
+
+ "Null-checking k->str suggests that it may be null, but it has already
+ been dereferenced on all paths leading to the check" - and it can't
+ legally be NULL at this point. Remove check.
+
+ Detected by Coverity CID 1463884
+
+ Closes #5495
+
+Marc Hoersken (1 Jun 2020)
+- select: always use Sleep in Curl_wait_ms on Win32
+
+ Since Win32 almost always will also have USE_WINSOCK,
+ we can reduce complexity and always use Sleep there.
+
+ Assisted-by: Jay Satiro
+ Reviewed-by: Daniel Stenberg
+
+ Follow up to #5343
+ Closes #5489
+
+Daniel Stenberg (31 May 2020)
+- conncache: download buffer needs +1 size for trailing zero
+
+ Follow-up to c4e6968127e
+ Detected by OSS-Fuzz: https://oss-fuzz.com/testcase-detail/5727799779524608
+
+Marc Hoersken (31 May 2020)
+- azure: use matrix strategy to avoid configuration redundancy
+
+ This also includes the following changes:
+
+ - Use the same timeout for all jobs on Linux (60 minutes)
+ and Windows (90 minutes)
+ - Use CLI stable apt-get install -y instead of apt install
+ which warns about that and run apt-get update first
+ - Enable MQTT for Windows msys2 builds instead of
+ legacy msys1 builds
+ - Add ./configure --prefix parameter to the msys2 builds
+ - The MSYSTEM environment variable is now preset inside
+ the container images for the msys2 builds
+
+ Note: on Azure Pipelines the matrix strategy is basically
+ just a simple list of job copies and not really a matrix.
+
+ Closes #5468
+
+Daniel Stenberg (30 May 2020)
+- build: disable more code/data when built without proxy support
+
+ Added build to travis to verify
+
+ Closes #5466
+
+- url: alloc the download buffer at transfer start
+
+ ... and free it as soon as the transfer is done. It removes the extra
+ alloc when a new size is set with setopt() and reduces memory for unused
+ easy handles.
+
+ In addition: the closure_handle now doesn't use an allocated buffer at
+ all but the smallest supported size as a stack based one.
+
+ Closes #5472
+
+- timeouts: change millisecond timeouts to timediff_t from time_t
+
+ For millisecond timers we like timediff_t better. Also, time_t can be
+ unsigned so returning a negative value doesn't work then.
+
+ Closes #5479
+
+Marc Hoersken (30 May 2020)
+- select: add overflow checks for timeval conversions
+
+ Using time_t and suseconds_t if suseconds_t is available,
+ long on Windows (maybe others in the future) and int elsewhere.
+
+ Also handle case of ULONG_MAX being greater or equal to INFINITE.
+
+ Assisted-by: Jay Satiro
+ Reviewed-by: Daniel Stenberg
+
+ Part of #5343
+
+- select: use timediff_t instead of time_t and int for timeout_ms
+
+ Make all functions in select.[ch] take timeout_ms as timediff_t
+ which should always be large enough and signed on all platforms
+ to take all possible timeout values and avoid type conversions.
+
+ Reviewed-by: Jay Satiro
+ Reviewed-by: Daniel Stenberg
+
+ Replaces #5107 and partially #5262
+ Related to #5240 and #5286
+ Closes #5343
+
+- unit1604.c: fix implicit conv from 'SANITIZEcode' to 'CURLcode'
+
+ GCC 10 warns about this with warning: implicit conversion
+ from 'SANITIZEcode' to 'CURLcode' [-Wenum-conversion]
+
+ Since 'expected_result' is not really of type 'CURLcode' and
+ it is not exposed in any way, we can just use 'SANITIZEcode'.
+
+ Reviewed-by: Daniel Stenberg
+ Reviewed-by: Marcel Raad
+
+ Closes #5476
+
+- tests/libtest: fix undefined reference to 'curlx_win32_fopen'
+
+ Since curl_setup.h now makes use of curlx_win32_fopen for Win32
+ builds with USE_WIN32_LARGE_FILES or USE_WIN32_SMALL_FILES defined,
+ we need to include the relevant files for tests using fopen,
+ because the libtest sources are also including curl_setup.h
+
+ Reviewed-by: Marcel Raad
+ Reviewed-by: Daniel Stenberg
+
+ Follow up to #3784 (ffdddb45d9)
+ Closes #5475
+
+- appveyor: add non-debug plain autotools-based build
+
+ This should enable us to catch linking issues with the
+ testsuite early, like the one described/fixed in #5475.
+
+ Reviewed-by: Daniel Stenberg
+ Reviewed-by: Marcel Raad
+
+ Closes #5477
+
+Daniel Stenberg (29 May 2020)
+- RELEASE-NOTES: synced
+
+- Revert "buildconf: use find -execdir"
+
+ This partially reverts commit c712009838f44211958854de431315586995bc61.
+
+ Keep the ares_ files removed but bring back the older way to run find,
+ to make it work with busybox's find, as apparently that's being used.
+
+ Reported-by: Max Peal
+ Fixes #5483
+ Closes #5484
+
+- server/sws: fix asan warning on use of uninitialized variable
+
+- libssh2: improved error output for wrong quote syntax
+
+ Reported-by: Werner Stolz
+
+ Closes #5474
+
+- mk-lib1521: generate code for testing BLOB options as well
+
+ Follow-up to cac5374298b3
+
+ Closes #5478
+
+- configure: repair the check if argv can be written to
+
+ Due to bad escaping of the test code, the test wouldn't build and thus
+ result in a negative test result, which would lead to the unconditional
+ assumption that overwriting the arguments doesn't work and thus curl
+ would never hide credentials given in the command line, even when it
+ would otherwise be possible.
+
+ Regression from commit 2d4c2152c (7.60.0)
+
+ Reported-by: huzunhao on github
+ Fixes #5470
+ Closes #5471
+
+Peter Wu (28 May 2020)
+- CMake: rebuild Makefile.inc.cmake when Makefile.inc changes
+
+ Otherwise the build might fail due to missing source files, as
+ demonstrated by the recent keylog.c addition on an existing build dir.
+
+ Closes #5469
+
+Daniel Stenberg (28 May 2020)
+- urldata: fix comments: Curl_done() is called multi_done() now
+
+ ... since 575e885db
+
+Peter Wu (27 May 2020)
+- ngtcp2: use common key log routine for better thread-safety
+
+ Tested with ngtcp2 built against the OpenSSL library. Additionally
+ tested with MultiSSL (NSS for TLS and ngtcp2+OpenSSL for QUIC).
+
+ The TLS backend (independent of QUIC) may or may not already have opened
+ the keylog file before. Therefore Curl_tls_keylog_open is always called
+ to ensure the file is open.
+
+- wolfssl: add SSLKEYLOGFILE support
+
+ Tested following the same curl and tshark commands as in commit
+ "vtls: Extract and simplify key log file handling from OpenSSL" using
+ WolfSSL v4.4.0-stable-128-g5179503e8 from git master built with
+ `./configure --enable-all --enable-debug CFLAGS=-DHAVE_SECRET_CALLBACK`.
+
+ Full support for this feature requires certain wolfSSL build options,
+ see "Availability note" in lib/vtls/wolfssl.c for details.
+
+ Closes #5327
+
+- vtls: Extract and simplify key log file handling from OpenSSL
+
+ Create a set of routines for TLS key log file handling to enable reuse
+ with other TLS backends. Simplify the OpenSSL backend as follows:
+
+ - Drop the ENABLE_SSLKEYLOGFILE macro as it is unconditionally enabled.
+ - Do not perform dynamic memory allocation when preparing a log entry.
+ Unless the TLS specifications change we can suffice with a reasonable
+ fixed-size buffer.
+ - Simplify state tracking when SSL_CTX_set_keylog_callback is
+ unavailable. My original sslkeylog.c code included this tracking in
+ order to handle multiple calls to SSL_connect and detect new keys
+ after renegotiation (via SSL_read/SSL_write). For curl however we can
+ be sure that a single master secret eventually becomes available
+ after SSL_connect, so a simple flag is sufficient. An alternative to
+ the flag is examining SSL_state(), but this seems more complex and is
+ not pursued. Capturing keys after server renegotiation was already
+ unsupported in curl and remains unsupported.
+
+ Tested with curl built against OpenSSL 0.9.8zh, 1.0.2u, and 1.1.1f
+ (`SSLKEYLOGFILE=keys.txt curl -vkso /dev/null https://localhost:4433`)
+ against an OpenSSL 1.1.1f server configured with:
+
+ # Force non-TLSv1.3, use TLSv1.0 since 0.9.8 fails with 1.1 or 1.2
+ openssl s_server -www -tls1
+ # Likewise, but fail the server handshake.
+ openssl s_server -www -tls1 -Verify 2
+ # TLS 1.3 test. No need to test the failing server handshake.
+ openssl s_server -www -tls1_3
+
+ Verify that all secrets (1 for TLS 1.0, 4 for TLS 1.3) are correctly
+ written using Wireshark. For the first and third case, expect four
+ matches per connection (decrypted Server Finished, Client Finished, HTTP
+ Request, HTTP Response). For the second case where the handshake fails,
+ expect a decrypted Server Finished only.
+
+ tshark -i lo -pf tcp -otls.keylog_file:keys.txt -Tfields \
+ -eframe.number -eframe.time -etcp.stream -e_ws.col.Info \
+ -dtls.port==4433,http -ohttp.desegment_body:FALSE \
+ -Y 'tls.handshake.verify_data or http'
+
+ A single connection can easily be identified via the `tcp.stream` field.
+
+Daniel Stenberg (27 May 2020)
+- FILEFORMAT: add more features that tests can depend on
+
+- [Michael Kaufmann brought this change]
+
+ transfer: close connection after excess data has been read
+
+ For HTTP 1.x, it's a protocol error when the server sends more bytes
+ than announced. If this happens, don't reuse the connection, because the
+ start position of the next response is undefined.
+
+ Closes #5440
+
+- [Estanislau Augé-Pujadas brought this change]
+
+ Revert "ssh: ignore timeouts during disconnect"
+
+ This reverts commit f31760e63b4e9ef1eb25f8f211390f8239388515. Shipped in
+ curl 7.54.1.
+
+ Bug: https://curl.haxx.se/mail/lib-2020-05/0068.html
+ Closes #5465
+
+- urldata: connect related booleans live in struct ConnectBits
+
+ And remove a few unused booleans!
+
+ Closes #5461
+
+- hostip: on macOS avoid DoH when given a numerical IP address
+
+ When USE_RESOLVE_ON_IPS is set (defined on macOS), it means that
+ numerical IP addresses still need to get "resolved" - but not with DoH.
+
+ Reported-by: Viktor Szakats
+ Fixes #5454
+ Closes #5459
+
+- ngtcp2: cleanup memory when failing to connect
+
+ Reported-by: Peter Wu
+ Fixes #5447 (the ngtcp2 side of it)
+ Closes #5451
+
+- quiche: clean up memory properly when failing to connect
+
+ Addresses the quiche side of #5447
+ Reported-by: Peter Wu
+ Closes #5450
+
+- cleanup: use a single space after equals sign in assignments
+
+- url: accept "any length" credentials for proxy auth
+
+ They're only limited to the maximum string input restrictions, not to
+ 256 bytes.
+
+ Added test 1178 to verify
+
+ Reported-by: Will Roberts
+ Fixes #5448
+ Closes #5449
+
+- [Maksim Stsepanenka brought this change]
+
+ test1167: fixes in badsymbols.pl
+
+ Closes #5442
+
+- altsvc: fix parser for lines ending with CRLF
+
+ Fixed the alt-svc parser to treat a newline as end of line.
+
+ The unit tests in test 1654 were done without CRLF and thus didn't quite
+ match the real world. Now they use CRLF as well.
+
+ Reported-by: Peter Wu
+ Assisted-by: Peter Wu
+ Assisted-by: Jay Satiro
+ Fixes #5445
+ Closes #5446
+
+Viktor Szakats (25 May 2020)
+- all: fix codespell errors
+
+ Reviewed-by: Jay Satiro
+ Reviewed-by: Daniel Stenberg
+ Closes https://github.com/curl/curl/pull/5452
+
+Peter Wu (25 May 2020)
+- ngtcp2: fix build with current ngtcp2 master implementing draft 28
+
+ Based on client.cc changes from ngtcp2. Tested with current git master,
+ ngtcp2 commit c77d5731ce92, nghttp3 commit 65ff479d4380.
+
+ Fixes #5444
+ Closes #5443
+
+Daniel Stenberg (25 May 2020)
+- RELEASE-NOTES: synced
+
+ moved the new setopts up to a "change"
+
+- RELEASE-NOTES: synced
+
+- copyright: updated year ranges out of sync
+
+ ... and whitelisted a few more files in the the copyright.pl script.
+
+- [Gilles Vollant brought this change]
+
+ setopt: add CURLOPT_PROXY_ISSUERCERT(_BLOB) for coherency
+
+ Closes #5431
+
+- curl: remove -J "informational" written on stdout
+
+ curl would previously show "curl: Saved to filename 'name from header'"
+ if -J was used and a name was picked from the Content-Disposition
+ header. That output could interfer with other stdout output, such as -w.
+
+ This commit removes that output line.
+ Bug: https://curl.haxx.se/mail/archive-2020-05/0044.html
+ Reported-by: Коваленко Анатолий Викторович
+ Closes #5435
+
+Peter Wu (22 May 2020)
+- travis: simplify quiche build instructions wrt boringssl
+
+ quiche builds boringssl as static library, reuse that instead of
+ building another shared library.
+
+ Closes #5438
+
+- configure: fix pthread check with static boringssl
+
+ A shared boringssl/OpenSSL library requires -lcrypto only for linking.
+ A static build additionally requires `-ldl -lpthread`. In the latter
+ case `-lpthread` is added to LIBS which prevented `-pthread` from being
+ added to CFLAGS. Clear LIBS to fix linking failures for libtest tests.
+
+Daniel Stenberg (22 May 2020)
+- Revert "sendf: make failf() use the mvsnprintf() return code"
+
+ This reverts commit 74623551f306990e70c7c5515b88972005604a74.
+
+ Instead mark the function call with (void). Getting the return code and
+ using it instead triggered Coverity warning CID 1463596 because
+ snprintf() can return a negative value...
+
+ Closes #5441
+
+- typecheck-gcc.h: CURLINFO_PRIVATE does not need a 'char *'
+
+ Reported-by: Billyzou0741326 on github
+ Fixes #5432
+ Closes #5436
+
+- tests/server/util.h: add extern to silence compiler warning
+
+ Follow-up from a3b0699d5c1
+
+- typecheck-gcc.h: fix the OFF_T check
+
+ The option number also needs to be less than CURLOPTTYPE_BLOB.
+
+ Follow-up to cac5374298
+ Reported-by: Jeroen Ooms
+ Bug: https://github.com/curl/curl/pull/5365#issuecomment-631084114
+
+- TODO: --dry-run
+
+ Closes #5426
+
+- TODO: Ratelimit or wait between serial requests
+
+ Closes #5406
+
+- tool_paramhlp: fixup C89 mistake
+
+ Follow-up to c5f0a9db22.
+
+- [Siva Sivaraman brought this change]
+
+ tool_paramhlp: fixed potentially uninitialized strtol() variable
+
+ Seems highly unlikely to actually be possible, but better safe than
+ sorry.
+
+ Closes #5417
+
+- [Siva Sivaraman brought this change]
+
+ tool_operate: fixed potentially uninitialized variables
+
+ ... in curl_easy_getinfo() calls. They're harmless but clearing the
+ variables makes the code safer and comforts the reader.
+
+ Closes #5416
+
+- sha256: move assign to the declaration line
+
+ Follow-up to fae30656. Should've been squashed with that commit...
+
+- [Siva Sivaraman brought this change]
+
+ sha256: fixed potentially uninitialized variable
+
+ Closes #5414
+
+- sendf: make failf() use the mvsnprintf() return code
+
+ ... and avoid a strlen() call. Fixes a MonocleAI warning.
+
+ Reported-by: MonocleAI
+ Fixes #5413
+ Closes #5420
+
+- hostip: make Curl_printable_address not return anything
+
+ It was not used much anyway and instead we let it store a blank buffer
+ in case of failure.
+
+ Reported-by: MonocleAI
+ Fixes #5411
+ Closes #5418
+
+- ftp: mark return-ignoring calls to Curl_GetFTPResponse with (void)
+
+ They're done on purpose, make that visible in the code.
+ Reported-by: MonocleAI
+ Fixes #5412
+ Closes #549
+
+- TODO: forbid TLS post-handshake auth and do TLS record padding
+
+ Closes #5396
+ Closes #5398
+
+- RELEASE-NOTES: synced
+
+- dynbuf: return NULL when there's no buffer length
+
+ ... as returning a "" is not a good idea as the string is supposed to be
+ allocated and returning a const string will cause issues.
+
+ Reported-by: Brian Carpenter
+ Follow-up to ed35d6590e72c
+ Closes #5405
+
+Peter Wu (16 May 2020)
+- travis: upgrade to bionic, clang-9, improve readability
+
+ Changes, partially to reduce build failures from external dependencies:
+ - Upgrade Ubuntu and drop unnecessary third-party repos.
+ - Properly clone apt config to ensure retries.
+ - Upgrade to clang-9 from the standard repos.
+ - Use Ubuntu 20.04 focal for the libssh build, use of ssh_get_publickey
+ fails on -Werror=deprecated-declarations in Ubuntu 18.04. Do not use
+ focal everywhere yet since Travis CI has not documented this option.
+ In focal, python-impacket (Py2.7) has been removed, leaving only
+ python3-impacket. Since it is only needed for SMB tests and not SSH,
+ skip it for the libssh job since it might need more work.
+ - apt: Remove gcc-8 and libstdc++-8-dev, already installed via g++-8.
+
+ Non-functional cleanups:
+ - Simplify test matrix, drop redundant os and compiler keys.
+ - Deprecation fixes: remove sudo, rename matrix -> jobs.
+ - Every job has an 'env' key, put this key first in a list item.
+
+ Closes #5370
+
+- travis: whitespace-only changes for consistency
+
+ Automatically apply a consistent indentation with:
+
+ python3 -c 'from ruamel.yaml import YAML;y=YAML();d=y.load(open(".travis.yml"));y.width=500;y.dump(d,open(".travis.yml.new","w"))'
+
+ followed by manually re-indenting three comments.
+
+ Closes #5370
+
+- CMake: add libssh build support
+
+ Closes #5372
+
+Daniel Stenberg (15 May 2020)
+- KNOWN_BUGS: wolfssh: publickey auth doesn't work
+
+ Closes #4820
+
+- KNOWN_BUGS: OS400 port requires deprecated IBM library
+
+ Closes #5176
+
+- [Vyron Tsingaras brought this change]
+
+ http2: keep trying to send pending frames after req.upload_done
+
+ Fixes #1410
+ Closes #5401
+
+- [Gilles Vollant brought this change]
+
+ setopt: support certificate options in memory with struct curl_blob
+
+ This change introduces a generic way to provide binary data in setopt
+ options, called BLOBs.
+
+ This change introduces these new setopts:
+
+ CURLOPT_ISSUERCERT_BLOB, CURLOPT_PROXY_SSLCERT_BLOB,
+ CURLOPT_PROXY_SSLKEY_BLOB, CURLOPT_SSLCERT_BLOB and CURLOPT_SSLKEY_BLOB.
+
+ Reviewed-by: Daniel Stenberg
+ Closes #5357
+
+- source cleanup: remove all custom typedef structs
+
+ - Stick to a single unified way to use structs
+ - Make checksrc complain on 'typedef struct {'
+ - Allow them in tests, public headers and examples
+
+ - Let MD4_CTX, MD5_CTX, and SHA256_CTX typedefs remain as they actually
+ typedef different types/structs depending on build conditions.
+
+ Closes #5338
+
+- travis: remove the .checksrc fiddling
+
+- ftp: make domore_getsock() return the secondary socket properly
+
+ Previously, after PASV and immediately after the data connection has
+ connected, the function would only return the control socket to wait for
+ which then made the data connection simply timeout and not get polled
+ correctly. This become obvious when running test 1631 and 1632 event-
+ based.
+
+- test1632: verify FTP through HTTPS-proxy with connection re-use
+
+- test1631: verify FTP download through HTTPS-proxy
+
+- sws: as last resort, get test number from server cmd file
+
+ If it can't be found in the request. Also support --cmdfile to set it to
+ a custom file name.
+
+ runtests.pl always writes this file with the test number in it since a
+ while back.
+
+- ftp: shut down the secondary connection properly when SSL is used
+
+ Reported-by: Neal Poole
+ Fixes #5340
+ Closes #5385
+
+Marcel Raad (14 May 2020)
+- KNOWN_BUGS: adapt 5.5 to recent changes
+
+ It only applies to non-Unicode builds now.
+ Also merge 5.10 into it as it's effectively a duplicate.
+
+ Closes https://github.com/curl/curl/pull/3784
+
+- curl_setup: support Unicode functions to open files on Windows
+
+ Use them only if `_UNICODE` is defined, in which case command-line
+ arguments have been converted to UTF-8.
+
+ Closes https://github.com/curl/curl/pull/3784
+
+- tool: support UTF-16 command line on Windows
+
+ - use `wmain` instead of `main` when `_UNICODE` is defined [0]
+ - define `argv_item_t` as `wchar_t *` in this case
+ - use the curl_multibyte gear to convert the command-line arguments to
+ UTF-8
+
+ This makes it possible to pass parameters with characters outside of
+ the current locale on Windows, which is required for some tests, e.g.
+ the IDN tests. Out of the box, this currently only works with the
+ Visual Studio project files, which default to Unicode, and winbuild
+ with the `ENABLE_UNICODE` option.
+
+ [0] https://devblogs.microsoft.com/oldnewthing/?p=40643
+
+ Ref: https://github.com/curl/curl/issues/3747
+ Closes https://github.com/curl/curl/pull/3784
+
+- curl_multibyte: add to curlx
+
+ This will also be needed in the tool and tests.
+
+ Ref: https://github.com/curl/curl/pull/3758#issuecomment-482197512
+ Closes https://github.com/curl/curl/pull/3784
+
+Daniel Stenberg (14 May 2020)
+- url: make the updated credentials URL-encoded in the URL
+
+ Found-by: Gregory Jefferis
+ Reported-by: Jeroen Ooms
+ Added test 1168 to verify. Bug spotted when doing a redirect.
+ Bug: https://github.com/jeroen/curl/issues/224
+ Closes #5400
+
+- tests: add https-proxy support to the test suite
+
+ Initial test 1630 added with basic HTTPS-proxy use. HTTPS-proxy is like
+ HTTP proxy but with a full TLS connection to the proxy.
+
+ Closes #5399
+
+- mailmap: James Fuller
+
+- [Major_Tom brought this change]
+
+ vauth/cleartext: fix theoretical integer overflow
+
+ Fix theoretical integer overflow in Curl_auth_create_plain_message.
+
+ The security impact of the overflow was discussed on hackerone. We
+ agreed this is more of a theoretical vulnerability, as the integer
+ overflow would only be triggerable on systems using 32-bits size_t with
+ over 4GB of available memory space for the process.
+
+ Closes #5391
+
+Jay Satiro (13 May 2020)
+- curl.1: Quote globbed URLs
+
+ - Quote the globbing example URLs that contain characters [] {} since
+ otherwise they may be interpreted as shell metacharacters.
+
+ Bug: https://github.com/curl/curl/issues/5388
+ Reported-by: John Simpson
+
+ Closes https://github.com/curl/curl/pull/5394
+
+Daniel Stenberg (14 May 2020)
+- checksrc: enhance the ASTERISKSPACE and update code accordingly
+
+ Fine: "struct hello *world"
+
+ Not fine: "struct hello* world" (and variations)
+
+ Closes #5386
+
+- docs/options-in-versions: which version added each cmdline option
+
+ Added test 971 to verify that the list is in sync with the files in
+ cmdline-opts. The check also verifies that .d-files that uses Added:
+ specify the same version number as the options-in-versions file does.
+
+ Closes #5381
+
+- docs: unify protocol lists
+
+ We boast support for 25 transfer protocols. Make sure the lists are
+ consistent
+
+ Closes #5384
+
+- OpenSSL: have CURLOPT_CRLFILE imply CURLSSLOPT_NO_PARTIALCHAIN
+
+ ... to avoid an OpenSSL bug that otherwise makes the CRL check to fail.
+
+ Reported-by: Michael Kaufmann
+ Fixes #5374
+ Closes #5376
+
+- tls13-ciphers.d: shorten the Arg
+
+- sasl-authzid.d: add Arg: and shorten the desc
+
+- cert-type.d: mention the available types in the desc
+
+- tool: shorten 3 --help descriptions
+
+ --happy-eyeballs-timeout-ms, --resolve and --ssl-revoke-best-effort
+
+ gen.pl already warned about these lines but we didn't listen
+
+ Closes #5379
+
+- configure: the wolfssh backend does not provide SCP
+
+ Closes #5387
+
+- RELEASE-NOTES: synced
+
+- url: reject too long input when parsing credentials
+
+ Since input passed to libcurl with CURLOPT_USERPWD and
+ CURLOPT_PROXYUSERPWD circumvents the regular string length check we have
+ in Curl_setstropt(), the input length limit is enforced in
+ Curl_parse_login_details too, separately.
+
+ Reported-by: Thomas Bouzerar
+ Closes #5383
+
+- list-only.d: this option existed already in 4.0
+
+Jay Satiro (12 May 2020)
+- retry-all-errors.d: Shorten the summary line
+
+ Follow-up to b995bb5 from a few moments ago.
+
+ Reported-by: Daniel Stenberg
+
+ Ref: https://github.com/curl/curl/commit/b995bb5#r39108929
+
+- [denzor brought this change]
+
+ easy: fix dangling pointer on easy_perform fail
+
+ Closes https://github.com/curl/curl/pull/5363
+
+- tool: Add option --retry-all-errors to retry on any error
+
+ The "sledgehammer" of retrying.
+
+ Closes https://github.com/curl/curl/pull/5185
+
+Daniel Stenberg (12 May 2020)
+- [James Le Cuirot brought this change]
+
+ libcurl.pc: Merge Libs.private into Libs for static-only builds
+
+ A project being built entirely statically will call pkg-config with
+ --static, which utilises the Libs.private field. Conversely it will
+ not use --static when not being built entirely statically, even if
+ there is only a static build of libcurl available. This will most
+ likely cause the build to fail due to underlinking unless we merge the
+ Libs fields.
+
+ Consider that this is what the Meson build system does when it
+ generates pkg-config files.
+
+ I have also reflected this in the --libs argument of curl-config even
+ though REQUIRE_LIB_DEPS always seems to be "yes" anyway.
+
+ Closes #5373
+
+- [Peter Wu brought this change]
+
+ CMake: fix runtests.pl with CMake, add new test targets
+
+ * runtests.pl:
+ - Fix out-of-tree build under CMake when srcdir is not set. Default
+ srcdir to the location of runtests.pl.
+ - Add a hack to allow CMake to use the TFLAGS option as documented
+ in tests/README and used in scripts/travis/script.sh.
+ * Bump CMake version to 3.2 for USES_TERMINAL, dropping Debian Jessie
+ support (no one should care, it is already EOL.).
+ * Remove CTest since it defines its own 'test' target with no tests
+ since all unittests are already broken and not built by default.
+ * Add new test targets based on the options from Makefile.am. Since
+ new test targets are rarely added, I opted for duplicating the
+ runtests.pl options as opposed to creating a new Makefile.inc file.
+ Use top-level target names (test-x) instead of x-test since that is
+ used by CI and others.
+
+ Closes #5358
+
+- [Peter Wu brought this change]
+
+ CMake: do not build test programs by default
+
+ The default target should only build libcurl and curl. Add a dedicated
+ 'testdeps' target which will be used later when running tests. Note that
+ unittests are currently broken in CMake and already excluded.
+
+ Closes #5368
+
+- FILEFORMAT: moved up the variables section and further polished
+
+- runtests: remove ftp2 support, not used
+
+ We once supported two separate ftp instances in the test suite. Has not
+ been used the last decade.
+
+ Closes #5375
+
+- url: sort the protocol schemes in rough popularity order
+
+ When looking for a protocol match among supported schemes, check the
+ most "popular" schemes first. It has zero functionality difference and
+ for all practical purposes a speed difference will not be measureable
+ but it still think it makes sense to put the least likely matches last.
+
+ "Popularity" based on the 2019 user survey.
+
+ Closes #5377
+
+Marc Hoersken (11 May 2020)
+- test1238: avoid tftpd being busy for tests shortly following
+
+ The tftpd server may still be busy if the total timeout of
+ 25 seconds has not been reached or no sread error was received
+ during or after the execution of the timeout test 1238.
+
+ Once the next TFTP test comes around (eg. 1242 or 1243),
+ those will fail because the tftpd server is still waiting
+ on data from curl due to the UDP protocol being stateless
+ and having no connection close. On Linux this error may not
+ happen, because ICMP errors generated due to a swrite error
+ can also be returned async on the next sread call instead.
+
+ Therefore we will now just kill the tftpd server after test
+ 1238 to make sure that the following tests are not affected.
+
+ This enables us to no longer ignore tests 1242, 1243, 2002
+ and 2003 on the CI platforms CirrusCI and AppVeyor.
+
+ Assisted-by: Peter Wu
+ Closes #5364
+
+Daniel Stenberg (11 May 2020)
+- write-out.d: added "response_code"
+
+- KNOWN_BUGS: Build with staticly built dependency
+
+ I rewrote the item 5.4 to be more generic about static dependencies.
+
+- ROADMAP: remove old entries
+
+ MQTT - the start has already landed
+
+ tiny-curl - also mostly landed and is a continuous work
+
+ make menuconfig - basically no interest from users, not pushing there
+
+- [Peter Wu brought this change]
+
+ travis: Add ngtcp2 and quiche tests for CMake
+
+ To avoid an explosion of jobs, extend the existing CMake tests with
+ ngtcp2 and quiche support. macOS was previously moved to GitHub actions,
+ so the non-Linux case can be dropped.
+
+- [Peter Wu brought this change]
+
+ CMake: add ENABLE_ALT_SVC option
+
+ Tested alt-svc with quiche. While at it, add missing MultiSSL reporting
+ (not tested).
+
+- [Peter Wu brought this change]
+
+ CMake: add HTTP/3 support (ngtcp2+nghttp3, quiche)
+
+ Add three new CMake Find modules (using the curl license, but I grant
+ others the right to apply the CMake BSD license instead).
+
+ This CMake config is simpler than the autotools one because it assumes
+ ngtcp2 and nghttp3 to be used together. Another difference is that this
+ CMake config checks whether QUIC is actually supported by the TLS
+ library (patched OpenSSL or boringssl) since this can be a common
+ configuration mistake that could result in build errors later.
+
+ Unlike autotools, CMake does not warn you that the features are
+ experimental. The user is supposed to already know that and read the
+ documentation. It requires a very special build environment anyway.
+
+ Tested with ngtcp2+OpenSSL+nghttp3 and quiche+boringssl, both built from
+ current git master. Use `LD_DEBUG=files src/curl |& grep need` to figure
+ out which features (libldap-2.4, libssh2) to disable due to conflicts
+ with boringssl.
+
+ Closes #5359
+
+Marc Hoersken (10 May 2020)
+- tests/server/tftpd.c: fix include and enhance debug logging
+
+ setjmp.h should only be included if HAVE_SETJMP_H is defined.
+
+ Add additional log statements to see wether reads and writes
+ are blocking or finishing before an alarm signal is received.
+
+ Assisted-by: Peter Wu
+ Part of #5364
+
+Daniel Stenberg (10 May 2020)
+- tool_operate: only set CURLOPT_SSL_OPTIONS if SSL support is present
+
+ Reported-by: Marcel Raad
+ Follow-up to 148534db5
+ Fixes #5367
+ Closes #5369
+
+Marc Hoersken (9 May 2020)
+- appveyor: update comments to be clear about toolchain
+
+ - CMake-based MSYS builds use mingw-w64 to cross-compile.
+ - autotools-based builds are compiled using msys2-devel.
+
+ The difference is that the later ones are not cross-compiled
+ to Windows and instead require the msys2 runtime to be present.
+
+ At the moment only the Azure Pipelines CI builds actually
+ run autotools-based cross-compilation builds for Windows.
+
+- TODO: update regarding missing Schannel features
+
+ Some aspects have already been implemented over the years.
+
+ 15.1 Client certificates are now supported:
+
+ - System stores via e35b0256eb34f1fe562e3e2a2615beb50a391c52
+ - PKCS#12 files via 0fdf96512613574591f501d63fe49495ba40e1d5
+
+ 15.2 Ciphers can now be specified through:
+
+ - Algorithms via 9aefbff30d280c60fc9d8cc3e0b2f19fc70a2f28
+
+ Reviewed-by: Daniel Stenberg and Marcel Raad
+ Closes #5358
+
+Daniel Stenberg (8 May 2020)
+- checksrc: close the .checksrc file handle when done reading
+
+- RELEASE-NOTES: synced
+
+ And bumped next version to 7.71.0
+
+- [Gilles Vollant brought this change]
+
+ CURLOPT_SSL_OPTIONS: add *_NATIVE_CA to use Windows CA store (with openssl)
+
+ Closes #4346
+
+- TODO: native IDN support on macOS
+
+- urlapi: accept :: as a valid IPv6 address
+
+ Text 1560 is extended to verify.
+
+ Reported-by: Pavel Volgarev
+ Fixes #5344
+ Closes #5351
+
+- THANKS-filter: Peter Wang
+
+- [Peter Wang brought this change]
+
+ *_sspi: fix bad uses of CURLE_NOT_BUILT_IN
+
+ Return CURLE_AUTH_ERROR instead of CURLE_NOT_BUILT_IN for other
+ instances of QuerySecurityPackageInfo failing, as in
+ commit 2a81439553286f12cd04a4bdcdf66d8e026d8201.
+
+ Closes #5355
+
+- docs/HTTP3: add qlog to the quiche build instruction
+
+- ngtcp2: introduce qlog support
+
+ If the QLOGDIR environment variable is set, enable qlogging.
+
+ ... and create Curl_qlogdir() in the new generic vquic/vquic.c file for
+ QUIC functions that are backend independent.
+
+ Closes #5353
+
+- ntlm_sspi: fix bad use of CURLE_NOT_BUILT_IN
+
+ That return code is reserved for build-time conditional code not being
+ present while this was a regular run-time error from a Windows API.
+
+ Reported-by: wangp on github
+ Fixes #5349
+ Closes #5350
+
+- runtests: show elapsed test time with higher precision (ms)
+
+- RELEASE-NOTES: synced
+
+- http2: simplify and clean up trailer handling
+
+ Triggered by a crash detected by OSS-Fuzz after the dynbuf introduction in
+ ed35d6590e72. This should make the trailer handling more straight forward and
+ hopefully less error-prone.
+
+ Deliver the trailer header to the callback already at receive-time. No
+ longer caches the trailers to get delivered at end of stream.
+
+ Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22030
+ Closes #5348
+
+Marc Hoersken (7 May 2020)
+- appveyor: disable test 1139 instead of ignoring it
+
+ Spending time on manpage checking makes no sense
+ for these builds due to lacking manpage support.
+
+- appveyor: disable flaky test 1501 and ignore broken 1056
+
+ Test 1501 is flaky on Windows CI due to being time sensitive
+ and the testsuite relying on taskkill.exe to check for the
+ existance of processes which can take to much time itself.
+
+ Test 1056 is broken in autotools-based Windows builds due
+ to scope ID support missing in these builds at the moment.
+
+- test613.pl: make tests 613 and 614 work with OpenSSH for Windows
+
+ OpenSSH for Windows shows group and other/world permissions as *,
+ because those concepts do not exist on Windows. It also does not
+ show the current or parent directory, so we just ignore those.
+
+ Reviewed-by: Daniel Stenberg
+ Closes #5328
+
+Daniel Stenberg (6 May 2020)
+- runtests: set +x mode again
+
+- libssh2: convert over to use dynbuf
+
+ In my very basic test that lists sftp://127.0.0.1/tmp/, this patched
+ code makes 161 allocations compared to 194 in git master. A 17%
+ reduction.
+
+ Closes #5336
+
+- travis: add "qlog" as feature in the quiche build
+
+- quiche: enable qlog output
+
+ quiche has the potential to log qlog files. To enable this, you must
+ build quiche with the qlog feature enabled `cargo build --features
+ qlog`. curl then passes a file descriptor to quiche, which takes
+ ownership of the file. The FD transfer only works on UNIX.
+
+ The convention is to enable logging when the QLOGDIR environment is
+ set. This should be a path to a folder where files are written with the
+ naming template <SCID>.qlog.
+
+ Co-authored-by: Lucas Pardue
+ Replaces #5337
+ Closes #5341
+
+- urldata.h: remove #define HEADERSIZE, not used anymore
+
+ Follow-up to ed35d6590e72c
+
+- ngtcp2: convert to dynbuf
+
+ Closes #5335
+
+- connect: make happy eyeballs work for QUIC (again)
+
+ Follow-up from dbd16c3e256c6c (regression in 7.70.0)
+
+ Closes #5334
+
+- connect: add two asserts to clue code analyzers in a little
+
+- http_proxy: ported to use dynbuf instead of a static size buffer
+
+ Removes a 16K static buffer from the easy handle. Simplifies the code.
+
+- dynbuf: introduce internal generic dynamic buffer functions
+
+ A common set of functions instead of many separate implementations for
+ creating buffers that can grow when appending data to them. Existing
+ functionality has been ported over.
+
+ In my early basic testing, the total number of allocations seem at
+ roughly the same amount as before, possibly a few less.
+
+ See docs/DYNBUF.md for a description of the API.
+
+ Closes #5300
+
+- runtests: remove sleep calls
+
+ Remove many one second sleeps that were done *after* each newly started
+ test server already has been verified. They should not have any purpose
+ there.
+
+ Closes #5323
+
+- asyn-*: remove support for never-used NULL entry pointers
+
+ ... and instead convert those to asserts to make sure they are truly
+ never NULL.
+
+ Closes #5324
+
+- [Emil Engler brought this change]
+
+ doc: Rename VERSIONS to VERSIONS.md as it already has Markdown syntax
+
+ Closes #5325
+
+Jay Satiro (2 May 2020)
+- asyn-thread: fix cppcheck warning
+
+ - Check for NULL entry parameter before attempting to deref entry in
+ Curl_resolver_is_resolved, like is already done in asyn-ares.
+
+ This is to silence cppcheck which does not seem to understand that
+ asyn-ares and asyn-thread have separate Curl_resolver_is_resolved
+ and those units are mutually exclusive. Prior to this change it warned
+ of a scenario where asyn-thread's Curl_resolver_is_resolved is called
+ with a NULL entry from asyn-ares, but that couldn't happen.
+
+ Reported-by: rl1987@users.noreply.github.com
+
+ Fixes https://github.com/curl/curl/issues/5326
+
+- select: fix overflow protection in Curl_socket_check
+
+ Follow-up to a96c752 which changed the timeout_ms type from time_t to
+ timediff_t.
+
+ Ref: https://github.com/curl/curl/pull/5240
+
+ Closes https://github.com/curl/curl/pull/5286
+
+Marc Hoersken (2 May 2020)
+- sockfilt: make select_ws stop waiting on exit signal event
+
+ This makes sure that select_ws behaves similar to real select
+ which stops waiting on a signal handler being triggered.
+
+ This makes it possible to gracefully stop sockfilt.exe on
+ Windows with taskkill /IM sockfilt.exe (without /F force flag).
+
+ Reviewed-by: Jay Satiro
+ Part of #5260
+
+- tests/server/util.[ch]: add exit event to stop waiting on Windows
+
+ This commit adds a global exit event to the test servers that
+ Windows-specific wait routines can use to get triggered if the
+ program was signaled to be terminated, eg. select_ws in sockfilt.c
+
+ The exit event will be managed by the signal handling code and is
+ set to not reset automatically to support multiple wait routines.
+
+ Reviewed-by: Jay Satiro
+ Closes #5260
+
+- tests/server/util.c: fix thread handle not being closed
+
+ Reviewed-by: Jay Satiro
+ Part of #5260
+
+- tests/server/util.c: use raise instead of calling signal handler
+
+ Use raise to trigger signal handler instead of calling it
+ directly and causing potential unexpected control flow.
+
+ Reviewed-by: Jay Satiro
+ Part of #5260
+
+- tests: add support for SSH server variant specific transfer paths
+
+ OpenSSH for Windows requires paths in the format of /C:/
+ instead of the pseudo-POSIX paths /cygdrive/c/ or just /c/
+
+ Reviewed-by: Daniel Stenberg
+ Closes #5298
+
+Daniel Stenberg (2 May 2020)
+- RELEASE-NOTES: synced
+
+- libssh2: set the expected total size in SCP upload init
+
+ ... as otherwise the progress callback gets called without that
+ information, making the progress meter have less info.
+
+ Reported-by: Murugan Balraj
+ Bug: https://curl.haxx.se/mail/archive-2020-05/0000.html
+ Closes #5317
+
+- runtests: make the logmsg from the ssh server only show in verbose
+
+- tests: make test 1248 + 1249 use %NOLISTENPORT
+
+ ... instead of a port of a non-running server so that it works
+ stand-alone.
+
+ Closes #5318
+
+- examples: remove asiohiper.cpp
+
+ This example has repeatedly been reported to contain bugs, and as users
+ copy and paste code from this into production, I now deem it better to
+ not provide the example at all.
+
+ Closes #5090
+ Closes #5322
+
+- [Emil Engler brought this change]
+
+ doc: add missing closing parenthesis in CURLINFO_SSL_VERIFYRESULT.3
+
+ Closes #5320
+
+- [Emil Engler brought this change]
+
+ KNOWN_BUGS: Remove "curl --upload-file . hang if delay in STDIN"
+
+ It was fixed in 9a2cbf3
+
+ Closes #5319
+
+- cirrus: disable SFTP and SCP tests
+
+ ... as we can't seem to start the sshd server on it. Those problems
+ existed before d1239b50bececd (running the SSH server on a random port),
+ but they're more noticable now since there are more failed attempts in
+ the logs.
+
+ Closes #5315
+
+- [Emil Engler brought this change]
+
+ runtests: fix typo in the existence of disabled tests checker
+
+ Closes #5316
+
+Dan Fandrich (30 Apr 2020)
+- test75: Remove precheck test
+
+ This has not been needed since commit 9fa42bed and often prevents it
+ from running at all with dynamic test ports.
+
+- tests: Stop referring to server ports when they're not used
+
+ Several tests referred to specific server ports even when the test
+ didn't actually use that server or specify that it's needed. In such
+ cases, the test harness substitutes the text "[not running]" as the port
+ number which causes many such tests to fail due to the inability to
+ parse the URL. These tests are changed to use %NOLISTENPORT which will
+ always be substituted correctly.
+
+Daniel Stenberg (30 Apr 2020)
+- [Emil Engler brought this change]
+
+ GnuTLS: Backend support for CURLINFO_SSL_VERIFYRESULT
+
+ Closes #5287
+
+- conncache: various concept cleanups
+
+ More connection cache accesses are protected by locks.
+
+ CONNCACHE_* is a beter prefix for the connection cache lock macros.
+
+ Curl_attach_connnection: now called as soon as there's a connection
+ struct available and before the connection is added to the connection
+ cache.
+
+ Curl_disconnect: now assumes that the connection is already removed from
+ the connection cache.
+
+ Ref: #4915
+ Closes #5009
+
+- tests: tests: run stunnel for HTTPS and FTPS on dynamic ports
+
+ As stunnel is an external tool and it has no specific option to export
+ the actually used port number when asked to listen to 0, runtests
+ instead iterates over ten randomly picked high number ports and sticks
+ to the first one stunnel can listen to.
+
+ Closes #5267
+
+- tests: pick a random port number for SSH
+
+ Since sshd doesn't have such an option by itself, we iterate over a
+ series of random ports until one works.
+
+ Closes #5273
+
+- [Rikard Falkeborn brought this change]
+
+ libtest/cmake: Remove commented code
+
+ These were commented out in e9dd0998706a when Makefile.inc was included
+ instead. 11 years have passed since then and the commented code is of
+ course very outdated. Remove it to avoid confusion.
+
+ Closes #5311
+
+- schannel: source code reindent
+
+ White space edits only. Conform better to standard curl source code
+ indenting style.
+
+ Closes #5305
+
+Kamil Dudka (29 Apr 2020)
+- test1177: look for curl.h in source directory
+
+ If we use a separate build directory, there is no copy of the header.
+
+ Closes #5310
+
+- tests: look for preprocessed tests in build directory
+
+ ... which is not always the same directory as source directory
+
+ Closes #5310
+
+Daniel Stenberg (29 Apr 2020)
+- RELEASE-NOTES: synced
+
+ ... and bumped curlver.h to 7.70.1
+
Version 7.70.0 (29 Apr 2020)
Daniel Stenberg (29 Apr 2020)
@@ -294,13 +2204,9 @@ Daniel Stenberg (20 Apr 2020)
- release-notes.pl: fix parsing typo
James Fuller (20 Apr 2020)
-- [xquery brought this change]
-
- ensure all references to ports are replaced by vars
+- ensure all references to ports are replaced by vars
-- [xquery brought this change]
-
- add more alt-svc test coverage
+- add more alt-svc test coverage
Daniel Stenberg (20 Apr 2020)
- test1247: use http server to get the port number set
@@ -1851,7 +3757,7 @@ Marc Hoersken (10 Mar 2020)
- runtests: log minimal and maximal used port numbers
Daniel Stenberg (9 Mar 2020)
-- [Jim Fuller brought this change]
+- [James Fuller brought this change]
sftp: fix segfault regression introduced by #4747
@@ -5597,1623 +7503,3 @@ Daniel Stenberg (25 Oct 2019)
Fixes #4518
Closes #4519
-
-Marcel Raad (24 Oct 2019)
-- test1591: fix spelling of http feature
-
- The test never got run because the feature name is `http` in lowercase.
-
- Closes https://github.com/curl/curl/pull/4520
-
-Daniel Stenberg (23 Oct 2019)
-- [Michał Janiszewski brought this change]
-
- appveyor: Use two parallel compilation on appveyor with CMake
-
- Appveyor provides 2 CPUs for each builder[1], make sure to use parallel
- compilation, when running with CMake. CMake learned this new option in
- version 3.12[2] and the version provided by appveyor is fresh enough.
-
- Curl doesn't really take that long to build and it is using the slowest
- builder available, msbuild, so expect only a moderate improvement in
- build times.
-
- [1] https://www.appveyor.com/docs/build-environment/
- [2] https://cmake.org/cmake/help/v3.12/release/3.12.html
-
- Closes #4508
-
-- conn-reuse: requests wanting NTLM can reuse non-NTLM connections
-
- Added test case 338 to verify.
-
- Reported-by: Daniel Silverstone
- Fixes #4499
- Closes #4514
-
-Marcel Raad (23 Oct 2019)
-- tests: add missing proxy features
-
-Daniel Stenberg (22 Oct 2019)
-- RELEASE-NOTES: synced
-
-Marcel Raad (21 Oct 2019)
-- tests: use %FILE_PWD for file:// URLs
-
- This way, we always have exactly one slash after the host name, making
- the tests pass when curl is compiled with the MSYS GCC.
-
- Closes https://github.com/curl/curl/pull/4512
-
-- tests: add `connect to non-listen` keywords
-
- These tests try to connect to ports nothing is listening on.
-
- Closes https://github.com/curl/curl/pull/4511
-
-- runtests: get textaware info from curl instead of perl
-
- The MSYS system on Windows can run the test suite for curl built with
- any toolset. When built with the MSYS GCC, curl uses Unix line endings,
- while it uses Windows line endings when built with the MinGW GCC, and
- `^O` reports 'msys' in both cases. Use the curl executable itself to
- determine the line endings instead, which reports 'x86_64-pc-msys' when
- built with the MSYS GCC.
-
- Closes https://github.com/curl/curl/pull/4506
-
-Daniel Stenberg (20 Oct 2019)
-- [Michał Janiszewski brought this change]
-
- appveyor: Add MSVC ARM64 build
-
- Closes #4507
-
-- http2_recv: a closed stream trumps pause state
-
- ... and thus should return 0, not EAGAIN.
-
- Reported-by: Tom van der Woerdt
- Fixes #4496
- Closes #4505
-
-- http2: expire a timeout at end of stream
-
- To make sure that transfer is being dealt with. Streams without
- Content-Length need a final read to notice the end-of-stream state.
-
- Reported-by: Tom van der Woerdt
- Fixes #4496
-
-Dan Fandrich (18 Oct 2019)
-- travis: Add an ARM64 build
-
- Test 323 is failing for some reason, so disable it there for now.
-
-Marcel Raad (18 Oct 2019)
-- examples/sslbackend: fix -Wchar-subscripts warning
-
- With the `isdigit` implementation that comes with MSYS2, the argument
- is used as an array subscript, resulting in a -Wchar-subscripts
- warning. `isdigit`'s behavior is undefined if the argument is negative
- and not EOF [0]. As done in lib/curl_ctype.h, cast the `char` variable
- to `unsigned char` to avoid that.
-
- [0] https://en.cppreference.com/w/c/string/byte/isdigit
-
- Closes https://github.com/curl/curl/pull/4503
-
-Daniel Stenberg (18 Oct 2019)
-- configure: remove all cyassl references
-
- In particular, this removes the case where configure would find an old
- cyall installation rather than a wolfssl one if present. The library is
- named wolfssl in modern days so there's no real need to keep support for
- the former.
-
- Reported-by: Jacob Barthelmeh
- Closes #4502
-
-Marcel Raad (17 Oct 2019)
-- test1162: disable MSYS2's POSIX path conversion
-
- This avoids MSYS2 converting the backslasb in the URL to a slash,
- causing the test to fail.
-
-Daniel Stenberg (17 Oct 2019)
-- RELEASE-NOTES: synced
-
-Jay Satiro (16 Oct 2019)
-- CURLOPT_TIMEOUT.3: Clarify transfer timeout time includes queue time
-
- Prior to this change some users did not understand that the "request"
- starts when the handle is added to the multi handle, or probably they
- did not understand that some of those transfers may be queued and that
- time is included in timeout.
-
- Reported-by: Jeroen Ooms
-
- Fixes https://github.com/curl/curl/issues/4486
- Closes https://github.com/curl/curl/pull/4489
-
-- [Stian Soiland-Reyes brought this change]
-
- tool_operate: Fix retry sleep time shown to user when Retry-After
-
- - If server header Retry-After is being used for retry sleep time then
- show that value to the user instead of the normal retry sleep time.
-
- This is a follow-up to 640b973 (7.66.0) which changed curl tool so that
- the value from Retry-After header overrides other retry timing options.
-
- Closes https://github.com/curl/curl/pull/4498
-
-Daniel Stenberg (16 Oct 2019)
-- url: normalize CURLINFO_EFFECTIVE_URL
-
- The URL extracted with CURLINFO_EFFECTIVE_URL was returned as given as
- input in most cases, which made it not get a scheme prefixed like before
- if the URL was given without one, and it didn't remove dotdot sequences
- etc.
-
- Added test case 1907 to verify that this now works as intended and as
- before 7.62.0.
-
- Regression introduced in 7.62.0
-
- Reported-by: Christophe Dervieux
- Fixes #4491
- Closes #4493
-
-Marcel Raad (16 Oct 2019)
-- tests: line ending fixes for Windows
-
- Mark some files as text.
-
- Closes https://github.com/curl/curl/pull/4490
-
-- tests: use proxy feature
-
- This makes the tests succeed when using --disable-proxy.
-
- Closes https://github.com/curl/curl/pull/4488
-
-- smbserver: fix Python 3 compatibility
-
- Python 2's `ConfigParser` module is spelled `configparser` in Python 3.
-
- Closes https://github.com/curl/curl/pull/4484
-
-- security: silence conversion warning
-
- With MinGW-w64, `curl_socket_t` is is a 32 or 64 bit unsigned integer,
- while `read` expects a 32 bit signed integer.
- Use `sread` instead of `read` to use the correct parameter type.
-
- Closes https://github.com/curl/curl/pull/4483
-
-- connect: silence sign-compare warning
-
- With MinGW-w64 using WinSock, `curl_socklen_t` is signed, while the
- result of `sizeof` is unsigned.
-
- Closes https://github.com/curl/curl/pull/4483
-
-Daniel Stenberg (13 Oct 2019)
-- TODO: Handle growing SFTP files
-
- Closes #4344
-
-- KNOWN_BUGS: remove "CURLFORM_CONTENTLEN in an array"
-
- The curl_formadd() function is deprecated and shouldn't be used so the
- real fix for applications is to switch to the curl_mime_* API.
-
-- KNOWN_BUGS: "LDAP on Windows does authentication wrong"
-
- Closes #3116
-
-- appveyor: add a winbuild that uses VS2017
-
- Closes #4482
-
-- [Harry Sintonen brought this change]
-
- socketpair: fix include and define for older TCP header systems
-
- fixed build for systems that need netinet/in.h for IPPROTO_TCP and are
- missing INADDR_LOOPBACK
-
- Closes #4480
-
-- socketpair: fix double-close in error case
-
- Follow-up to bc2dbef0afc08
-
-- gskit: use the generic Curl_socketpair
-
-- asyn-thread: make use of Curl_socketpair() where available
-
-- socketpair: an implemention for Windows and more
-
- Curl_socketpair() is designed to be used and work everywhere if there's
- no native version or the native version isn't good enough.
-
- Closes #4466
-
-- RELEASE-NOTES: synced
-
-- connect: return CURLE_OPERATION_TIMEDOUT for errno == ETIMEDOUT
-
- Previosly all connect() failures would return CURLE_COULDNT_CONNECT, no
- matter what errno said.
-
- This makes for example --retry work on these transfer failures.
-
- Reported-by: Nathaniel J. Smith
- Fixes #4461
- Clsoes #4462
-
-- cirrus: switch off blackhole status on the freebsd CI machines
-
-- tests: use port 2 instead of 60000 for a safer non-listening port
-
- ... when the tests want "connection refused".
-
-- KNOWN_BUGS: IDN tests failing on Windows
-
- Closes #3747
-
-Dan Fandrich (9 Oct 2019)
-- cirrus: Increase the git clone depth.
-
- If more commits are submitted to master between the time of triggering
- the first Cirrus build and the time the final build gets started, the
- desired commit is no longer at HEAD and the build will error out.
- [skip ci]
-
-Daniel Stenberg (9 Oct 2019)
-- docs: make sure the --no-progress-meter docs file is in dist too
-
-- docs: document it as --no-progress-meter instead of the reverse
-
- Follow-up to 93373a960c3bb4
-
- Reported-by: infinnovation-dev on github
- Fixes #4474
- Closes #4475
-
-Dan Fandrich (9 Oct 2019)
-- cirrus: Switch the FreeBSD 11.x build to 11.3 and add a 13.0 build.
-
- Also, select the images using image_family to get the latest snapshots
- automatically.
- [skip ci]
-
-Daniel Stenberg (8 Oct 2019)
-- curl: --no-progress-meter
-
- New option that allows a user to ONLY switch off curl's progress meter
- and leave everything else in "talkative" mode.
-
- Reported-by: Piotr Komborski
- Fixes #4422
- Closes #4470
-
-- TODO: Consult %APPDATA% also for .netrc
-
- Closes #4016
-
-- CURLOPT_TIMEOUT.3: remove the mention of "minutes"
-
- ... just say that limiting operations risk aborting otherwise fine
- working transfers. If that means seconds, minutes or hours, we leave to
- the user.
-
- Reported-by: Martin Gartner
- Closes #4469
-
-- [Andrei Valeriu BICA brought this change]
-
- docs: added multi-event.c example
-
- Similar to multi-uv.c but using libevent 2. This is a simpler libevent
- integration example then hiperfifo.c.
-
- Closes #4471
-
-Jay Satiro (5 Oct 2019)
-- [Nicolas brought this change]
-
- ldap: fix OOM error on missing query string
-
- - Allow missing queries, don't return NO_MEMORY error in such a case.
-
- It is acceptable for there to be no specified query string, for example:
-
- curl ldap://ldap.forumsys.com
-
- A regression bug in 1b443a7 caused this issue.
-
- This is a partial fix for #4261.
-
- Bug: https://github.com/curl/curl/issues/4261#issuecomment-525543077
- Reported-by: Jojojov@users.noreply.github.com
- Analyzed-by: Samuel Surtees
-
- Closes https://github.com/curl/curl/pull/4467
-
-- [Paul B. Omta brought this change]
-
- build: Remove unused HAVE_LIBSSL and HAVE_LIBCRYPTO defines
-
- Closes https://github.com/curl/curl/pull/4460
-
-Daniel Stenberg (5 Oct 2019)
-- RELEASE-NOTES: synced
-
-- [Stian Soiland-Reyes brought this change]
-
- curl: ensure HTTP 429 triggers --retry
-
- This completes #3794.
-
- Also make sure the new tests from #4195 are enabled
-
- Closes #4465
-
-Marcel Raad (4 Oct 2019)
-- [apique brought this change]
-
- winbuild: add ENABLE_UNICODE option
-
- Fixes https://github.com/curl/curl/issues/4308
- Closes https://github.com/curl/curl/pull/4309
-
-Daniel Stenberg (4 Oct 2019)
-- ngtcp2: adapt to API change
-
- Closes #4457
-
-- cookies: change argument type for Curl_flush_cookies
-
- The second argument is really a 'bool' so use that and pass in TRUE/FALSE
- to make it clear.
-
- Closes #4455
-
-- http2: move state-init from creation to pre-transfer
-
- To make sure that the HTTP/2 state is initialized correctly for
- duplicated handles. It would otherwise easily generate "spurious"
- PRIORITY frames to get sent over HTTP/2 connections when duplicated easy
- handles were used.
-
- Reported-by: Daniel Silverstone
- Fixes #4303
- Closes #4442
-
-- urlapi: fix use-after-free bug
-
- Follow-up from 2c20109a9b5d04
-
- Added test 663 to verify.
-
- Reported by OSS-Fuzz
- Bug: https://crbug.com/oss-fuzz/17954
-
- Closes #4453
-
-- [Paul Dreik brought this change]
-
- cookie: avoid harmless use after free
-
- This fix removes a use after free which can be triggered by
- the internal cookie fuzzer, but otherwise is probably
- impossible to trigger from an ordinary application.
-
- The following program reproduces it:
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
- CURL* handle=curl_easy_init();
- CookieInfo* info=Curl_cookie_init(handle,NULL,NULL,false);
- curl_easy_setopt(handle, CURLOPT_COOKIEJAR, "/dev/null");
- Curl_flush_cookies(handle, true);
- Curl_cookie_cleanup(info);
- curl_easy_cleanup(handle);
- curl_global_cleanup();
-
- This was found through fuzzing.
-
- Closes #4454
-
-- [Denis Chaplygin brought this change]
-
- docs: add note on failed handles not being counted by curl_multi_perform
-
- Closes #4446
-
-- CURLMOPT_MAX_CONCURRENT_STREAMS.3: fix SEE ALSO typo
-
-- [Niall O'Reilly brought this change]
-
- ESNI: initial build/setup
-
- Closes #4011
-
-- RELEASE-NOTES: synced
-
-- redirect: when following redirects to an absolute URL, URL encode it
-
- ... to make it handle for example (RFC violating) embeded spaces.
-
- Reported-by: momala454 on github
- Fixes #4445
- Closes #4447
-
-- urlapi: fix URL encoding when setting a full URL
-
-- tool_operate: rename functions to make more sense
-
-- curl: create easy handles on-demand and not ahead of time
-
- This should again enable crazy-large download ranges of the style
- [1-10000000] that otherwise easily ran out of memory starting in 7.66.0
- when this new handle allocating scheme was introduced.
-
- Reported-by: Peter Sumatra
- Fixes #4393
- Closes #4438
-
-- [Kunal Ekawde brought this change]
-
- CURLMOPT_MAX_CONCURRENT_STREAMS: new setopt
-
- Closes #4410
-
-- chunked-encoding: stop hiding the CURLE_BAD_CONTENT_ENCODING error
-
- Unknown content-encoding would get returned as CURLE_WRITE_ERROR if the
- response is chunked-encoded.
-
- Reported-by: Ilya Kosarev
- Fixes #4310
- Closes #4449
-
-Marcel Raad (1 Oct 2019)
-- checksrc: fix uninitialized variable warning
-
- The loop doesn't need to be executed without a file argument.
-
- Closes https://github.com/curl/curl/pull/4444
-
-- urlapi: fix unused variable warning
-
- `dest` is only used with `ENABLE_IPV6`.
-
- Closes https://github.com/curl/curl/pull/4444
-
-- lib: silence conversion warnings
-
- Closes https://github.com/curl/curl/pull/4444
-
-- AppVeyor: add 32-bit MinGW-w64 build
-
- With WinSSL and testing enabled so that it would have detected most of
- the warnings fixed in [0] and [1].
-
- [0] https://github.com/curl/curl/pull/4398
- [1] https://github.com/curl/curl/pull/4415
-
- Closes https://github.com/curl/curl/pull/4433
-
-- AppVeyor: remove MSYS2_ARG_CONV_EXCL for winbuild
-
- It's only used for MSYS2 with MinGW.
-
- Closes
-
-Daniel Stenberg (30 Sep 2019)
-- [Emil Engler brought this change]
-
- git: add tests/server/disabled to .gitignore
-
- Closes #4441
-
-- altsvc: accept quoted ma and persist values
-
- As mandated by the spec. Test 1654 is extended to verify.
-
- Closes #4443
-
-- mailmap: a Lucas fix
-
-Alessandro Ghedini (29 Sep 2019)
-- [Lucas Pardue brought this change]
-
- quiche: update HTTP/3 config creation to new API
-
-Daniel Stenberg (29 Sep 2019)
-- BINDINGS: PureBasic, Net::Curl for perl and Nim
-
-- BINDINGS: Kapito is an Erlang library, basically a binding
-
-- BINDINGS: added clj-curl
-
- Reported-by: Lucas Severo
-
-- [Jay Satiro brought this change]
-
- docs: disambiguate CURLUPART_HOST is for host name (ie no port)
-
- Closes #4424
-
-- cookies: using a share with cookies shouldn't enable the cookie engine
-
- The 'share object' only sets the storage area for cookies. The "cookie
- engine" still needs to be enabled or activated using the normal cookie
- options.
-
- This caused the curl command line tool to accidentally use cookies
- without having been told to, since curl switched to using shared cookies
- in 7.66.0.
-
- Test 1166 verifies
-
- Updated test 506
-
- Fixes #4429
- Closes #4434
-
-- setopt: handle ALTSVC set to NULL
-
-- RELEASE-NOTES: synced
-
-- [grdowns brought this change]
-
- INSTALL: add vcpkg installation instructions
-
- Closes #4435
-
-- [Zenju brought this change]
-
- FTP: add test for FTPFILE_NOCWD: Avoid redundant CWDs
-
- Add libtest 661
-
- Closes #4417
-
-- [Zenju brought this change]
-
- FTP: url-decode path before evaluation
-
- Closes #4428
-
-Marcel Raad (27 Sep 2019)
-- tests: fix narrowing conversion warnings
-
- `timediff_t` is 64 bits wide also on 32-bit systems since
- commit b1616dad8f0.
-
- Closes https://github.com/curl/curl/pull/4415
-
-Jay Satiro (27 Sep 2019)
-- [Julian Z brought this change]
-
- vtls: Fix comment typo about macosx-version-min compiler flag
-
- Closes https://github.com/curl/curl/pull/4425
-
-Daniel Stenberg (26 Sep 2019)
-- [Yechiel Kalmenson brought this change]
-
- README: minor grammar fix
-
- Closes #4431
-
-- [Spezifant brought this change]
-
- HTTP3: fix prefix parameter for ngtcp2 build
-
- Closes #4430
-
-- quiche: don't close connection at end of stream!
-
-- quiche: set 'drain' when returning without having drained the queues
-
-- Revert "FTP: url-decode path before evaluation"
-
- This reverts commit 2f036a72d543e96128bd75cb0fedd88815fd42e2.
-
-- HTTP3: merged and simplified the two 'running' sections
-
-- HTTP3: show an --alt-svc using example too
-
-- [Zenju brought this change]
-
- FTP: url-decode path before evaluation
-
- Closes #4423
-
-- openssl: use strerror on SSL_ERROR_SYSCALL
-
- Instead of showing the somewhat nonsensical errno number, use strerror()
- to provide a more relatable error message.
-
- Closes #4411
-
-- HTTP3: update quic.aiortc.org + add link to server list
-
- Reported-by: Jeremy Lainé
-
-Jay Satiro (26 Sep 2019)
-- url: don't set appconnect time for non-ssl/non-ssh connections
-
- Prior to this change non-ssl/non-ssh connections that were reused set
- TIMER_APPCONNECT [1]. Arguably that was incorrect since no SSL/SSH
- handshake took place.
-
- [1]: TIMER_APPCONNECT is publicly known as CURLINFO_APPCONNECT_TIME in
- libcurl and %{time_appconnect} in the curl tool. It is documented as
- "the time until the SSL/SSH handshake is completed".
-
- Reported-by: Marcel Hernandez
-
- Ref: https://github.com/curl/curl/issues/3760
-
- Closes https://github.com/curl/curl/pull/3773
-
-Daniel Stenberg (25 Sep 2019)
-- ngtcp2: remove fprintf() calls
-
- - convert some of them to H3BUF() calls to infof()
- - remove some of them completely
- - made DEBUG_HTTP3 defined only if CURLDEBUG is set for now
-
- Closes #4421
-
-- [Jay Satiro brought this change]
-
- url: fix the NULL hostname compiler warning case
-
- Closes #4403
-
-- [Jay Satiro brought this change]
-
- travis: move the go install to linux-only
-
- ... to repair the build again
- Closes #4403
-
-- altsvc: correct the #ifdef for the ngtcp2 backend
-
-- altsvc: save h3 as h3-23
-
- Follow-up to d176a2c7e5
-
-- urlapi: question mark within fragment is still fragment
-
- The parser would check for a query part before fragment, which caused it
- to do wrong when the fragment contains a question mark.
-
- Extended test 1560 to verify.
-
- Reported-by: Alex Konev
- Fixes #4412
- Closes #4413
-
-- [Alex Samorukov brought this change]
-
- HTTP3.md: move -p for mkdir, remove -j for make
-
- - mkdir on OSX/Darwin requires `-p` argument before dir
-
- - portabbly figuring out number of cores is an exercise for somewhere
- else
-
- Closes #4407
-
-Patrick Monnerat (24 Sep 2019)
-- os400: getpeername() and getsockname() return ebcdic AF_UNIX sockaddr,
-
- As libcurl now uses these 2 system functions, wrappers are needed on os400
- to convert returned AF_UNIX sockaddrs to ascii.
-
- This is a follow-up to commit 7fb54ef.
- See also #4037.
- Closes #4214
-
-Jay Satiro (24 Sep 2019)
-- [Lucas Pardue brought this change]
-
- strcase: fix raw lowercasing the letter X
-
- Casing mistake in Curl_raw_tolower 'X' wasn't lowercased as 'x' prior to
- this change.
-
- Follow-up to 0023fce which added the function several days ago.
-
- Ref: https://github.com/curl/curl/pull/4401#discussion_r327396546
-
- Closes https://github.com/curl/curl/pull/4408
-
-Daniel Stenberg (23 Sep 2019)
-- http2: Expression 'stream->stream_id != - 1' is always true
-
- PVS-Studio warning
- Fixes #4402
-
-- http2: A value is being subtracted from the unsigned variable
-
- PVS-Studio warning
- Fixes #4402
-
-- libssh: part of conditional expression is always true: !result
-
- PVS-Studio warning
- Fixed #4402
-
-- libssh: part of conditional expression is always true
-
- PVS-Studio warning
- Fixes #4402
-
-- libssh: The expression is excessive or contains a misprint
-
- PVS-Studio warning
- Fixes #4402
-
-- quiche: The expression must be surrounded by parentheses
-
- PVS-Studio warning
- Fixes #4402
-
-- vauth: The parameter 'status' must be surrounded by parentheses
-
- PVS-Studio warning
- Fixes #4402
-
-- [Paul Dreik brought this change]
-
- doh: allow only http and https in debug mode
-
- Otherwise curl may be told to use for instance pop3 to
- communicate with the doh server, which most likely
- is not what you want.
-
- Found through fuzzing.
-
- Closes #4406
-
-- [Paul Dreik brought this change]
-
- doh: return early if there is no time left
-
- Closes #4406
-
-- [Barry Pollard brought this change]
-
- http: lowercase headernames for HTTP/2 and HTTP/3
-
- Closes #4401
- Fixes #4400
-
-Marcel Raad (23 Sep 2019)
-- vtls: fix narrowing conversion warnings
-
- Curl_timeleft returns `timediff_t`, which is 64 bits wide also on
- 32-bit systems since commit b1616dad8f0.
-
- Closes https://github.com/curl/curl/pull/4398
-
-Daniel Stenberg (23 Sep 2019)
-- [Joel Depooter brought this change]
-
- winbuild: Add manifest to curl.exe for proper OS version detection
-
- This is a small fix to commit ebd213270a017a6830928ee2e1f4a9cabc799898
- in pull request #1221. That commit added the CURL_EMBED_MANIFEST flag to
- CURL_RC_FLAGS. However, later in the file CURL_RC_FLAGS is
- overwritten. The fix is to append values to CURL_RC_FLAGS instead of
- overwriting
-
- Closes #4399
-
-- RELEASE-NOTES: synced
-
-Marcel Raad (22 Sep 2019)
-- openssl: fix compiler warning with LibreSSL
-
- It was already fixed for BoringSSL in commit a0f8fccb1e0.
- LibreSSL has had the second argument to SSL_CTX_set_min_proto_version
- as uint16_t ever since the function was added in [0].
-
- [0] https://github.com/libressl-portable/openbsd/commit/56f107201baefb5533486d665a58d8f57fd3aeda
-
- Closes https://github.com/curl/curl/pull/4397
-
-Daniel Stenberg (22 Sep 2019)
-- curl: exit the create_transfers loop on errors
-
- When looping around the ranges and given URLs to create transfers, all
- errors should exit the loop and return. Previously it would keep
- looping.
-
- Reported-by: SumatraPeter on github
- Bug: #4393
- Closes #4396
-
-Jay Satiro (21 Sep 2019)
-- socks: Fix destination host shown on SOCKS5 error
-
- Prior to this change when a server returned a socks5 connect error then
- curl would parse the destination address:port from that data and show it
- to the user as the destination:
-
- curld -v --socks5 10.0.3.1:1080 http://google.com:99
- * SOCKS5 communication to google.com:99
- * SOCKS5 connect to IPv4 172.217.12.206 (locally resolved)
- * Can't complete SOCKS5 connection to 253.127.0.0:26673. (1)
- curl: (7) Can't complete SOCKS5 connection to 253.127.0.0:26673. (1)
-
- That's incorrect because the address:port included in the connect error
- is actually a bind address:port (typically unused) and not the
- destination address:port. This fix changes curl to show the destination
- information that curl sent to the server instead:
-
- curld -v --socks5 10.0.3.1:1080 http://google.com:99
- * SOCKS5 communication to google.com:99
- * SOCKS5 connect to IPv4 172.217.7.14:99 (locally resolved)
- * Can't complete SOCKS5 connection to 172.217.7.14:99. (1)
- curl: (7) Can't complete SOCKS5 connection to 172.217.7.14:99. (1)
-
- curld -v --socks5-hostname 10.0.3.1:1080 http://google.com:99
- * SOCKS5 communication to google.com:99
- * SOCKS5 connect to google.com:99 (remotely resolved)
- * Can't complete SOCKS5 connection to google.com:99. (1)
- curl: (7) Can't complete SOCKS5 connection to google.com:99. (1)
-
- Ref: https://tools.ietf.org/html/rfc1928#section-6
-
- Closes https://github.com/curl/curl/pull/4394
-
-Daniel Stenberg (21 Sep 2019)
-- travis: enable ngtcp2 h3-23 builds
-
-- altsvc: both backends run h3-23 now
-
- Closes #4395
-
-- http: fix warning on conversion from int to bit
-
- Follow-up from 03ebe66d70
-
-- urldata: use 'bool' for the bit type on MSVC compilers
-
- Closes #4387
- Fixes #4379
-
-- appveyor: upgrade VS2017 to VS2019
-
- Closes #4383
-
-- [Zenju brought this change]
-
- FTP: FTPFILE_NOCWD: avoid redundant CWDs
-
- Closes #4382
-
-- cookie: pass in the correct cookie amount to qsort()
-
- As the loop discards cookies without domain set. This bug would lead to
- qsort() trying to sort uninitialized pointers. We have however not found
- it a security problem.
-
- Reported-by: Paul Dreik
- Closes #4386
-
-- [Paul Dreik brought this change]
-
- urlapi: avoid index underflow for short ipv6 hostnames
-
- If the input hostname is "[", hlen will underflow to max of size_t when
- it is subtracted with 2.
-
- hostname[hlen] will then cause a warning by ubsanitizer:
-
- runtime error: addition of unsigned offset to 0x<snip> overflowed to
- 0x<snip>
-
- I think that in practice, the generated code will work, and the output
- of hostname[hlen] will be the first character "[".
-
- This can be demonstrated by the following program (tested in both clang
- and gcc, with -O3)
-
- int main() {
- char* hostname=strdup("[");
- size_t hlen = strlen(hostname);
-
- hlen-=2;
- hostname++;
- printf("character is %d\n",+hostname[hlen]);
- free(hostname-1);
- }
-
- I found this through fuzzing, and even if it seems harmless, the proper
- thing is to return early with an error.
-
- Closes #4389
-
-- [Tatsuhiro Tsujikawa brought this change]
-
- ngtcp2: compile with latest ngtcp2 + nghttp3 draft-23
-
- Closes #4392
-
-- THANKS-filter: deal with my typos 'Jat' => 'Jay'
-
-- travis: use go master
-
- ... as the boringssl builds needs a very recent version
-
- Co-authored-by: Jat Satiro
- Closes #4361
-
-- tool_operate: removed unused variable 'done'
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- tool_operate: Expression 'config->resume_from' is always true
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- tool_getparam: remove duplicate switch case
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- libssh2: part of conditional expression is always true: !result
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- urlapi: Expression 'storep' is always true
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- urlapi: 'scheme' is always true
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- urlapi: part of conditional expression is always true: (relurl[0] == '/')
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- setopt: store CURLOPT_RTSP_SERVER_CSEQ correctly
-
- Fixes bug detected by PVS-Studio
- Fixes #4374
-
-- mime: make Curl_mime_duppart() assert if called without valid dst
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- http_proxy: part of conditional expression is always true: !error
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- imap: merged two case-branches performing the same action
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- multi: value '2L' is assigned to a boolean
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- easy: part of conditional expression is always true: !result
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- netrc: part of conditional expression is always true: !done
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- version: Expression 'left > 1' is always true
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- url: remove dead code
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- url: part of expression is always true: (bundle->multiuse == 0)
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- ftp: the conditional expression is always true
-
- ... both !result and (ftp->transfer != FTPTRANSFER_BODY)!
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- ftp: Expression 'ftpc->wait_data_conn' is always false
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- ftp: Expression 'ftpc->wait_data_conn' is always true
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- ftp: part of conditional expression is always true: !result
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
-
-- http: fix Expression 'http->postdata' is always false
-
- Fixes warning detected by PVS-Studio
- Fixes #4374
- Reported-by: Valerii Zapodovnikov
-
-- [Niall O'Reilly brought this change]
-
- doh: avoid truncating DNS QTYPE to lower octet
-
- Closes #4381
-
-- [Jens Finkhaeuser brought this change]
-
- urlapi: CURLU_NO_AUTHORITY allows empty authority/host part
-
- CURLU_NO_AUTHORITY is intended for use with unknown schemes (i.e. not
- "file:///") to override cURL's default demand that an authority exists.
-
- Closes #4349
-
-- version: next release will be 7.67.0
-
-- RELEASE-NOTES: synced
-
-- url: only reuse TLS connections with matching pinning
-
- If the requests have different CURLOPT_PINNEDPUBLICKEY strings set, the
- connection should not be reused.
-
- Bug: https://curl.haxx.se/mail/lib-2019-09/0061.html
- Reported-by: Sebastian Haglund
-
- Closes #4347
-
-- README: add OSS-Fuzz badge [skip ci]
-
- Closes #4380
-
-Michael Kaufmann (18 Sep 2019)
-- http: merge two "case" statements
-
-Daniel Stenberg (18 Sep 2019)
-- [Zenju brought this change]
-
- FTP: remove trailing slash from path for LIST/MLSD
-
- Closes #4348
-
-- mime: when disabled, avoid C99 macro
-
- Closes #4368
-
-- url: cleanup dangling DOH request headers too
-
- Follow-up to 9bc44ff64d9081
-
- Credit to OSS-Fuzz
- Bug: https://crbug.com/oss-fuzz/17269
-
- Closes #4372
-
-- [Christoph M. Becker brought this change]
-
- http2: relax verification of :authority in push promise requests
-
- If the :authority pseudo header field doesn't contain an explicit port,
- we assume it is valid for the default port, instead of rejecting the
- request for all ports.
-
- Ref: https://curl.haxx.se/mail/lib-2019-09/0041.html
-
- Closes #4365
-
-- doh: clean up dangling DOH handles and memory on easy close
-
- If you set the same URL for target as for DoH (and it isn't a DoH
- server), like "https://example.com" in both, the easy handles used for
- the DoH requests could be left "dangling" and end up not getting freed.
-
- Reported-by: Paul Dreik
- Closes #4366
-
-- unit1655: make it C90 compliant
-
- Unclear why this was not detected in the CI.
-
- Follow-up to b7666027296a
-
-- smb: check for full size message before reading message details
-
- To avoid reading of uninitialized data.
-
- Assisted-by: Max Dymond
- Bug: https://crbug.com/oss-fuzz/16907
- Closes #4363
-
-- quiche: persist connection details
-
- ... like we do for other protocols at connect time. This makes "curl -I"
- and other things work.
-
- Reported-by: George Liu
- Fixes #4358
- Closes #4360
-
-- openssl: fix warning with boringssl and SSL_CTX_set_min_proto_version
-
- Follow-up to ffe34b7b59
- Closes #4359
-
-- [Paul Dreik brought this change]
-
- doh: fix undefined behaviour and open up for gcc and clang optimization
-
- The undefined behaviour is annoying when running fuzzing with
- sanitizers. The codegen is the same, but the meaning is now not up for
- dispute. See https://cppinsights.io/s/516a2ff4
-
- By incrementing the pointer first, both gcc and clang recognize this as
- a bswap and optimizes it to a single instruction. See
- https://godbolt.org/z/994Zpx
-
- Closes #4350
-
-- [Paul Dreik brought this change]
-
- doh: fix (harmless) buffer overrun
-
- Added unit test case 1655 to verify.
- Close #4352
-
- the code correctly finds the flaws in the old code,
- if one temporarily restores doh.c to the old version.
-
-Alessandro Ghedini (15 Sep 2019)
-- docs: remove trailing ':' from section names in CURLOPT_TRAILER* man
-
-- docs: fix typo in CURLOPT_HTTP_VERSION man
-
-GitHub (14 Sep 2019)
-- [Daniel Stenberg brought this change]
-
- CI: inintial github action job
-
- First shot at a CI build on github actions
-
-Daniel Stenberg (13 Sep 2019)
-- appveyor: add a winbuild
-
- Assisted-by: Marcel Raad
- Assisted-by: Jay Satiro
-
- Closes #4324
-
-- FTP: allow "rubbish" prepended to the SIZE response
-
- This is a protocol violation but apparently there are legacy proprietary
- servers doing this.
-
- Added test 336 and 337 to verify.
-
- Reported-by: Philippe Marguinaud
- Closes #4339
-
-- [Zenju brought this change]
-
- FTP: skip CWD to entry dir when target is absolute
-
- Closes #4332
-
-Kamil Dudka (13 Sep 2019)
-- curl: fix memory leaked by parse_metalink()
-
- This commit fixes a regression introduced by curl-7_65_3-5-gb88940850.
- Detected by tests 2005, 2008, 2009, 2010, 2011, and 2012 with valgrind
- and libmetalink enabled.
-
- Closes #4326
-
-Daniel Stenberg (13 Sep 2019)
-- parsedate: still provide the name arrays when disabled
-
- If FILE or FTP are enabled, since they also use them!
-
- Reported-by: Roland Hieber
- Fixes #4325
- Closes #4343
-
-- [Gilles Vollant brought this change]
-
- curl:file2string: load large files much faster
-
- ... by using a more efficient realloc scheme.
-
- Bug: https://curl.haxx.se/mail/lib-2019-09/0045.html
- Closes #4336
-
-- openssl: close_notify on the FTP data connection doesn't mean closure
-
- For FTPS transfers, curl gets close_notify on the data connection
- without that being a signal to close the control connection!
-
- Regression since 3f5da4e59a556fc (7.65.0)
-
- Reported-by: Zenju on github
- Reviewed-by: Jay Satiro
- Fixes #4329
- Closes #4340
-
-- [Jimmy Gaussen brought this change]
-
- docs/HTTP3: fix `--with-ssl` ngtcp2 configure flag
-
- Closes #4338
-
-- RELEASE-NOTES: synced
-
-- curlver: bump to 7.66.1
-
-- [Zenju brought this change]
-
- setopt: make it easier to add new enum values
-
- ... by using the *_LAST define names better.
-
- Closes #4321
-
-- asyn-thread: s/AF_LOCAL/AF_UNIX for Solaris
-
- Reported-by: Dagobert Michelsen
- Fixes #4328
- Closes #4333
-
-- [Bernhard Walle brought this change]
-
- winbuild/MakefileBuild.vc: Add vssh
-
- Without that modification, the Windows build using the makefiles doesn't
- work.
-
- Signed-off-by: Bernhard Walle <bernhard.walle@posteo.eu>
-
- Fixes #4322
- Closes #4323
-
-Bernhard Walle (11 Sep 2019)
-- winbuild/MakefileBuild.vc: Fix line endings
-
- The file had mixed line endings.
-
- Signed-off-by: Bernhard Walle <bernhard.walle@posteo.eu>
-
-Jay Satiro (11 Sep 2019)
-- ldap: Stop using wide char version of ldapp_err2string
-
- Despite ldapp_err2string being documented by MS as returning a
- PCHAR (char *), when UNICODE it is mapped to ldap_err2stringW and
- returns PWCHAR (wchar_t *).
-
- We have lots of code that expects ldap_err2string to return char *,
- most of it failf used like this:
-
- failf(data, "LDAP local: Some error: %s", ldap_err2string(rc));
-
- Closes https://github.com/curl/curl/pull/4272
-
-Version 7.66.0 (10 Sep 2019)
-
-Daniel Stenberg (10 Sep 2019)
-- RELEASE-NOTES: curl 7.66.0
-
-- THANKS: from the 7.66.0 release
-
-- curl: make sure the parallel transfers do them all
-
- The logic could erroneously break the loop too early before all
- transfers had been transferred.
-
- Reported-by: Tom van der Woerdt
- Fixes #4316
- Closes #4317
-
-- urlapi: one colon is enough for the strspn() input (typo)
-
-- urlapi: verify the IPv6 numerical address
-
- It needs to parse correctly. Otherwise it could be tricked into letting
- through a-f using host names that libcurl would then resolve. Like
- '[ab.be]'.
-
- Reported-by: Thomas Vegas
- Closes #4315
-
-- [Clément Notin brought this change]
-
- openssl: use SSL_CTX_set_<min|max>_proto_version() when available
-
- OpenSSL 1.1.0 adds SSL_CTX_set_<min|max>_proto_version() that we now use
- when available. Existing code is preserved for older versions of
- OpenSSL.
-
- Closes #4304
-
-- [Clément Notin brought this change]
-
- openssl: indent, re-organize and add comments
-
-- [migueljcrum brought this change]
-
- sspi: fix memory leaks
-
- Closes #4299
-
-- travis: disable ngtcp2 builds (again)
-
-- Curl_fillreadbuffer: avoid double-free trailer buf on error
-
- Reviewed-by: Jay Satiro
- Reported-by: Thomas Vegas
-
- Closes #4307
-
-- tool_setopt: handle a libcurl build without netrc support
-
- Reported-by: codesniffer13 on github
- Fixes #4302
- Closes #4305
-
-- security:read_data fix bad realloc()
-
- ... that could end up a double-free
-
- CVE-2019-5481
- Bug: https://curl.haxx.se/docs/CVE-2019-5481.html
-
-- [Thomas Vegas brought this change]
-
- tftp: Alloc maximum blksize, and use default unless OACK is received
-
- Fixes potential buffer overflow from 'recvfrom()', should the server
- return an OACK without blksize.
-
- Bug: https://curl.haxx.se/docs/CVE-2019-5482.html
- CVE-2019-5482
-
-- [Thomas Vegas brought this change]
-
- tftp: return error when packet is too small for options
-
-- KNOWN_BUGS/TODO: cleanup and remove outdated issues
-
-- RELEASE-NOTES: synced
-
-- netrc: free 'home' on error
-
- Follow-up to f9c7ba9096ec2
-
- Coverity CID 1453474
-
- Closes #4291
-
-- urldata: avoid 'generic', use dedicated pointers
-
- For the 'proto' union within the connectdata struct.
-
- Closes #4290
-
-- cleanup: move functions out of url.c and make them static
-
- Closes #4289
-
-- smtp: check for and bail out on too short EHLO response
-
- Otherwise, a three byte response would make the smtp_state_ehlo_resp()
- function misbehave.
-
- Credit to OSS-Fuzz
- Bug: https://crbug.com/oss-fuzz/16918
-
- Assisted-by: Max Dymond
-
- Closes #4287
-
-- smb: init *msg to NULL in smb_send_and_recv()
-
- ... it might otherwise return OK from this function leaving that pointer
- uninitialized.
-
- Bug: https://crbug.com/oss-fuzz/16907
-
- Closes #4286
-
-- ROADMAP: updated after recent user poll
-
- In rough prio order
-
-- THANKS: remove duplicate
-
-- Curl_addr2string: take an addrlen argument too
-
- This allows the function to figure out if a unix domain socket has a
- file name or not associated with it! When a socket is created with
- socketpair(), as done in the fuzzer testing, the path struct member is
- uninitialized and must not be accessed.
-
- Bug: https://crbug.com/oss-fuzz/16699
-
- Closes #4283
-
-- [Rolf Eike Beer brought this change]
-
- CMake: remove needless newlines at end of gss variables
-
-- [Rolf Eike Beer brought this change]
-
- CI: remove duplicate configure flag for LGTM.com
-
-- [Rolf Eike Beer brought this change]
-
- CMake: use platform dependent name for dlopen() library
-
- Closes #4279
-
-- quiche: expire when poll returned data
-
- ... to make sure we continue draining the queue until empty
-
- Closes #4281
-
-- quiche: decrease available buffer size, don't assign it!
-
- Found-by: Jeremy Lainé
-
-- RELEASE-NOTES: synced
-
-- [Kyohei Kadota brought this change]
-
- curl: fix include conditions
-
-- [Kyohei Kadota brought this change]
-
- plan9: fix installation instructions
-
- Closes #4276
-
-- ngtcp2: on h3 stream close, call expire
-
- ... to trigger a new read to detect the stream close!
-
- Closes #4275
-
-- [Tatsuhiro Tsujikawa brought this change]
-
- ngtcp2: build latest ngtcp2 and ngtcp2_crypto_openssl
-
- Closes #4278
-
-- ngtcp2: set flow control window to stream buffer size
-
- Closes #4274
-
-- [Christopher Head brought this change]
-
- CURLOPT_HEADERFUNCTION.3: clarify
-
- Closes #4273
-
-- CURLINFO docs: mention that in redirects times are added
-
- Suggested-by: Brandon Dong
- Fixes #4250
- Closes #4269
-
-- travis: enable ngtcp2 builds again
-
- Switched to the openssl-quic-draft-22 openssl branch.
-
- Closes #4271
-
-- HTTP3: switched openssl branch to use
-
-- [Tatsuhiro Tsujikawa brought this change]
-
- ngtcp2: Build with latest ngtcp2 and ngtcp2_crypto_openssl
-
- Closes #4270
-
-- http2: when marked for closure and wanted to close == OK
-
- It could otherwise return an error even when closed correctly if GOAWAY
- had been received previously.
-
- Reported-by: Tom van der Woerdt
- Fixes #4267
- Closes #4268
-
-- RELEASE-NOTES: synced
-
-- build-openssl: fix build with Visual Studio 2019
-
- Reviewed-by: Marcel Raad
- Contributed-by: osabc on github
- Fixes #4188
- Closes #4266
-
-Kamil Dudka (26 Aug 2019)
-- vauth: return CURLE_AUTH_ERROR on gss_init_sec_context() failure
-
- This is a follow-up to https://github.com/curl/curl/pull/3864 .
-
- Closes #4224
-
-Daniel Stenberg (26 Aug 2019)
-- KNOWN_BUGS: USE_UNIX_SOCKETS on Windows
-
- Closes #4040
-
-- quiche: send the HTTP body correctly on callback uploads
-
- Closes #4265
-
-- travis: disable ngtcp2 builds (temporarily)
-
- Just too many API changes right now
-
- Closes #4264
-
-- ngtcp2: add support for SSLKEYLOGFILE
-
- Closes #4260
-
-- ngtcp2: improve h3 response receiving
-
- Closes #4259
-
-- ngtcp2: use nghttp3_version()
-
-- ngtcp2: sync with upstream API changes
-
- Assisted-by: Tatsuhiro Tsujikawa
-
-- [Kyle Abramowitz brought this change]
-
- scp: fix directory name length used in memcpy
-
- Fix read off end of array due to bad pointer math in getworkingpath for
- SCP home directory case.
-
- Closes #4258
diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS
index d39deffbfd..11cd57fdda 100644
--- a/libs/libcurl/docs/THANKS
+++ b/libs/libcurl/docs/THANKS
@@ -24,6 +24,7 @@ Adam Marcionek
Adam Piggott
Adam Sampson
Adam Tkac
+Adnan Khan
adnn on github
Adrian Burcea
Adrian Peniak
@@ -243,6 +244,7 @@ Bill Hoffman
Bill Middlecamp
Bill Nagel
Bill Pyne
+Billyzou0741326 on github
Bjarni Ingi Gislason
Bjoern Franke
Bjoern Sikora
@@ -318,6 +320,7 @@ Chandrakant Bagul
Charles Kerr
Charles Romestant
Chen Prog
+Cherish98 on github
Chester Liu
Chih-Chung Chang
Chih-Hsuan Yen
@@ -633,6 +636,7 @@ Ernest Beinrohr
Ernst Sjöstrand
Erwan Legrand
Erwin Authried
+Estanislau Augé-Pujadas
Ethan Glasser Camp
Etienne Simard
Eugene Kotlyarov
@@ -684,6 +688,7 @@ Frank Ticheler
Frank Van Uffelen
František Kučera
François Charlier
+François Rigault
Fred Machado
Fred New
Fred Noz
@@ -744,6 +749,7 @@ Greg Onufer
Greg Pratt
Greg Rowe
Greg Zavertnik
+Gregory Jefferis
Gregory Nicholls
Gregory Szorc
Griffin Downs
@@ -802,7 +808,9 @@ Howard Blaise
Howard Chu
hsiao yi
Hubert Kario
+Hugo van Kemenade
Huzaifa Sidhpurwala
+huzunhao on github
hydra3333 on github
Hzhijun
Ian D Allen
@@ -865,6 +873,7 @@ James Gallagher
James Griffiths
James Housley
James Knight
+James Le Cuirot
James MacMillan
James Slaughter
Jamie Lokier
@@ -993,6 +1002,7 @@ John Marshall
John McGowan
John P. McCaskey
John Schroeder
+John Simpson
John Starks
John Suprock
John V. Chow
@@ -1078,6 +1088,7 @@ Kai Sommerfeld
Kai-Uwe Rommel
Kalle Vahlman
Kamil Dudka
+Kane York
Kang Lin
Kang-Jin Lee
Karl Chen
@@ -1119,6 +1130,7 @@ Kobi Gurkan
Koen Dergent
Konstantin Isakov
Konstantin Kushnir
+kotoriのねこ
kouzhudong on github
kreshano on github
Kris Kennaway
@@ -1296,6 +1308,7 @@ Martin Lemke
Martin Skinner
Martin Staael
Martin Storsjö
+Martin V
Martin Vejnár
Marty Kuhrt
Maruko
@@ -1333,6 +1346,7 @@ Max Dymond
Max Katsev
Max Kellermann
Max Khon
+Max Peal
Max Savenkov
Maxim Ivanov
Maxim Perenesenko
@@ -1418,6 +1432,7 @@ Mischa Salle
Mitz Wark
mkzero on github
Mohamed Lrhazi
+Mohamed Osama
Mohammad AlSaleh
Mohammad Hasbini
Mohun Biswas
@@ -1428,6 +1443,7 @@ Moti Avrahami
MrdUkk on github
MrSorcus on github
Muhammad Herdiansyah
+Murugan Balraj
Muz Dima
Myk Taylor
Nach M. S.
@@ -1471,6 +1487,7 @@ Nicolas François
Nicolas Grekas
Nicolas Guillier
Nicolas Morey-Chaisemartin
+Nicolas Sterchele
Niels van Tongeren
Nikita Schmidt
Nikitinskit Dmitriy
@@ -1642,11 +1659,13 @@ Praveen Pvs
Priyanka Shah
Przemysław Tomaszewski
pszemus on github
+puckipedia on github
Puneet Pawaia
Quagmire
Quanah Gibson-Mount
Quinn Slack
R. Dennis Steed
+Radoslav Georgiev
Radu Simionescu
Rafa Muyo
Rafael Antonio
@@ -1695,6 +1714,7 @@ Rich Burridge
Rich Gray
Rich Mirch
Rich Rauenzahn
+Rich Salz
Rich Turner
Richard Adams
Richard Alcock
@@ -1725,6 +1745,7 @@ Ricky Leverence
Ricky-Tigg on github
Rider Linden
Rikard Falkeborn
+rl1987 on github
Rob Cotrone
Rob Crittenden
Rob Davies
@@ -1792,6 +1813,7 @@ Ryuichi KAWAMATA
Rémy Léone
S. Moonesamy
Salah-Eddin Shaban
+Saleem Abdulrasool
Salvador Dávila
Salvatore Sorrentino
Sam Deane
@@ -1801,6 +1823,7 @@ Sam Schanken
Sampo Kellomaki
Samuel Díaz García
Samuel Listopad
+Samuel Marks
Samuel Surtees
Samuel Thibault
Sander Gates
@@ -1868,8 +1891,10 @@ Simon Josefsson
Simon Legner
Simon Liu
Simon Warta
+Siva Sivaraman
SLDiggie on github
smuellerDD on github
+sn on hackerone
Somnath Kundu
Song Ma
Sonia Subramanian
@@ -1960,7 +1985,9 @@ thanhchungbtc on github
The Infinnovation team
TheAssassin on github
Theodore Dubois
+therealhirudo on github
tholin on github
+Thomas Bouzerar
Thomas Braun
Thomas Gamper
Thomas Glanzmann
@@ -2067,6 +2094,7 @@ Ulrich Doehner
Ulrich Telle
Ulrich Zadow
Valentin David
+Valentyn Korniienko
Valerii Zapodovnikov
vanillajonathan on github
Vasiliy Faronov
@@ -2102,6 +2130,7 @@ Vojtěch Král
Volker Schmid
Vsevolod Novikov
vshmuk on hackerone
+Vyron Tsingaras
W. Mark Kubacki
Waldek Kozba
Walter J. Mack
@@ -2111,6 +2140,7 @@ Wayne Haigh
Wenchao Li
Wenxiang Qian
Werner Koch
+Werner Stolz
wesinator on github
Wesley Laxton
Wesley Miaw
@@ -2118,6 +2148,7 @@ Wez Furlong
Wham Bang
Wilfredo Sanchez
Will Dietz
+Will Roberts
Willem Sparreboom
William A. Rowe Jr
William Ahern
@@ -2165,11 +2196,13 @@ Zhao Yisha
Zhaoyang Wu
Zhibiao Wu
Zhouyihai Ding
+zloi-user on github
Zmey Petroff
Zvi Har'El
zzq1015 on github
İsmail Dönmez
Łukasz Domeradzki
Štefan Kremeň
+Коваленко Анатолий Викторович
Никита Дорохин
加藤郁之
diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h
index 11246ea303..d5f8817d5f 100644
--- a/libs/libcurl/include/curl/curl.h
+++ b/libs/libcurl/include/curl/curl.h
@@ -838,6 +838,10 @@ typedef enum {
behavior is present. */
#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
+/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
+ operating system. Currently implemented under MS-Windows. */
+#define CURLSSLOPT_NATIVE_CA (1<<4)
+
/* The default connection attempt delay in milliseconds for happy eyeballs.
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
this value, keep them in sync. */
@@ -946,6 +950,7 @@ typedef enum {
#define CURLOPTTYPE_OBJECTPOINT 10000
#define CURLOPTTYPE_FUNCTIONPOINT 20000
#define CURLOPTTYPE_OFF_T 30000
+#define CURLOPTTYPE_BLOB 40000
/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
string options from the header file */
@@ -1955,6 +1960,17 @@ typedef enum {
/* allow RCPT TO command to fail for some recipients */
CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290),
+ /* the private SSL-certificate as a "blob" */
+ CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
+ CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292),
+ CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293),
+ CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294),
+ CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295),
+
+ /* Issuer certificate for proxy */
+ CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
+ CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2111,8 +2127,8 @@ CURL_EXTERN int curl_strequal(const char *s1, const char *s2);
CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
/* Mime/form handling support. */
-typedef struct curl_mime_s curl_mime; /* Mime context. */
-typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */
+typedef struct curl_mime curl_mime; /* Mime context. */
+typedef struct curl_mimepart curl_mimepart; /* Mime part context. */
/*
* NAME curl_mime_init()
@@ -2486,10 +2502,11 @@ struct curl_slist {
* subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
*/
-typedef struct {
+struct curl_ssl_backend {
curl_sslbackend id;
const char *name;
-} curl_ssl_backend;
+};
+typedef struct curl_ssl_backend curl_ssl_backend;
typedef enum {
CURLSSLSET_OK = 0,
@@ -2741,7 +2758,7 @@ typedef enum {
from above. */
#define CURLVERSION_NOW CURLVERSION_SEVENTH
-typedef struct {
+struct curl_version_info_data {
CURLversion age; /* age of the returned struct */
const char *version; /* LIBCURL_VERSION */
unsigned int version_num; /* LIBCURL_VERSION_NUM */
@@ -2785,7 +2802,8 @@ typedef struct {
const char *capath; /* the built-in default CURLOPT_CAPATH, might
be NULL */
-} curl_version_info_data;
+};
+typedef struct curl_version_info_data curl_version_info_data;
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h
index 39e430be01..62e0beeb80 100644
--- a/libs/libcurl/include/curl/curlver.h
+++ b/libs/libcurl/include/curl/curlver.h
@@ -30,16 +30,16 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "7.70.0"
+#define LIBCURL_VERSION "7.71.0"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 70
+#define LIBCURL_VERSION_MINOR 71
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
- parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+ parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
@@ -57,7 +57,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 0x074600
+#define LIBCURL_VERSION_NUM 0x074700
/*
* This is the date and time when the full source package was created. The
@@ -68,7 +68,7 @@
*
* "2007-11-23"
*/
-#define LIBCURL_TIMESTAMP "2020-04-29"
+#define LIBCURL_TIMESTAMP "2020-06-24"
#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/easy.h b/libs/libcurl/include/curl/easy.h
index 592f5d3c1c..9aef133962 100644
--- a/libs/libcurl/include/curl/easy.h
+++ b/libs/libcurl/include/curl/easy.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -25,6 +25,17 @@
extern "C" {
#endif
+/* Flag bits in the curl_blob struct: */
+#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
+#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
+
+struct curl_blob {
+ void *data;
+ size_t len;
+ unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
+ left zeroes */
+};
+
CURL_EXTERN CURL *curl_easy_init(void);
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
diff --git a/libs/libcurl/include/curl/multi.h b/libs/libcurl/include/curl/multi.h
index bda9bb7b81..3039e787ea 100644
--- a/libs/libcurl/include/curl/multi.h
+++ b/libs/libcurl/include/curl/multi.h
@@ -377,12 +377,10 @@ typedef enum {
will not be considered for pipelining */
CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
- /* a list of site names(+port) that are blacklisted from
- pipelining */
+ /* a list of site names(+port) that are blocked from pipelining */
CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
- /* a list of server types that are blacklisted from
- pipelining */
+ /* a list of server types that are blocked from pipelining */
CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
/* maximum number of open connections in total */
diff --git a/libs/libcurl/include/curl/typecheck-gcc.h b/libs/libcurl/include/curl/typecheck-gcc.h
index 03c84fc85b..f8cb921f2e 100644
--- a/libs/libcurl/include/curl/typecheck-gcc.h
+++ b/libs/libcurl/include/curl/typecheck-gcc.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -248,7 +248,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
#define curlcheck_off_t_option(option) \
- ((option) > CURLOPTTYPE_OFF_T)
+ (((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
/* evaluates to true if option takes a char* argument */
#define curlcheck_string_option(option) \
@@ -392,8 +392,9 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
/* groups of curl_easy_getinfo infos that take the same type of argument */
/* evaluates to true if info expects a pointer to char * argument */
-#define curlcheck_string_info(info) \
- (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+#define curlcheck_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
+ (info) != CURLINFO_PRIVATE)
/* evaluates to true if info expects a pointer to long argument */
#define curlcheck_long_info(info) \
diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in
index 7edf8abc1a..5c99a1d816 100644
--- a/libs/libcurl/src/Makefile.in
+++ b/libs/libcurl/src/Makefile.in
@@ -227,7 +227,8 @@ am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \
libcurl_la-telnet.lo libcurl_la-tftp.lo libcurl_la-timeval.lo \
libcurl_la-transfer.lo libcurl_la-urlapi.lo \
libcurl_la-version.lo libcurl_la-warnless.lo \
- libcurl_la-wildcard.lo libcurl_la-x509asn1.lo
+ libcurl_la-wildcard.lo libcurl_la-x509asn1.lo \
+ libcurl_la-dynbuf.lo
am__dirstamp = $(am__leading_dot)dirstamp
am__objects_2 = vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \
vauth/libcurl_la-digest.lo vauth/libcurl_la-digest_sspi.lo \
@@ -236,14 +237,16 @@ am__objects_2 = vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \
vauth/libcurl_la-oauth2.lo vauth/libcurl_la-spnego_gssapi.lo \
vauth/libcurl_la-spnego_sspi.lo vauth/libcurl_la-vauth.lo
am__objects_3 = vtls/libcurl_la-bearssl.lo vtls/libcurl_la-gskit.lo \
- vtls/libcurl_la-gtls.lo vtls/libcurl_la-mbedtls.lo \
+ vtls/libcurl_la-gtls.lo vtls/libcurl_la-keylog.lo \
+ vtls/libcurl_la-mbedtls.lo \
vtls/libcurl_la-mbedtls_threadlock.lo \
vtls/libcurl_la-mesalink.lo vtls/libcurl_la-nss.lo \
vtls/libcurl_la-openssl.lo vtls/libcurl_la-schannel.lo \
vtls/libcurl_la-schannel_verify.lo \
vtls/libcurl_la-sectransp.lo vtls/libcurl_la-vtls.lo \
vtls/libcurl_la-wolfssl.lo
-am__objects_4 = vquic/libcurl_la-ngtcp2.lo vquic/libcurl_la-quiche.lo
+am__objects_4 = vquic/libcurl_la-ngtcp2.lo vquic/libcurl_la-quiche.lo \
+ vquic/libcurl_la-vquic.lo
am__objects_5 = vssh/libcurl_la-libssh.lo vssh/libcurl_la-libssh2.lo \
vssh/libcurl_la-wolfssh.lo
am__objects_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
@@ -314,7 +317,7 @@ am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \
libcurlu_la-timeval.lo libcurlu_la-transfer.lo \
libcurlu_la-urlapi.lo libcurlu_la-version.lo \
libcurlu_la-warnless.lo libcurlu_la-wildcard.lo \
- libcurlu_la-x509asn1.lo
+ libcurlu_la-x509asn1.lo libcurlu_la-dynbuf.lo
am__objects_10 = vauth/libcurlu_la-cleartext.lo \
vauth/libcurlu_la-cram.lo vauth/libcurlu_la-digest.lo \
vauth/libcurlu_la-digest_sspi.lo \
@@ -324,7 +327,8 @@ am__objects_10 = vauth/libcurlu_la-cleartext.lo \
vauth/libcurlu_la-spnego_gssapi.lo \
vauth/libcurlu_la-spnego_sspi.lo vauth/libcurlu_la-vauth.lo
am__objects_11 = vtls/libcurlu_la-bearssl.lo vtls/libcurlu_la-gskit.lo \
- vtls/libcurlu_la-gtls.lo vtls/libcurlu_la-mbedtls.lo \
+ vtls/libcurlu_la-gtls.lo vtls/libcurlu_la-keylog.lo \
+ vtls/libcurlu_la-mbedtls.lo \
vtls/libcurlu_la-mbedtls_threadlock.lo \
vtls/libcurlu_la-mesalink.lo vtls/libcurlu_la-nss.lo \
vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-schannel.lo \
@@ -332,7 +336,7 @@ am__objects_11 = vtls/libcurlu_la-bearssl.lo vtls/libcurlu_la-gskit.lo \
vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-vtls.lo \
vtls/libcurlu_la-wolfssl.lo
am__objects_12 = vquic/libcurlu_la-ngtcp2.lo \
- vquic/libcurlu_la-quiche.lo
+ vquic/libcurlu_la-quiche.lo vquic/libcurlu_la-vquic.lo
am__objects_13 = vssh/libcurlu_la-libssh.lo \
vssh/libcurlu_la-libssh2.lo vssh/libcurlu_la-wolfssh.lo
am__objects_14 = $(am__objects_9) $(am__objects_10) $(am__objects_11) \
@@ -387,6 +391,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurl_la-curl_threads.Plo \
./$(DEPDIR)/libcurl_la-dict.Plo ./$(DEPDIR)/libcurl_la-doh.Plo \
./$(DEPDIR)/libcurl_la-dotdot.Plo \
+ ./$(DEPDIR)/libcurl_la-dynbuf.Plo \
./$(DEPDIR)/libcurl_la-easy.Plo \
./$(DEPDIR)/libcurl_la-escape.Plo \
./$(DEPDIR)/libcurl_la-file.Plo \
@@ -497,6 +502,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurlu_la-dict.Plo \
./$(DEPDIR)/libcurlu_la-doh.Plo \
./$(DEPDIR)/libcurlu_la-dotdot.Plo \
+ ./$(DEPDIR)/libcurlu_la-dynbuf.Plo \
./$(DEPDIR)/libcurlu_la-easy.Plo \
./$(DEPDIR)/libcurlu_la-escape.Plo \
./$(DEPDIR)/libcurlu_la-file.Plo \
@@ -606,8 +612,10 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
vauth/$(DEPDIR)/libcurlu_la-vauth.Plo \
vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo \
vquic/$(DEPDIR)/libcurl_la-quiche.Plo \
+ vquic/$(DEPDIR)/libcurl_la-vquic.Plo \
vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo \
vquic/$(DEPDIR)/libcurlu_la-quiche.Plo \
+ vquic/$(DEPDIR)/libcurlu_la-vquic.Plo \
vssh/$(DEPDIR)/libcurl_la-libssh.Plo \
vssh/$(DEPDIR)/libcurl_la-libssh2.Plo \
vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo \
@@ -617,6 +625,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
vtls/$(DEPDIR)/libcurl_la-bearssl.Plo \
vtls/$(DEPDIR)/libcurl_la-gskit.Plo \
vtls/$(DEPDIR)/libcurl_la-gtls.Plo \
+ vtls/$(DEPDIR)/libcurl_la-keylog.Plo \
vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo \
vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo \
vtls/$(DEPDIR)/libcurl_la-mesalink.Plo \
@@ -630,6 +639,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo \
vtls/$(DEPDIR)/libcurlu_la-gskit.Plo \
vtls/$(DEPDIR)/libcurlu_la-gtls.Plo \
+ vtls/$(DEPDIR)/libcurlu_la-keylog.Plo \
vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo \
vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo \
vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo \
@@ -769,6 +779,7 @@ LCOV = @LCOV@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBCURL_NO_SHARED = @LIBCURL_NO_SHARED@
LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@
LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@
LIBMETALINK_LIBS = @LIBMETALINK_LIBS@
@@ -981,17 +992,17 @@ LIB_VAUTH_CFILES = vauth/cleartext.c vauth/cram.c vauth/digest.c \
vauth/vauth.c
LIB_VAUTH_HFILES = vauth/digest.h vauth/ntlm.h vauth/vauth.h
-LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/mbedtls.c \
- vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c vtls/openssl.c \
- vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c vtls/vtls.c \
- vtls/wolfssl.c
+LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/keylog.c \
+ vtls/mbedtls.c vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c \
+ vtls/openssl.c vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c \
+ vtls/vtls.c vtls/wolfssl.c
-LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/mbedtls.h \
- vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h vtls/openssl.h \
- vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
+LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/keylog.h \
+ vtls/mbedtls.h vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h \
+ vtls/openssl.h vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
-LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
-LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
+LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c vquic/vquic.c
+LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h vquic/vquic.h
LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
LIB_VSSH_HFILES = vssh/ssh.h
LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \
@@ -1010,7 +1021,7 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.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 timeval.c \
- transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c
+ transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c
LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \
@@ -1029,7 +1040,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \
timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \
- x509asn1.h
+ x509asn1.h dynbuf.h
LIB_RCFILES = libcurl.rc
CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \
@@ -1190,6 +1201,8 @@ vtls/libcurl_la-gskit.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurl_la-gtls.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
+vtls/libcurl_la-keylog.lo: vtls/$(am__dirstamp) \
+ vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurl_la-mbedtls.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurl_la-mbedtls_threadlock.lo: vtls/$(am__dirstamp) \
@@ -1220,6 +1233,8 @@ vquic/libcurl_la-ngtcp2.lo: vquic/$(am__dirstamp) \
vquic/$(DEPDIR)/$(am__dirstamp)
vquic/libcurl_la-quiche.lo: vquic/$(am__dirstamp) \
vquic/$(DEPDIR)/$(am__dirstamp)
+vquic/libcurl_la-vquic.lo: vquic/$(am__dirstamp) \
+ vquic/$(DEPDIR)/$(am__dirstamp)
vssh/$(am__dirstamp):
@$(MKDIR_P) vssh
@: > vssh/$(am__dirstamp)
@@ -1265,6 +1280,8 @@ vtls/libcurlu_la-gskit.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurlu_la-gtls.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
+vtls/libcurlu_la-keylog.lo: vtls/$(am__dirstamp) \
+ vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurlu_la-mbedtls.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurlu_la-mbedtls_threadlock.lo: vtls/$(am__dirstamp) \
@@ -1289,6 +1306,8 @@ vquic/libcurlu_la-ngtcp2.lo: vquic/$(am__dirstamp) \
vquic/$(DEPDIR)/$(am__dirstamp)
vquic/libcurlu_la-quiche.lo: vquic/$(am__dirstamp) \
vquic/$(DEPDIR)/$(am__dirstamp)
+vquic/libcurlu_la-vquic.lo: vquic/$(am__dirstamp) \
+ vquic/$(DEPDIR)/$(am__dirstamp)
vssh/libcurlu_la-libssh.lo: vssh/$(am__dirstamp) \
vssh/$(DEPDIR)/$(am__dirstamp)
vssh/libcurlu_la-libssh2.lo: vssh/$(am__dirstamp) \
@@ -1343,6 +1362,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dict.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-doh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dotdot.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dynbuf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easy.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-escape.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-file.Plo@am__quote@ # am--include-marker
@@ -1456,6 +1476,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dict.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-doh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dotdot.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dynbuf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easy.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-escape.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-file.Plo@am__quote@ # am--include-marker
@@ -1565,8 +1586,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-vauth.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurl_la-quiche.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurl_la-vquic.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurlu_la-quiche.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurlu_la-vquic.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh2.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo@am__quote@ # am--include-marker
@@ -1576,6 +1599,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-bearssl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gskit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gtls.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-keylog.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mesalink.Plo@am__quote@ # am--include-marker
@@ -1589,6 +1613,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gskit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gtls.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-keylog.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo@am__quote@ # am--include-marker
@@ -2421,6 +2446,13 @@ libcurl_la-x509asn1.lo: x509asn1.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-x509asn1.lo `test -f 'x509asn1.c' || echo '$(srcdir)/'`x509asn1.c
+libcurl_la-dynbuf.lo: dynbuf.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-dynbuf.lo -MD -MP -MF $(DEPDIR)/libcurl_la-dynbuf.Tpo -c -o libcurl_la-dynbuf.lo `test -f 'dynbuf.c' || echo '$(srcdir)/'`dynbuf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-dynbuf.Tpo $(DEPDIR)/libcurl_la-dynbuf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dynbuf.c' object='libcurl_la-dynbuf.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-dynbuf.lo `test -f 'dynbuf.c' || echo '$(srcdir)/'`dynbuf.c
+
vauth/libcurl_la-cleartext.lo: vauth/cleartext.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 vauth/libcurl_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo -c -o vauth/libcurl_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo vauth/$(DEPDIR)/libcurl_la-cleartext.Plo
@@ -2526,6 +2558,13 @@ vtls/libcurl_la-gtls.lo: vtls/gtls.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 vtls/libcurl_la-gtls.lo `test -f 'vtls/gtls.c' || echo '$(srcdir)/'`vtls/gtls.c
+vtls/libcurl_la-keylog.lo: vtls/keylog.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 vtls/libcurl_la-keylog.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-keylog.Tpo -c -o vtls/libcurl_la-keylog.lo `test -f 'vtls/keylog.c' || echo '$(srcdir)/'`vtls/keylog.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-keylog.Tpo vtls/$(DEPDIR)/libcurl_la-keylog.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/keylog.c' object='vtls/libcurl_la-keylog.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 vtls/libcurl_la-keylog.lo `test -f 'vtls/keylog.c' || echo '$(srcdir)/'`vtls/keylog.c
+
vtls/libcurl_la-mbedtls.lo: vtls/mbedtls.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 vtls/libcurl_la-mbedtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-mbedtls.Tpo -c -o vtls/libcurl_la-mbedtls.lo `test -f 'vtls/mbedtls.c' || echo '$(srcdir)/'`vtls/mbedtls.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-mbedtls.Tpo vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
@@ -2610,6 +2649,13 @@ vquic/libcurl_la-quiche.lo: vquic/quiche.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 vquic/libcurl_la-quiche.lo `test -f 'vquic/quiche.c' || echo '$(srcdir)/'`vquic/quiche.c
+vquic/libcurl_la-vquic.lo: vquic/vquic.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 vquic/libcurl_la-vquic.lo -MD -MP -MF vquic/$(DEPDIR)/libcurl_la-vquic.Tpo -c -o vquic/libcurl_la-vquic.lo `test -f 'vquic/vquic.c' || echo '$(srcdir)/'`vquic/vquic.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurl_la-vquic.Tpo vquic/$(DEPDIR)/libcurl_la-vquic.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vquic/vquic.c' object='vquic/libcurl_la-vquic.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 vquic/libcurl_la-vquic.lo `test -f 'vquic/vquic.c' || echo '$(srcdir)/'`vquic/vquic.c
+
vssh/libcurl_la-libssh.lo: vssh/libssh.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 vssh/libcurl_la-libssh.lo -MD -MP -MF vssh/$(DEPDIR)/libcurl_la-libssh.Tpo -c -o vssh/libcurl_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurl_la-libssh.Tpo vssh/$(DEPDIR)/libcurl_la-libssh.Plo
@@ -3422,6 +3468,13 @@ libcurlu_la-x509asn1.lo: x509asn1.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-x509asn1.lo `test -f 'x509asn1.c' || echo '$(srcdir)/'`x509asn1.c
+libcurlu_la-dynbuf.lo: dynbuf.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-dynbuf.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-dynbuf.Tpo -c -o libcurlu_la-dynbuf.lo `test -f 'dynbuf.c' || echo '$(srcdir)/'`dynbuf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-dynbuf.Tpo $(DEPDIR)/libcurlu_la-dynbuf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dynbuf.c' object='libcurlu_la-dynbuf.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-dynbuf.lo `test -f 'dynbuf.c' || echo '$(srcdir)/'`dynbuf.c
+
vauth/libcurlu_la-cleartext.lo: vauth/cleartext.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 vauth/libcurlu_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo -c -o vauth/libcurlu_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo
@@ -3527,6 +3580,13 @@ vtls/libcurlu_la-gtls.lo: vtls/gtls.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 vtls/libcurlu_la-gtls.lo `test -f 'vtls/gtls.c' || echo '$(srcdir)/'`vtls/gtls.c
+vtls/libcurlu_la-keylog.lo: vtls/keylog.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 vtls/libcurlu_la-keylog.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-keylog.Tpo -c -o vtls/libcurlu_la-keylog.lo `test -f 'vtls/keylog.c' || echo '$(srcdir)/'`vtls/keylog.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-keylog.Tpo vtls/$(DEPDIR)/libcurlu_la-keylog.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/keylog.c' object='vtls/libcurlu_la-keylog.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 vtls/libcurlu_la-keylog.lo `test -f 'vtls/keylog.c' || echo '$(srcdir)/'`vtls/keylog.c
+
vtls/libcurlu_la-mbedtls.lo: vtls/mbedtls.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 vtls/libcurlu_la-mbedtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-mbedtls.Tpo -c -o vtls/libcurlu_la-mbedtls.lo `test -f 'vtls/mbedtls.c' || echo '$(srcdir)/'`vtls/mbedtls.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-mbedtls.Tpo vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo
@@ -3611,6 +3671,13 @@ vquic/libcurlu_la-quiche.lo: vquic/quiche.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 vquic/libcurlu_la-quiche.lo `test -f 'vquic/quiche.c' || echo '$(srcdir)/'`vquic/quiche.c
+vquic/libcurlu_la-vquic.lo: vquic/vquic.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 vquic/libcurlu_la-vquic.lo -MD -MP -MF vquic/$(DEPDIR)/libcurlu_la-vquic.Tpo -c -o vquic/libcurlu_la-vquic.lo `test -f 'vquic/vquic.c' || echo '$(srcdir)/'`vquic/vquic.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurlu_la-vquic.Tpo vquic/$(DEPDIR)/libcurlu_la-vquic.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vquic/vquic.c' object='vquic/libcurlu_la-vquic.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 vquic/libcurlu_la-vquic.lo `test -f 'vquic/vquic.c' || echo '$(srcdir)/'`vquic/vquic.c
+
vssh/libcurlu_la-libssh.lo: vssh/libssh.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 vssh/libcurlu_la-libssh.lo -MD -MP -MF vssh/$(DEPDIR)/libcurlu_la-libssh.Tpo -c -o vssh/libcurlu_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurlu_la-libssh.Tpo vssh/$(DEPDIR)/libcurlu_la-libssh.Plo
@@ -3809,6 +3876,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurl_la-dict.Plo
-rm -f ./$(DEPDIR)/libcurl_la-doh.Plo
-rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo
+ -rm -f ./$(DEPDIR)/libcurl_la-dynbuf.Plo
-rm -f ./$(DEPDIR)/libcurl_la-easy.Plo
-rm -f ./$(DEPDIR)/libcurl_la-escape.Plo
-rm -f ./$(DEPDIR)/libcurl_la-file.Plo
@@ -3922,6 +3990,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurlu_la-dict.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-doh.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo
+ -rm -f ./$(DEPDIR)/libcurlu_la-dynbuf.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-escape.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-file.Plo
@@ -4031,8 +4100,10 @@ distclean: distclean-am
-rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo
-rm -f vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo
-rm -f vquic/$(DEPDIR)/libcurl_la-quiche.Plo
+ -rm -f vquic/$(DEPDIR)/libcurl_la-vquic.Plo
-rm -f vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo
-rm -f vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
+ -rm -f vquic/$(DEPDIR)/libcurlu_la-vquic.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo
@@ -4042,6 +4113,7 @@ distclean: distclean-am
-rm -f vtls/$(DEPDIR)/libcurl_la-bearssl.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurl_la-keylog.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo
@@ -4055,6 +4127,7 @@ distclean: distclean-am
-rm -f vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurlu_la-keylog.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo
@@ -4140,6 +4213,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurl_la-dict.Plo
-rm -f ./$(DEPDIR)/libcurl_la-doh.Plo
-rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo
+ -rm -f ./$(DEPDIR)/libcurl_la-dynbuf.Plo
-rm -f ./$(DEPDIR)/libcurl_la-easy.Plo
-rm -f ./$(DEPDIR)/libcurl_la-escape.Plo
-rm -f ./$(DEPDIR)/libcurl_la-file.Plo
@@ -4253,6 +4327,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurlu_la-dict.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-doh.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo
+ -rm -f ./$(DEPDIR)/libcurlu_la-dynbuf.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-escape.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-file.Plo
@@ -4362,8 +4437,10 @@ maintainer-clean: maintainer-clean-am
-rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo
-rm -f vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo
-rm -f vquic/$(DEPDIR)/libcurl_la-quiche.Plo
+ -rm -f vquic/$(DEPDIR)/libcurl_la-vquic.Plo
-rm -f vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo
-rm -f vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
+ -rm -f vquic/$(DEPDIR)/libcurlu_la-vquic.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo
@@ -4373,6 +4450,7 @@ maintainer-clean: maintainer-clean-am
-rm -f vtls/$(DEPDIR)/libcurl_la-bearssl.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurl_la-keylog.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo
@@ -4386,6 +4464,7 @@ maintainer-clean: maintainer-clean-am
-rm -f vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurlu_la-keylog.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo
diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc
index e3cf41891a..723b826e90 100644
--- a/libs/libcurl/src/Makefile.inc
+++ b/libs/libcurl/src/Makefile.inc
@@ -27,18 +27,18 @@ LIB_VAUTH_CFILES = vauth/cleartext.c vauth/cram.c vauth/digest.c \
LIB_VAUTH_HFILES = vauth/digest.h vauth/ntlm.h vauth/vauth.h
-LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/mbedtls.c \
- vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c vtls/openssl.c \
- vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c vtls/vtls.c \
- vtls/wolfssl.c
+LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/keylog.c \
+ vtls/mbedtls.c vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c \
+ vtls/openssl.c vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c \
+ vtls/vtls.c vtls/wolfssl.c
-LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/mbedtls.h \
- vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h vtls/openssl.h \
- vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
+LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/keylog.h \
+ vtls/mbedtls.h vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h \
+ vtls/openssl.h vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
-LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
+LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c vquic/vquic.c
-LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
+LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h vquic/vquic.h
LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
@@ -60,7 +60,7 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.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 timeval.c \
- transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c
+ transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c
LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \
@@ -79,7 +79,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \
timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \
- x509asn1.h
+ x509asn1.h dynbuf.h
LIB_RCFILES = libcurl.rc
diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c
index c39d86eaff..c2ec489d9e 100644
--- a/libs/libcurl/src/altsvc.c
+++ b/libs/libcurl/src/altsvc.c
@@ -50,8 +50,10 @@
#define MAX_ALTSVC_ALPNLENSTR "10"
#define MAX_ALTSVC_ALPNLEN 10
-#if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
-#define H3VERSION "h3-27"
+#if defined(USE_QUICHE) && !defined(UNITTESTS)
+#define H3VERSION "h3-29"
+#elif defined(USE_NGTCP2) && !defined(UNITTESTS)
+#define H3VERSION "h3-29"
#else
#define H3VERSION "h3"
#endif
@@ -167,7 +169,6 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
as->prio = prio;
as->persist = persist ? 1 : 0;
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
- asi->num++; /* one more entry */
}
}
@@ -408,7 +409,6 @@ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
strcasecompare(srchost, as->src.host)) {
Curl_llist_remove(&asi->list, e, NULL);
altsvc_free(as);
- asi->num--;
}
}
}
@@ -429,6 +429,8 @@ static time_t debugtime(void *unused)
#define time(x) debugtime(x)
#endif
+#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
+
/*
* Curl_altsvc_parse() takes an incoming alt-svc response header and stores
* the data correctly in the cache.
@@ -474,7 +476,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
dstalpnid = alpn2alpnid(alpnbuf);
p++;
if(*p == '\"') {
- const char *dsthost;
+ const char *dsthost = "";
const char *value_ptr;
char option[32];
unsigned long num;
@@ -518,12 +520,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
/* Handle the optional 'ma' and 'persist' flags. Unknown flags
are skipped. */
for(;;) {
- while(*p && ISBLANK(*p) && *p != ';' && *p != ',')
+ while(ISBLANK(*p))
p++;
- if(!*p || *p == ',')
+ if(*p != ';')
break;
p++; /* pass the semicolon */
- if(!*p)
+ if(!*p || ISNEWLINE(*p))
break;
result = getalnum(&p, option, sizeof(option));
if(result) {
@@ -573,7 +575,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
as->expires = maxage + time(NULL);
as->persist = persist;
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
- asi->num++; /* one more entry */
infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
Curl_alpnid2str(dstalpnid));
}
diff --git a/libs/libcurl/src/altsvc.h b/libs/libcurl/src/altsvc.h
index 248e71eef8..578a4fbfb0 100644
--- a/libs/libcurl/src/altsvc.h
+++ b/libs/libcurl/src/altsvc.h
@@ -52,7 +52,6 @@ struct altsvc {
struct altsvcinfo {
char *filename;
struct curl_llist list; /* list of entries */
- size_t num; /* number of alt-svc entries */
long flags; /* the publicly set bitmask */
};
diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c
index b76e66548e..ba5160b253 100644
--- a/libs/libcurl/src/asyn-ares.c
+++ b/libs/libcurl/src/asyn-ares.c
@@ -87,7 +87,8 @@
struct ResolverResults {
int num_pending; /* number of ares_gethostbyname() requests */
- Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
+ struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
+ parts */
int last_status;
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
};
@@ -285,7 +286,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
* return number of sockets it worked on
*/
-static int waitperform(struct connectdata *conn, int timeout_ms)
+static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
{
struct Curl_easy *data = conn->data;
int nfds;
@@ -352,8 +353,8 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
conn->async.os_specific;
CURLcode result = CURLE_OK;
- if(dns)
- *dns = NULL;
+ DEBUGASSERT(dns);
+ *dns = NULL;
waitperform(conn, 0);
@@ -381,19 +382,18 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
}
if(res && !res->num_pending) {
- if(dns) {
- (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
- /* temp_ai ownership is moved to the connection, so we need not free-up
- them */
- res->temp_ai = NULL;
- }
+ (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+ /* temp_ai ownership is moved to the connection, so we need not free-up
+ them */
+ res->temp_ai = NULL;
+
if(!conn->async.dns) {
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
- else if(dns)
+ else
*dns = conn->async.dns;
destroy_async_data(&conn->async);
@@ -408,7 +408,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
* Waits for a resolve to finish. This function should be avoided since using
* this risk getting the multi interface to "hang".
*
- * If 'entry' is non-NULL, make it point to the resolved dns entry
+ * 'entry' MUST be non-NULL.
*
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
@@ -420,10 +420,9 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
struct Curl_easy *data = conn->data;
timediff_t timeout;
struct curltime now = Curl_now();
- struct Curl_dns_entry *temp_entry;
- if(entry)
- *entry = NULL; /* clear on entry */
+ DEBUGASSERT(entry);
+ *entry = NULL; /* clear on entry */
timeout = Curl_timeleft(data, &now, TRUE);
if(timeout < 0) {
@@ -438,9 +437,13 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
while(!result) {
struct timeval *tvp, tv, store;
int itimeout;
- int timeout_ms;
+ timediff_t timeout_ms;
- itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+#if TIMEDIFF_T_MAX > INT_MAX
+ itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
+#else
+ itimeout = (int)timeout;
+#endif
store.tv_sec = itimeout/1000;
store.tv_usec = (itimeout%1000)*1000;
@@ -451,12 +454,12 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
second is left, otherwise just use 1000ms to make sure the progress
callback gets called frequent enough */
if(!tvp->tv_sec)
- timeout_ms = (int)(tvp->tv_usec/1000);
+ timeout_ms = (timediff_t)(tvp->tv_usec/1000);
else
timeout_ms = 1000;
waitperform(conn, timeout_ms);
- result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
+ result = Curl_resolver_is_resolved(conn, entry);
if(result || conn->async.done)
break;
@@ -471,7 +474,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
else if(timediff > timeout)
timeout = -1;
else
- timeout -= (long)timediff;
+ timeout -= timediff;
now = now2; /* for next loop */
}
if(timeout < 0)
@@ -496,9 +499,9 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
/* Connects results to the list */
static void compound_results(struct ResolverResults *res,
- Curl_addrinfo *ai)
+ struct Curl_addrinfo *ai)
{
- Curl_addrinfo *ai_tail;
+ struct Curl_addrinfo *ai_tail;
if(!ai)
return;
ai_tail = ai;
@@ -540,7 +543,7 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
res->num_pending--;
if(CURL_ASYNC_SUCCESS == status) {
- Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+ struct Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
if(ai) {
compound_results(res, ai);
}
@@ -619,10 +622,10 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
* memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*/
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
char *bufp;
struct Curl_easy *data = conn->data;
diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c
index 68dcbb3ecd..a60f4f0661 100644
--- a/libs/libcurl/src/asyn-thread.c
+++ b/libs/libcurl/src/asyn-thread.c
@@ -158,7 +158,7 @@ static bool init_resolve_thread(struct connectdata *conn,
/* Data for synchronization between resolver thread and its parent */
struct thread_sync_data {
- curl_mutex_t * mtx;
+ curl_mutex_t *mtx;
int done;
char *hostname; /* hostname to resolve, Curl_async.hostname
@@ -169,7 +169,7 @@ struct thread_sync_data {
curl_socket_t sock_pair[2]; /* socket pair */
#endif
int sock_error;
- Curl_addrinfo *res;
+ struct Curl_addrinfo *res;
#ifdef HAVE_GETADDRINFO
struct addrinfo hints;
#endif
@@ -179,7 +179,7 @@ struct thread_sync_data {
struct thread_data {
curl_thread_t thread_hnd;
unsigned int poll_interval;
- time_t interval_end;
+ timediff_t interval_end;
struct thread_sync_data tsd;
};
@@ -190,7 +190,7 @@ static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
/* Destroy resolver thread synchronization data */
static
-void destroy_thread_sync_data(struct thread_sync_data * tsd)
+void destroy_thread_sync_data(struct thread_sync_data *tsd)
{
if(tsd->mtx) {
Curl_mutex_destroy(tsd->mtx);
@@ -216,7 +216,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
/* Initialize resolver thread synchronization data */
static
-int init_thread_sync_data(struct thread_data * td,
+int init_thread_sync_data(struct thread_data *td,
const char *hostname,
int port,
const struct addrinfo *hints)
@@ -494,11 +494,14 @@ static CURLcode resolver_error(struct connectdata *conn)
const char *host_or_proxy;
CURLcode result;
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy) {
host_or_proxy = "proxy";
result = CURLE_COULDNT_RESOLVE_PROXY;
}
- else {
+ else
+#endif
+ {
host_or_proxy = "host";
result = CURLE_COULDNT_RESOLVE_HOST;
}
@@ -509,6 +512,9 @@ static CURLcode resolver_error(struct connectdata *conn)
return result;
}
+/*
+ * 'entry' may be NULL and then no data is returned
+ */
static CURLcode thread_wait_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry,
bool report)
@@ -593,6 +599,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
int done = 0;
+ DEBUGASSERT(entry);
*entry = NULL;
if(!td) {
@@ -618,8 +625,8 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
else {
/* poll for name lookup done with exponential backoff up to 250ms */
/* should be fine even if this converts to 32 bit */
- time_t elapsed = (time_t)Curl_timediff(Curl_now(),
- data->progress.t_startsingle);
+ timediff_t elapsed = Curl_timediff(Curl_now(),
+ data->progress.t_startsingle);
if(elapsed < 0)
elapsed = 0;
@@ -644,7 +651,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
curl_socket_t *socks)
{
int ret_val = 0;
- time_t milli;
+ timediff_t milli;
timediff_t ms;
struct Curl_easy *data = conn->data;
struct resdata *reslv = (struct resdata *)data->state.resolver;
@@ -668,7 +675,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
if(ms < 3)
milli = 0;
else if(ms <= 50)
- milli = (time_t)ms/3;
+ milli = ms/3;
else if(ms <= 250)
milli = 50;
else
@@ -686,10 +693,10 @@ int Curl_resolver_getsock(struct connectdata *conn,
/*
* Curl_getaddrinfo() - for platforms without getaddrinfo
*/
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
struct Curl_easy *data = conn->data;
struct resdata *reslv = (struct resdata *)data->state.resolver;
@@ -714,10 +721,10 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
/*
* Curl_resolver_getaddrinfo() - for getaddrinfo
*/
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
struct addrinfo hints;
int pf = PF_INET;
diff --git a/libs/libcurl/src/asyn.h b/libs/libcurl/src/asyn.h
index 081c3fef03..be2796cf0f 100644
--- a/libs/libcurl/src/asyn.h
+++ b/libs/libcurl/src/asyn.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -153,10 +153,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
* Each resolver backend must of course make sure to return data in the
* correct format to comply with this.
*/
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp);
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp);
#ifndef CURLRES_ASYNCH
/* convert these functions if an asynch resolver isn't used */
diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl
index b074f2744f..97b8f9e1d2 100644
--- a/libs/libcurl/src/checksrc.pl
+++ b/libs/libcurl/src/checksrc.pl
@@ -31,14 +31,14 @@ my $warnings = 0;
my $swarnings = 0;
my $errors = 0;
my $serrors = 0;
-my $suppressed; # whitelisted problems
+my $suppressed; # skipped problems
my $file;
my $dir=".";
my $wlist="";
my @alist;
my $windows_os = $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys';
my $verbose;
-my %whitelist;
+my %skiplist;
my %ignore;
my %ignore_set;
@@ -81,14 +81,15 @@ my %warnings = (
'SIZEOFNOPAREN' => 'use of sizeof without parentheses',
'SNPRINTF' => 'use of snprintf',
'ONELINECONDITION' => 'conditional block on the same line as the if()',
+ 'TYPEDEFSTRUCT' => 'typedefed struct',
);
-sub readwhitelist {
- open(W, "<$dir/checksrc.whitelist") or return;
+sub readskiplist {
+ open(W, "<$dir/checksrc.skip") or return;
my @all=<W>;
for(@all) {
$windows_os ? $_ =~ s/\r?\n$// : chomp;
- $whitelist{$_}=1;
+ $skiplist{$_}=1;
}
close(W);
}
@@ -116,10 +117,19 @@ sub readlocalfile {
}
$warnings{$1} = $warnings_extended{$1};
}
+ elsif (/^\s*disable ([A-Z]+)$/) {
+ if(!defined($warnings{$1})) {
+ print STDERR "invalid warning specified in .checksrc: \"$1\"\n";
+ next;
+ }
+ # Accept-list
+ push @alist, $1;
+ }
else {
die "Invalid format in $dir/.checksrc on line $i\n";
}
}
+ close($rcfile);
}
sub checkwarn {
@@ -132,8 +142,8 @@ sub checkwarn {
# print STDERR "Dev! there's no description for $name!\n";
#}
- # checksrc.whitelist
- if($whitelist{$line}) {
+ # checksrc.skip
+ if($skiplist{$line}) {
$nowarn = 1;
}
# !checksrc! controlled
@@ -218,7 +228,7 @@ if(!$file) {
print " -A[rule] Accept this violation, can be used multiple times\n";
print " -D[DIR] Directory to prepend file names\n";
print " -h Show help output\n";
- print " -W[file] Whitelist the given file - ignore all its flaws\n";
+ print " -W[file] Skip the given file - ignore all its flaws\n";
print " -i<n> Indent spaces. Default: 2\n";
print " -m<n> Maximum line length. Default: 79\n";
print "\nDetects and warns for these problems:\n";
@@ -228,7 +238,7 @@ if(!$file) {
exit;
}
-readwhitelist();
+readskiplist();
readlocalfile();
do {
@@ -639,10 +649,10 @@ sub scanfile {
}
# check for 'char * name'
- if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) {
- checkwarn("ASTERISKNOSPACE",
+ if(($l =~ /(^.*(char|int|long|void|CURL|CURLM|CURLMsg|[cC]url_[A-Za-z_]+|struct [a-zA-Z_]+) *(\*+)) (\w+)/) && ($4 !~ /^(const|volatile)$/)) {
+ checkwarn("ASTERISKSPACE",
$line, length($1), $file, $ol,
- "no space after declarative asterisk");
+ "space after declarative asterisk");
}
# check for 'char*'
if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) {
@@ -697,6 +707,13 @@ sub scanfile {
"no space after semicolon");
}
+ # typedef struct ... {
+ if($nostr =~ /^(.*)typedef struct.*{/) {
+ checkwarn("TYPEDEFSTRUCT",
+ $line, length($1)+1, $file, $ol,
+ "typedef'ed struct");
+ }
+
# check for more than one consecutive space before open brace or
# question mark. Skip lines containing strings since they make it hard
# due to artificially getting multiple spaces
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index 7063114429..76ee6b1a77 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.h
@@ -246,10 +246,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. */
/* #define HAVE_STRCASECMP 1 */
@@ -717,9 +713,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
@@ -731,6 +724,7 @@ Vista
/* Replicating logic present in afunix.h of newer Windows 10 SDK versions */
# define UNIX_PATH_MAX 108
# include <ws2tcpip.h>
+ /* !checksrc! disable TYPEDEFSTRUCT 1 */
typedef struct sockaddr_un {
ADDRESS_FAMILY sun_family;
char sun_path[UNIX_PATH_MAX];
diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c
index cbd3bb1bb3..d21a00cfdd 100644
--- a/libs/libcurl/src/conncache.c
+++ b/libs/libcurl/src/conncache.c
@@ -49,53 +49,51 @@ static void conn_llist_dtor(void *user, void *element)
conn->bundle = NULL;
}
-static CURLcode bundle_create(struct Curl_easy *data,
- struct connectbundle **cb_ptr)
+static CURLcode bundle_create(struct connectbundle **bundlep)
{
- (void)data;
- DEBUGASSERT(*cb_ptr == NULL);
- *cb_ptr = malloc(sizeof(struct connectbundle));
- if(!*cb_ptr)
+ DEBUGASSERT(*bundlep == NULL);
+ *bundlep = malloc(sizeof(struct connectbundle));
+ if(!*bundlep)
return CURLE_OUT_OF_MEMORY;
- (*cb_ptr)->num_connections = 0;
- (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+ (*bundlep)->num_connections = 0;
+ (*bundlep)->multiuse = BUNDLE_UNKNOWN;
- Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
+ Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor);
return CURLE_OK;
}
-static void bundle_destroy(struct connectbundle *cb_ptr)
+static void bundle_destroy(struct connectbundle *bundle)
{
- if(!cb_ptr)
+ if(!bundle)
return;
- Curl_llist_destroy(&cb_ptr->conn_list, NULL);
+ Curl_llist_destroy(&bundle->conn_list, NULL);
- free(cb_ptr);
+ free(bundle);
}
/* Add a connection to a bundle */
-static void bundle_add_conn(struct connectbundle *cb_ptr,
+static void bundle_add_conn(struct connectbundle *bundle,
struct connectdata *conn)
{
- Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
+ Curl_llist_insert_next(&bundle->conn_list, bundle->conn_list.tail, conn,
&conn->bundle_node);
- conn->bundle = cb_ptr;
- cb_ptr->num_connections++;
+ conn->bundle = bundle;
+ bundle->num_connections++;
}
/* Remove a connection from a bundle */
-static int bundle_remove_conn(struct connectbundle *cb_ptr,
+static int bundle_remove_conn(struct connectbundle *bundle,
struct connectdata *conn)
{
struct curl_llist_element *curr;
- curr = cb_ptr->conn_list.head;
+ curr = bundle->conn_list.head;
while(curr) {
if(curr->ptr == conn) {
- Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
- cb_ptr->num_connections--;
+ Curl_llist_remove(&bundle->conn_list, curr, NULL);
+ bundle->num_connections--;
conn->bundle = NULL;
return 1; /* we removed a handle */
}
@@ -145,12 +143,15 @@ static void hashkey(struct connectdata *conn, char *buf,
const char *hostname;
long port = conn->remote_port;
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
hostname = conn->http_proxy.host.name;
port = conn->port;
}
- else if(conn->bits.conn_to_host)
- hostname = conn->conn_to_host.name;
+ else
+#endif
+ if(conn->bits.conn_to_host)
+ hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;
@@ -162,20 +163,15 @@ static void hashkey(struct connectdata *conn, char *buf,
msnprintf(buf, len, "%ld%s", port, hostname);
}
-void Curl_conncache_unlock(struct Curl_easy *data)
-{
- CONN_UNLOCK(data);
-}
-
/* Returns number of connections currently held in the connection cache.
Locks/unlocks the cache itself!
*/
size_t Curl_conncache_size(struct Curl_easy *data)
{
size_t num;
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
num = data->state.conn_cache->num_conn;
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return num;
}
@@ -188,7 +184,7 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
const char **hostp)
{
struct connectbundle *bundle = NULL;
- CONN_LOCK(conn->data);
+ CONNCACHE_LOCK(conn->data);
if(connc) {
char key[HASHKEY_SIZE];
hashkey(conn, key, sizeof(key), hostp);
@@ -235,8 +231,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct connectbundle *bundle;
- struct connectbundle *new_bundle = NULL;
+ struct connectbundle *bundle = NULL;
struct Curl_easy *data = conn->data;
/* *find_bundle() locks the connection cache */
@@ -245,20 +240,19 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
int rc;
char key[HASHKEY_SIZE];
- result = bundle_create(data, &new_bundle);
+ result = bundle_create(&bundle);
if(result) {
goto unlock;
}
hashkey(conn, key, sizeof(key), NULL);
- rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+ rc = conncache_add_bundle(data->state.conn_cache, key, bundle);
if(!rc) {
- bundle_destroy(new_bundle);
+ bundle_destroy(bundle);
result = CURLE_OUT_OF_MEMORY;
goto unlock;
}
- bundle = new_bundle;
}
bundle_add_conn(bundle, conn);
@@ -270,15 +264,17 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
conn->connection_id, connc->num_conn));
unlock:
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return result;
}
/*
- * Removes the connectdata object from the connection cache *and* clears the
- * ->data pointer association. Pass TRUE/FALSE in the 'lock' argument
- * depending on if the parent function already holds the lock or not.
+ * Removes the connectdata object from the connection cache, but does *not*
+ * clear the conn->data association. The transfer still owns this connection.
+ *
+ * Pass TRUE/FALSE in the 'lock' argument depending on if the parent function
+ * already holds the lock or not.
*/
void Curl_conncache_remove_conn(struct Curl_easy *data,
struct connectdata *conn, bool lock)
@@ -290,7 +286,7 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
due to a failed connection attempt, before being added to a bundle */
if(bundle) {
if(lock) {
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
}
bundle_remove_conn(bundle, conn);
if(bundle->num_connections == 0)
@@ -301,9 +297,8 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
DEBUGF(infof(data, "The cache now contains %zu members\n",
connc->num_conn));
}
- conn->data = NULL; /* clear the association */
if(lock) {
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
}
}
}
@@ -332,7 +327,7 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
if(!connc)
return FALSE;
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
Curl_hash_start_iterate(&connc->hash, &iter);
he = Curl_hash_next_element(&iter);
@@ -350,12 +345,12 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
curr = curr->next;
if(1 == func(conn, param)) {
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return TRUE;
}
}
}
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return FALSE;
}
@@ -494,7 +489,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
now = Curl_now();
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
Curl_hash_start_iterate(&connc->hash, &iter);
he = Curl_hash_next_element(&iter);
@@ -531,7 +526,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
connc->num_conn));
conn_candidate->data = data; /* associate! */
}
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return conn_candidate;
}
@@ -539,6 +534,11 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
void Curl_conncache_close_all_connections(struct conncache *connc)
{
struct connectdata *conn;
+ char buffer[READBUFFER_MIN + 1];
+ if(!connc->closure_handle)
+ return;
+ connc->closure_handle->state.buffer = buffer;
+ connc->closure_handle->set.buffer_size = READBUFFER_MIN;
conn = conncache_find_first_connection(connc);
while(conn) {
@@ -548,12 +548,14 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
sigpipe_ignore(conn->data, &pipe_st);
/* This will remove the connection from the cache */
connclose(conn, "kill all");
+ Curl_conncache_remove_conn(conn->data, conn, TRUE);
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
sigpipe_restore(&pipe_st);
conn = conncache_find_first_connection(connc);
}
+ connc->closure_handle->state.buffer = NULL;
if(connc->closure_handle) {
SIGPIPE_VARIABLE(pipe_st);
sigpipe_ignore(connc->closure_handle, &pipe_st);
diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h
index e3e4c9c282..3dda21cdc6 100644
--- a/libs/libcurl/src/conncache.h
+++ b/libs/libcurl/src/conncache.h
@@ -45,21 +45,21 @@ struct conncache {
#ifdef CURLDEBUG
/* the debug versions of these macros make extra certain that the lock is
never doubly locked or unlocked */
-#define CONN_LOCK(x) if((x)->share) { \
+#define CONNCACHE_LOCK(x) if((x)->share) { \
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \
DEBUGASSERT(!(x)->state.conncache_lock); \
(x)->state.conncache_lock = TRUE; \
}
-#define CONN_UNLOCK(x) if((x)->share) { \
+#define CONNCACHE_UNLOCK(x) if((x)->share) { \
DEBUGASSERT((x)->state.conncache_lock); \
(x)->state.conncache_lock = FALSE; \
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \
}
#else
-#define CONN_LOCK(x) if((x)->share) \
+#define CONNCACHE_LOCK(x) if((x)->share) \
Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
-#define CONN_UNLOCK(x) if((x)->share) \
+#define CONNCACHE_UNLOCK(x) if((x)->share) \
Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
#endif
@@ -77,7 +77,6 @@ void Curl_conncache_destroy(struct conncache *connc);
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
struct conncache *connc,
const char **hostp);
-void Curl_conncache_unlock(struct Curl_easy *data);
/* returns number of connections currently held in the connection cache */
size_t Curl_conncache_size(struct Curl_easy *data);
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index 421f904159..29293f0874 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -166,7 +166,7 @@ tcpkeepalive(struct Curl_easy *data,
static CURLcode
singleipconnect(struct connectdata *conn,
- const Curl_addrinfo *ai, /* start connecting to this */
+ const struct Curl_addrinfo *ai, /* start connecting to this */
int tempindex); /* 0 or 1 among the temp ones */
/*
@@ -558,11 +558,11 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
/* update tempaddr[tempindex] (to the next entry), makes sure to stick
to the correct family */
-static Curl_addrinfo *ainext(struct connectdata *conn,
- int tempindex,
- bool next) /* use current or next entry */
+static struct Curl_addrinfo *ainext(struct connectdata *conn,
+ int tempindex,
+ bool next) /* use next entry? */
{
- Curl_addrinfo *ai = conn->tempaddr[tempindex];
+ struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
if(ai && next)
ai = ai->ai_next;
while(ai && (ai->ai_family != conn->tempfamily[tempindex]))
@@ -571,7 +571,7 @@ static Curl_addrinfo *ainext(struct connectdata *conn,
return ai;
}
-/* Used within the multi interface. Try next IP address, return TRUE if no
+/* Used within the multi interface. Try next IP address, returns error if no
more address exists or error */
static CURLcode trynextip(struct connectdata *conn,
int sockindex,
@@ -587,7 +587,7 @@ static CURLcode trynextip(struct connectdata *conn,
conn->tempsock[tempindex] = CURL_SOCKET_BAD;
if(sockindex == FIRSTSOCKET) {
- Curl_addrinfo *ai = conn->tempaddr[tempindex];
+ struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
while(ai) {
if(ai) {
@@ -747,8 +747,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
{
CURLcode result = CURLE_OK;
- if(conn->bits.socksproxy) {
#ifndef CURL_DISABLE_PROXY
+ if(conn->bits.socksproxy) {
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
@@ -781,11 +781,12 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
failf(conn->data, "unknown proxytype option given");
result = CURLE_COULDNT_CONNECT;
} /* switch proxytype */
-#else
- (void)sockindex;
-#endif /* CURL_DISABLE_PROXY */
}
else
+#else
+ (void)conn;
+ (void)sockindex;
+#endif /* CURL_DISABLE_PROXY */
*done = TRUE; /* no SOCKS proxy, so consider us connected */
return result;
@@ -822,8 +823,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
timediff_t allow;
int error = 0;
struct curltime now;
- int rc;
- int i;
+ int rc = 0;
+ unsigned int i;
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
@@ -858,49 +859,50 @@ CURLcode Curl_is_connected(struct connectdata *conn,
const int other = i ^ 1;
if(conn->tempsock[i] == CURL_SOCKET_BAD)
continue;
-
+ error = 0;
#ifdef ENABLE_QUIC
if(conn->transport == TRNSPRT_QUIC) {
result = Curl_quic_is_connected(conn, i, connected);
- if(result) {
- error = SOCKERRNO;
- goto error;
- }
- if(*connected) {
+ if(!result && *connected) {
/* use this socket from now on */
conn->sock[sockindex] = conn->tempsock[i];
conn->ip_addr = conn->tempaddr[i];
conn->tempsock[i] = CURL_SOCKET_BAD;
post_SOCKS(conn, sockindex, connected);
connkeep(conn, "HTTP/3 default");
+ return CURLE_OK;
}
- return result;
+ if(result)
+ error = SOCKERRNO;
}
+ else
#endif
-
+ {
#ifdef mpeix
- /* Call this function once now, and ignore the results. We do this to
- "clear" the error state on the socket so that we can later read it
- reliably. This is reported necessary on the MPE/iX operating system. */
- (void)verifyconnect(conn->tempsock[i], NULL);
+ /* Call this function once now, and ignore the results. We do this to
+ "clear" the error state on the socket so that we can later read it
+ reliably. This is reported necessary on the MPE/iX operating
+ system. */
+ (void)verifyconnect(conn->tempsock[i], NULL);
#endif
- /* check socket for connect */
- rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
+ /* check socket for connect */
+ rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
+ }
if(rc == 0) { /* no connection yet */
- error = 0;
- if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
+ if(Curl_timediff(now, conn->connecttime) >=
+ conn->timeoutms_per_addr[i]) {
infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
- "ms connect time, move on!\n", conn->timeoutms_per_addr);
+ "ms connect time, move on!\n", conn->timeoutms_per_addr[i]);
error = ETIMEDOUT;
}
/* should we try another protocol family? */
- if(i == 0 && !conn->parallel_connect &&
+ if(i == 0 && !conn->bits.parallel_connect &&
(Curl_timediff(now, conn->connecttime) >=
data->set.happy_eyeballs_timeout)) {
- conn->parallel_connect = TRUE; /* starting now */
+ conn->bits.parallel_connect = TRUE; /* starting now */
trynextip(conn, sockindex, 1);
}
}
@@ -937,9 +939,6 @@ CURLcode Curl_is_connected(struct connectdata *conn,
else if(rc & CURL_CSELECT_ERR)
(void)verifyconnect(conn->tempsock[i], &error);
-#ifdef ENABLE_QUIC
- error:
-#endif
/*
* The connection failed here, we should attempt to connect to the "next
* address" for the given host. But first remember the latest error.
@@ -952,13 +951,14 @@ CURLcode Curl_is_connected(struct connectdata *conn,
#ifndef CURL_DISABLE_VERBOSE_STRINGS
char ipaddress[MAX_IPADR_LEN];
char buffer[STRERROR_LEN];
- Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
-#endif
+ Curl_printable_address(conn->tempaddr[i], ipaddress,
+ sizeof(ipaddress));
infof(data, "connect to %s port %ld failed: %s\n",
ipaddress, conn->port,
Curl_strerror(error, buffer, sizeof(buffer)));
+#endif
- conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
+ conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ?
allow : allow / 2;
ainext(conn, i, TRUE);
status = trynextip(conn, sockindex, i);
@@ -970,25 +970,28 @@ CURLcode Curl_is_connected(struct connectdata *conn,
}
}
- if(result) {
+ if(result &&
+ (conn->tempsock[0] == CURL_SOCKET_BAD) &&
+ (conn->tempsock[1] == CURL_SOCKET_BAD)) {
/* no more addresses to try */
const char *hostname;
char buffer[STRERROR_LEN];
- /* if the first address family runs out of addresses to try before
- the happy eyeball timeout, go ahead and try the next family now */
- {
- result = trynextip(conn, sockindex, 1);
- if(!result)
- return result;
- }
+ /* if the first address family runs out of addresses to try before the
+ happy eyeball timeout, go ahead and try the next family now */
+ result = trynextip(conn, sockindex, 1);
+ if(!result)
+ return result;
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy)
hostname = conn->socks_proxy.host.name;
else if(conn->bits.httpproxy)
hostname = conn->http_proxy.host.name;
- else if(conn->bits.conn_to_host)
- hostname = conn->conn_to_host.name;
+ else
+#endif
+ if(conn->bits.conn_to_host)
+ hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;
@@ -996,6 +999,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
hostname, conn->port,
Curl_strerror(error, buffer, sizeof(buffer)));
+ Curl_quic_disconnect(conn, 0);
+ Curl_quic_disconnect(conn, 1);
+
#ifdef WSAETIMEDOUT
if(WSAETIMEDOUT == data->state.os_errno)
result = CURLE_OPERATION_TIMEDOUT;
@@ -1004,6 +1010,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
result = CURLE_OPERATION_TIMEDOUT;
#endif
}
+ else
+ result = CURLE_OK; /* still trying */
return result;
}
@@ -1105,7 +1113,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
* having connected.
*/
static CURLcode singleipconnect(struct connectdata *conn,
- const Curl_addrinfo *ai,
+ const struct Curl_addrinfo *ai,
int tempindex)
{
struct Curl_sockaddr_ex addr;
@@ -1195,8 +1203,10 @@ static CURLcode singleipconnect(struct connectdata *conn,
(void)curlx_nonblock(sockfd, TRUE);
conn->connecttime = Curl_now();
- if(conn->num_addr > 1)
- Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME);
+ if(conn->num_addr > 1) {
+ Curl_expire(data, conn->timeoutms_per_addr[0], EXPIRE_DNS_PER_NAME);
+ Curl_expire(data, conn->timeoutms_per_addr[1], EXPIRE_DNS_PER_NAME2);
+ }
/* Connect TCP and QUIC sockets */
if(!isconnected && (conn->transport != TRNSPRT_UDP)) {
@@ -1319,8 +1329,10 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
conn->tempsock[0] = conn->tempsock[1] = CURL_SOCKET_BAD;
/* Max time for the next connection attempt */
- conn->timeoutms_per_addr =
+ conn->timeoutms_per_addr[0] =
conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
+ conn->timeoutms_per_addr[1] =
+ conn->tempaddr[1]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
conn->tempfamily[0] = conn->tempaddr[0]?
conn->tempaddr[0]->ai_family:0;
@@ -1443,11 +1455,11 @@ int Curl_closesocket(struct connectdata *conn,
curl_socket_t sock)
{
if(conn && conn->fclosesocket) {
- if((sock == conn->sock[SECONDARYSOCKET]) && conn->sock_accepted)
+ if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted)
/* if this socket matches the second socket, and that was created with
accept, then we MUST NOT call the callback but clear the accepted
status */
- conn->sock_accepted = FALSE;
+ conn->bits.sock_accepted = FALSE;
else {
int rc;
Curl_multi_closed(conn->data, sock);
@@ -1477,7 +1489,7 @@ int Curl_closesocket(struct connectdata *conn,
*
*/
CURLcode Curl_socket(struct connectdata *conn,
- const Curl_addrinfo *ai,
+ const struct Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd)
{
@@ -1559,6 +1571,7 @@ void Curl_conncontrol(struct connectdata *conn,
/* close if a connection, or a stream that isn't multiplexed */
bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
+ DEBUGASSERT(conn);
if((ctrl == CONNCTRL_STREAM) &&
(conn->handler->flags & PROTOPT_STREAM))
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
@@ -1574,6 +1587,7 @@ void Curl_conncontrol(struct connectdata *conn,
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
{
int readable;
+ DEBUGASSERT(conn);
if(Curl_ssl_data_pending(conn, sockindex) ||
Curl_recv_has_postponed_data(conn, sockindex))
diff --git a/libs/libcurl/src/connect.h b/libs/libcurl/src/connect.h
index b23085a98a..6fd9ea8789 100644
--- a/libs/libcurl/src/connect.h
+++ b/libs/libcurl/src/connect.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -105,7 +105,7 @@ struct Curl_sockaddr_ex {
*
*/
CURLcode Curl_socket(struct connectdata *conn,
- const Curl_addrinfo *ai,
+ const struct Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c
index 6d47537883..e2e68a1166 100644
--- a/libs/libcurl/src/content_encoding.c
+++ b/libs/libcurl/src/content_encoding.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -81,11 +81,11 @@ typedef enum {
} zlibInitState;
/* Writer parameters. */
-typedef struct {
+struct zlib_params {
zlibInitState zlib_init; /* zlib init state */
uInt trailerlen; /* Remaining trailer byte count. */
z_stream z; /* State structure for zlib. */
-} zlib_params;
+};
static voidpf
@@ -133,7 +133,8 @@ exit_zlib(struct connectdata *conn,
return result;
}
-static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
+static CURLcode process_trailer(struct connectdata *conn,
+ struct zlib_params *zp)
{
z_stream *z = &zp->z;
CURLcode result = CURLE_OK;
@@ -157,9 +158,10 @@ static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
}
static CURLcode inflate_stream(struct connectdata *conn,
- contenc_writer *writer, zlibInitState started)
+ struct contenc_writer *writer,
+ zlibInitState started)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
uInt nread = z->avail_in;
Bytef *orig_in = z->next_in;
@@ -259,9 +261,9 @@ static CURLcode inflate_stream(struct connectdata *conn,
/* Deflate handler. */
static CURLcode deflate_init_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
if(!writer->downstream)
@@ -278,10 +280,10 @@ static CURLcode deflate_init_writer(struct connectdata *conn,
}
static CURLcode deflate_unencode_write(struct connectdata *conn,
- contenc_writer *writer,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
/* Set the compressed input when this function is called */
@@ -296,29 +298,29 @@ static CURLcode deflate_unencode_write(struct connectdata *conn,
}
static void deflate_close_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
}
-static const content_encoding deflate_encoding = {
+static const struct content_encoding deflate_encoding = {
"deflate",
NULL,
deflate_init_writer,
deflate_unencode_write,
deflate_close_writer,
- sizeof(zlib_params)
+ sizeof(struct zlib_params)
};
/* Gzip handler. */
static CURLcode gzip_init_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
if(!writer->downstream)
@@ -432,10 +434,10 @@ static enum {
#endif
static CURLcode gzip_unencode_write(struct connectdata *conn,
- contenc_writer *writer,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
if(zp->zlib_init == ZLIB_INIT_GZIP) {
@@ -560,33 +562,31 @@ static CURLcode gzip_unencode_write(struct connectdata *conn,
}
static void gzip_close_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
- zlib_params *zp = (zlib_params *) &writer->params;
+ struct zlib_params *zp = (struct zlib_params *) &writer->params;
z_stream *z = &zp->z; /* zlib state structure */
exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
}
-static const content_encoding gzip_encoding = {
+static const struct content_encoding gzip_encoding = {
"gzip",
"x-gzip",
gzip_init_writer,
gzip_unencode_write,
gzip_close_writer,
- sizeof(zlib_params)
+ sizeof(struct zlib_params)
};
#endif /* HAVE_LIBZ */
#ifdef HAVE_BROTLI
-
/* Writer parameters. */
-typedef struct {
+struct brotli_params {
BrotliDecoderState *br; /* State structure for brotli. */
-} brotli_params;
-
+};
static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
{
@@ -627,10 +627,9 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
}
static CURLcode brotli_init_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
- brotli_params *bp = (brotli_params *) &writer->params;
-
+ struct brotli_params *bp = (struct brotli_params *) &writer->params;
(void) conn;
if(!writer->downstream)
@@ -641,10 +640,10 @@ static CURLcode brotli_init_writer(struct connectdata *conn,
}
static CURLcode brotli_unencode_write(struct connectdata *conn,
- contenc_writer *writer,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
- brotli_params *bp = (brotli_params *) &writer->params;
+ struct brotli_params *bp = (struct brotli_params *) &writer->params;
const uint8_t *src = (const uint8_t *) buf;
char *decomp;
uint8_t *dst;
@@ -689,10 +688,9 @@ static CURLcode brotli_unencode_write(struct connectdata *conn,
}
static void brotli_close_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
- brotli_params *bp = (brotli_params *) &writer->params;
-
+ struct brotli_params *bp = (struct brotli_params *) &writer->params;
(void) conn;
if(bp->br) {
@@ -701,40 +699,40 @@ static void brotli_close_writer(struct connectdata *conn,
}
}
-static const content_encoding brotli_encoding = {
+static const struct content_encoding brotli_encoding = {
"br",
NULL,
brotli_init_writer,
brotli_unencode_write,
brotli_close_writer,
- sizeof(brotli_params)
+ sizeof(struct brotli_params)
};
#endif
/* Identity handler. */
static CURLcode identity_init_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
(void) conn;
return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
}
static CURLcode identity_unencode_write(struct connectdata *conn,
- contenc_writer *writer,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
return Curl_unencode_write(conn, writer->downstream, buf, nbytes);
}
static void identity_close_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
(void) conn;
(void) writer;
}
-static const content_encoding identity_encoding = {
+static const struct content_encoding identity_encoding = {
"identity",
"none",
identity_init_writer,
@@ -745,7 +743,7 @@ static const content_encoding identity_encoding = {
/* supported content encodings table. */
-static const content_encoding * const encodings[] = {
+static const struct content_encoding * const encodings[] = {
&identity_encoding,
#ifdef HAVE_LIBZ
&deflate_encoding,
@@ -762,8 +760,8 @@ static const content_encoding * const encodings[] = {
char *Curl_all_content_encodings(void)
{
size_t len = 0;
- const content_encoding * const *cep;
- const content_encoding *ce;
+ const struct content_encoding * const *cep;
+ const struct content_encoding *ce;
char *ace;
for(cep = encodings; *cep; cep++) {
@@ -796,14 +794,14 @@ char *Curl_all_content_encodings(void)
/* Real client writer: no downstream. */
static CURLcode client_init_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
(void) conn;
return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK;
}
static CURLcode client_unencode_write(struct connectdata *conn,
- contenc_writer *writer,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
struct Curl_easy *data = conn->data;
@@ -818,13 +816,13 @@ static CURLcode client_unencode_write(struct connectdata *conn,
}
static void client_close_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
(void) conn;
(void) writer;
}
-static const content_encoding client_encoding = {
+static const struct content_encoding client_encoding = {
NULL,
NULL,
client_init_writer,
@@ -836,14 +834,14 @@ static const content_encoding client_encoding = {
/* Deferred error dummy writer. */
static CURLcode error_init_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
(void) conn;
return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
}
static CURLcode error_unencode_write(struct connectdata *conn,
- contenc_writer *writer,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
char *all = Curl_all_content_encodings();
@@ -861,13 +859,13 @@ static CURLcode error_unencode_write(struct connectdata *conn,
}
static void error_close_writer(struct connectdata *conn,
- contenc_writer *writer)
+ struct contenc_writer *writer)
{
(void) conn;
(void) writer;
}
-static const content_encoding error_encoding = {
+static const struct content_encoding error_encoding = {
NULL,
NULL,
error_init_writer,
@@ -877,12 +875,13 @@ static const content_encoding error_encoding = {
};
/* Create an unencoding writer stage using the given handler. */
-static contenc_writer *new_unencoding_writer(struct connectdata *conn,
- const content_encoding *handler,
- contenc_writer *downstream)
+static struct contenc_writer *
+new_unencoding_writer(struct connectdata *conn,
+ const struct content_encoding *handler,
+ struct contenc_writer *downstream)
{
- size_t sz = offsetof(contenc_writer, params) + handler->paramsize;
- contenc_writer *writer = (contenc_writer *) calloc(1, sz);
+ size_t sz = offsetof(struct contenc_writer, params) + handler->paramsize;
+ struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz);
if(writer) {
writer->handler = handler;
@@ -897,7 +896,8 @@ static contenc_writer *new_unencoding_writer(struct connectdata *conn,
}
/* Write data using an unencoding writer stack. */
-CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+CURLcode Curl_unencode_write(struct connectdata *conn,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
if(!nbytes)
@@ -910,7 +910,7 @@ void Curl_unencode_cleanup(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
struct SingleRequest *k = &data->req;
- contenc_writer *writer = k->writer_stack;
+ struct contenc_writer *writer = k->writer_stack;
while(writer) {
k->writer_stack = writer->downstream;
@@ -921,12 +921,13 @@ void Curl_unencode_cleanup(struct connectdata *conn)
}
/* Find the content encoding by name. */
-static const content_encoding *find_encoding(const char *name, size_t len)
+static const struct content_encoding *find_encoding(const char *name,
+ size_t len)
{
- const content_encoding * const *cep;
+ const struct content_encoding * const *cep;
for(cep = encodings; *cep; cep++) {
- const content_encoding *ce = *cep;
+ const struct content_encoding *ce = *cep;
if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
(ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
return ce;
@@ -962,8 +963,8 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
Curl_httpchunk_init(conn); /* init our chunky engine. */
}
else if(namelen) {
- const content_encoding *encoding = find_encoding(name, namelen);
- contenc_writer *writer;
+ const struct content_encoding *encoding = find_encoding(name, namelen);
+ struct contenc_writer *writer;
if(!k->writer_stack) {
k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL);
@@ -997,7 +998,8 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
return CURLE_NOT_BUILT_IN;
}
-CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+CURLcode Curl_unencode_write(struct connectdata *conn,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
(void) conn;
diff --git a/libs/libcurl/src/content_encoding.h b/libs/libcurl/src/content_encoding.h
index 4cd52be622..bdd3f1c8c6 100644
--- a/libs/libcurl/src/content_encoding.h
+++ b/libs/libcurl/src/content_encoding.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -23,31 +23,31 @@
***************************************************************************/
#include "curl_setup.h"
-/* Decoding writer. */
-typedef struct contenc_writer_s contenc_writer;
-typedef struct content_encoding_s content_encoding;
-
-struct contenc_writer_s {
- const content_encoding *handler; /* Encoding handler. */
- contenc_writer *downstream; /* Downstream writer. */
+struct contenc_writer {
+ const struct content_encoding *handler; /* Encoding handler. */
+ struct contenc_writer *downstream; /* Downstream writer. */
void *params; /* Encoding-specific storage (variable length). */
};
/* Content encoding writer. */
-struct content_encoding_s {
+struct content_encoding {
const char *name; /* Encoding name. */
const char *alias; /* Encoding name alias. */
- CURLcode (*init_writer)(struct connectdata *conn, contenc_writer *writer);
- CURLcode (*unencode_write)(struct connectdata *conn, contenc_writer *writer,
+ CURLcode (*init_writer)(struct connectdata *conn,
+ struct contenc_writer *writer);
+ CURLcode (*unencode_write)(struct connectdata *conn,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes);
- void (*close_writer)(struct connectdata *conn, contenc_writer *writer);
+ void (*close_writer)(struct connectdata *conn,
+ struct contenc_writer *writer);
size_t paramsize;
};
CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
const char *enclist, int maybechunked);
-CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+CURLcode Curl_unencode_write(struct connectdata *conn,
+ struct contenc_writer *writer,
const char *buf, size_t nbytes);
void Curl_unencode_cleanup(struct connectdata *conn);
char *Curl_all_content_encodings(void);
diff --git a/libs/libcurl/src/curl_addrinfo.c b/libs/libcurl/src/curl_addrinfo.c
index b2dd83423d..947d0d3756 100644
--- a/libs/libcurl/src/curl_addrinfo.c
+++ b/libs/libcurl/src/curl_addrinfo.c
@@ -78,16 +78,13 @@
#endif
void
-Curl_freeaddrinfo(Curl_addrinfo *cahead)
+Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
{
- Curl_addrinfo *vqualifier canext;
- Curl_addrinfo *ca;
+ struct Curl_addrinfo *vqualifier canext;
+ struct Curl_addrinfo *ca;
- for(ca = cahead; ca != NULL; ca = canext) {
- free(ca->ai_addr);
- free(ca->ai_canonname);
+ for(ca = cahead; ca; ca = canext) {
canext = ca->ai_next;
-
free(ca);
}
}
@@ -112,13 +109,13 @@ int
Curl_getaddrinfo_ex(const char *nodename,
const char *servname,
const struct addrinfo *hints,
- Curl_addrinfo **result)
+ struct Curl_addrinfo **result)
{
const struct addrinfo *ai;
struct addrinfo *aihead;
- Curl_addrinfo *cafirst = NULL;
- Curl_addrinfo *calast = NULL;
- Curl_addrinfo *ca;
+ struct Curl_addrinfo *cafirst = NULL;
+ struct Curl_addrinfo *calast = NULL;
+ struct Curl_addrinfo *ca;
size_t ss_size;
int error;
@@ -131,7 +128,7 @@ Curl_getaddrinfo_ex(const char *nodename,
/* traverse the addrinfo list */
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
-
+ size_t namelen = ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0;
/* ignore elements with unsupported address family, */
/* settle family-specific sockaddr structure size. */
if(ai->ai_family == AF_INET)
@@ -151,7 +148,7 @@ Curl_getaddrinfo_ex(const char *nodename,
if((size_t)ai->ai_addrlen < ss_size)
continue;
- ca = malloc(sizeof(Curl_addrinfo));
+ ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
if(!ca) {
error = EAI_MEMORY;
break;
@@ -169,22 +166,12 @@ Curl_getaddrinfo_ex(const char *nodename,
ca->ai_canonname = NULL;
ca->ai_next = NULL;
- ca->ai_addr = malloc(ss_size);
- if(!ca->ai_addr) {
- error = EAI_MEMORY;
- free(ca);
- break;
- }
+ ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
- if(ai->ai_canonname != NULL) {
- ca->ai_canonname = strdup(ai->ai_canonname);
- if(!ca->ai_canonname) {
- error = EAI_MEMORY;
- free(ca->ai_addr);
- free(ca);
- break;
- }
+ if(namelen) {
+ ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size);
+ memcpy(ca->ai_canonname, ai->ai_canonname, namelen);
}
/* if the return list is empty, this becomes the first element */
@@ -252,7 +239,6 @@ Curl_getaddrinfo_ex(const char *nodename,
* struct sockaddr *ai_addr;
* struct Curl_addrinfo *ai_next;
* };
- * typedef struct Curl_addrinfo Curl_addrinfo;
*
* hostent defined in <netdb.h>
*
@@ -269,12 +255,12 @@ Curl_getaddrinfo_ex(const char *nodename,
* #define h_addr h_addr_list[0]
*/
-Curl_addrinfo *
+struct Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port)
{
- Curl_addrinfo *ai;
- Curl_addrinfo *prevai = NULL;
- Curl_addrinfo *firstai = NULL;
+ struct Curl_addrinfo *ai;
+ struct Curl_addrinfo *prevai = NULL;
+ struct Curl_addrinfo *firstai = NULL;
struct sockaddr_in *addr;
#ifdef ENABLE_IPV6
struct sockaddr_in6 *addr6;
@@ -290,8 +276,8 @@ Curl_he2ai(const struct hostent *he, int port)
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
-
size_t ss_size;
+ size_t namelen = strlen(he->h_name) + 1; /* include zero termination */
#ifdef ENABLE_IPV6
if(he->h_addrtype == AF_INET6)
ss_size = sizeof(struct sockaddr_in6);
@@ -299,24 +285,17 @@ Curl_he2ai(const struct hostent *he, int port)
#endif
ss_size = sizeof(struct sockaddr_in);
- ai = calloc(1, sizeof(Curl_addrinfo));
+ /* allocate memory to told the struct, the address and the name */
+ ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
if(!ai) {
result = CURLE_OUT_OF_MEMORY;
break;
}
- ai->ai_canonname = strdup(he->h_name);
- if(!ai->ai_canonname) {
- result = CURLE_OUT_OF_MEMORY;
- free(ai);
- break;
- }
- ai->ai_addr = calloc(1, ss_size);
- if(!ai->ai_addr) {
- result = CURLE_OUT_OF_MEMORY;
- free(ai->ai_canonname);
- free(ai);
- break;
- }
+ /* put the address after the struct */
+ ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
+ /* then put the name after the address */
+ ai->ai_canonname = (char *)ai->ai_addr + ss_size;
+ memcpy(ai->ai_canonname, he->h_name, namelen);
if(!firstai)
/* store the pointer we want to return from this function */
@@ -389,10 +368,10 @@ struct namebuff {
* given address/host
*/
-Curl_addrinfo *
+struct Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
{
- Curl_addrinfo *ai;
+ struct Curl_addrinfo *ai;
#if defined(__VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
@@ -465,7 +444,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
* Given an IPv4 or IPv6 dotted string address, this converts it to a proper
* allocated Curl_addrinfo struct and returns it.
*/
-Curl_addrinfo *Curl_str2addr(char *address, int port)
+struct Curl_addrinfo *Curl_str2addr(char *address, int port)
{
struct in_addr in;
if(Curl_inet_pton(AF_INET, address, &in) > 0)
@@ -488,22 +467,19 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
* struct initialized with this path.
* Set '*longpath' to TRUE if the error is a too long path.
*/
-Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
+struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
+ bool abstract)
{
- Curl_addrinfo *ai;
+ struct Curl_addrinfo *ai;
struct sockaddr_un *sa_un;
size_t path_len;
*longpath = FALSE;
- ai = calloc(1, sizeof(Curl_addrinfo));
+ ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
if(!ai)
return NULL;
- ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
- if(!ai->ai_addr) {
- free(ai);
- return NULL;
- }
+ ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
sa_un = (void *) ai->ai_addr;
sa_un->sun_family = AF_UNIX;
@@ -511,7 +487,6 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
/* sun_path must be able to store the NUL-terminated path */
path_len = strlen(path) + 1;
if(path_len > sizeof(sa_un->sun_path)) {
- free(ai->ai_addr);
free(ai);
*longpath = TRUE;
return NULL;
@@ -594,9 +569,9 @@ curl_dbg_getaddrinfo(const char *hostname,
* Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
* 10.11.5.
*/
-void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
+void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port)
{
- Curl_addrinfo *ca;
+ struct Curl_addrinfo *ca;
struct sockaddr_in *addr;
#ifdef ENABLE_IPV6
struct sockaddr_in6 *addr6;
diff --git a/libs/libcurl/src/curl_addrinfo.h b/libs/libcurl/src/curl_addrinfo.h
index 205e121ea6..a0cade614e 100644
--- a/libs/libcurl/src/curl_addrinfo.h
+++ b/libs/libcurl/src/curl_addrinfo.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -40,7 +40,6 @@
# include <stdlib.h>
#endif
-
/*
* Curl_addrinfo is our internal struct definition that we use to allow
* consistent internal handling of this data. We use this even when the
@@ -58,29 +57,29 @@ struct Curl_addrinfo {
struct sockaddr *ai_addr;
struct Curl_addrinfo *ai_next;
};
-typedef struct Curl_addrinfo Curl_addrinfo;
void
-Curl_freeaddrinfo(Curl_addrinfo *cahead);
+Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
#ifdef HAVE_GETADDRINFO
int
Curl_getaddrinfo_ex(const char *nodename,
const char *servname,
const struct addrinfo *hints,
- Curl_addrinfo **result);
+ struct Curl_addrinfo **result);
#endif
-Curl_addrinfo *
+struct Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port);
-Curl_addrinfo *
+struct Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
-Curl_addrinfo *Curl_str2addr(char *dotted, int port);
+struct Curl_addrinfo *Curl_str2addr(char *dotted, int port);
#ifdef USE_UNIX_SOCKETS
-Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
+struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
+ bool abstract);
#endif
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
@@ -98,7 +97,7 @@ curl_dbg_getaddrinfo(const char *hostname, const char *service,
#ifdef HAVE_GETADDRINFO
#ifdef USE_RESOLVE_ON_IPS
-void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
+void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port);
#else
#define Curl_addrinfo_set_port(x,y)
#endif
diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake
index 57a86e50ac..05a5acb038 100644
--- a/libs/libcurl/src/curl_config.h.cmake
+++ b/libs/libcurl/src/curl_config.h.cmake
@@ -428,6 +428,9 @@
/* Define to 1 if you have the <libssh2.h> header file. */
#cmakedefine HAVE_LIBSSH2_H 1
+/* Define to 1 if you have the <libssh/libssh.h> header file. */
+#cmakedefine HAVE_LIBSSH_LIBSSH_H 1
+
/* if zlib is available */
#cmakedefine HAVE_LIBZ 1
@@ -969,6 +972,9 @@ ${SIZEOF_TIME_T_CODE}
/* if WolfSSL is enabled */
#cmakedefine USE_WOLFSSL 1
+/* if libSSH is in use */
+#cmakedefine USE_LIBSSH 1
+
/* if libSSH2 is in use */
#cmakedefine USE_LIBSSH2 1
@@ -990,9 +996,24 @@ ${SIZEOF_TIME_T_CODE}
/* to enable NGHTTP2 */
#cmakedefine USE_NGHTTP2 1
+/* to enable NGTCP2 */
+#cmakedefine USE_NGTCP2 1
+
+/* to enable NGHTTP3 */
+#cmakedefine USE_NGHTTP3 1
+
+/* to enable quiche */
+#cmakedefine USE_QUICHE 1
+
+/* Define to 1 if you have the quiche_conn_set_qlog_fd function. */
+#cmakedefine HAVE_QUICHE_CONN_SET_QLOG_FD 1
+
/* if Unix domain sockets are enabled */
#cmakedefine USE_UNIX_SOCKETS
+/* to enable alt-svc */
+#cmakedefine USE_ALTSVC 1
+
/* Define to 1 if you are building a Windows target with large file support. */
#cmakedefine USE_WIN32_LARGE_FILES 1
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index abb6c07823..dc792f4ca7 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -552,6 +552,9 @@
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
+/* Define to 1 if you have the `quiche_conn_set_qlog_fd' function. */
+#undef HAVE_QUICHE_CONN_SET_QLOG_FD
+
/* Define to 1 if you have the <quiche.h> header file. */
#undef HAVE_QUICHE_H
@@ -690,6 +693,9 @@
/* Define to 1 if you have the timeval struct. */
#undef HAVE_STRUCT_TIMEVAL
+/* Define to 1 if suseconds_t is an available type. */
+#undef HAVE_SUSECONDS_T
+
/* Define to 1 if you have the <sys/filio.h> header file. */
#undef HAVE_SYS_FILIO_H
@@ -792,6 +798,9 @@
/* Define to 1 if you have the `wolfSSLv3_client_method' function. */
#undef HAVE_WOLFSSLV3_CLIENT_METHOD
+/* if you have wolfSSL_DES_set_odd_parity */
+#undef HAVE_WOLFSSL_DES_SET_ODD_PARITY
+
/* Define to 1 if you have the `wolfSSL_get_peer_certificate' function. */
#undef HAVE_WOLFSSL_GET_PEER_CERTIFICATE
diff --git a/libs/libcurl/src/curl_hmac.h b/libs/libcurl/src/curl_hmac.h
index 3ff799bbda..9b70c8468b 100644
--- a/libs/libcurl/src/curl_hmac.h
+++ b/libs/libcurl/src/curl_hmac.h
@@ -34,37 +34,35 @@ typedef void (* HMAC_hfinal_func)(unsigned char *result, void *context);
/* Per-hash function HMAC parameters. */
-
-typedef struct {
- HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */
+struct HMAC_params {
+ HMAC_hinit_func
+ hmac_hinit; /* Initialize context procedure. */
HMAC_hupdate_func hmac_hupdate; /* Update context with data. */
HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */
unsigned int hmac_ctxtsize; /* Context structure size. */
unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */
unsigned int hmac_resultlen; /* Result length (bytes). */
-} HMAC_params;
+};
/* HMAC computation context. */
-
-typedef struct {
- const HMAC_params *hmac_hash; /* Hash function definition. */
+struct HMAC_context {
+ const struct HMAC_params *hmac_hash; /* Hash function definition. */
void *hmac_hashctxt1; /* Hash function context 1. */
void *hmac_hashctxt2; /* Hash function context 2. */
-} HMAC_context;
+};
/* Prototypes. */
-
-HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams,
- const unsigned char *key,
- unsigned int keylen);
-int Curl_HMAC_update(HMAC_context *context,
+struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
+ const unsigned char *key,
+ unsigned int keylen);
+int Curl_HMAC_update(struct HMAC_context *context,
const unsigned char *data,
unsigned int len);
-int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
+int Curl_HMAC_final(struct HMAC_context *context, unsigned char *result);
-CURLcode Curl_hmacit(const HMAC_params *hashparams,
+CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
const unsigned char *key, const size_t keylen,
const unsigned char *data, const size_t datalen,
unsigned char *output);
diff --git a/libs/libcurl/src/curl_md5.h b/libs/libcurl/src/curl_md5.h
index dd464416a2..e06c68edfc 100644
--- a/libs/libcurl/src/curl_md5.h
+++ b/libs/libcurl/src/curl_md5.h
@@ -33,30 +33,30 @@ typedef void (* Curl_MD5_update_func)(void *context,
unsigned int len);
typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
-typedef struct {
+struct MD5_params {
Curl_MD5_init_func md5_init_func; /* Initialize context procedure */
Curl_MD5_update_func md5_update_func; /* Update context with data */
Curl_MD5_final_func md5_final_func; /* Get final result procedure */
unsigned int md5_ctxtsize; /* Context structure size */
unsigned int md5_resultlen; /* Result length (bytes) */
-} MD5_params;
+};
-typedef struct {
- const MD5_params *md5_hash; /* Hash function definition */
+struct MD5_context {
+ const struct MD5_params *md5_hash; /* Hash function definition */
void *md5_hashctx; /* Hash function context */
-} MD5_context;
+};
-extern const MD5_params Curl_DIGEST_MD5[1];
-extern const HMAC_params Curl_HMAC_MD5[1];
+extern const struct MD5_params Curl_DIGEST_MD5[1];
+extern const struct HMAC_params Curl_HMAC_MD5[1];
void Curl_md5it(unsigned char *output, const unsigned char *input,
const size_t len);
-MD5_context * Curl_MD5_init(const MD5_params *md5params);
-CURLcode Curl_MD5_update(MD5_context *context,
+struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
+CURLcode Curl_MD5_update(struct MD5_context *context,
const unsigned char *data,
unsigned int len);
-CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result);
+CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result);
#endif
diff --git a/libs/libcurl/src/curl_multibyte.c b/libs/libcurl/src/curl_multibyte.c
index e3843449bb..2c8925b531 100644
--- a/libs/libcurl/src/curl_multibyte.c
+++ b/libs/libcurl/src/curl_multibyte.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -20,24 +20,21 @@
*
***************************************************************************/
-#include "curl_setup.h"
-
-#include <curl/curl.h>
+/*
+ * This file is 'mem-include-scan' clean. See test 1132.
+ */
-#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
- defined(USE_WIN32_LDAP)) && defined(UNICODE))
+#include "curl_setup.h"
- /*
- * MultiByte conversions using Windows kernel32 library.
- */
+#if defined(WIN32)
#include "curl_multibyte.h"
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
+/*
+ * MultiByte conversions using Windows kernel32 library.
+ */
-wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
+wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
{
wchar_t *str_w = NULL;
@@ -59,7 +56,7 @@ wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
return str_w;
}
-char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
+char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
{
char *str_utf8 = NULL;
@@ -81,4 +78,76 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
return str_utf8;
}
-#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
+#endif /* WIN32 */
+
+#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
+
+FILE *curlx_win32_fopen(const char *filename, const char *mode)
+{
+#ifdef _UNICODE
+ FILE *result = NULL;
+ wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
+ wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
+ if(filename_w && mode_w)
+ result = _wfopen(filename_w, mode_w);
+ free(filename_w);
+ free(mode_w);
+ if(result)
+ return result;
+#endif
+
+ return (fopen)(filename, mode);
+}
+
+int curlx_win32_stat(const char *path, struct_stat *buffer)
+{
+ int result = -1;
+#ifdef _UNICODE
+ wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
+#endif /* _UNICODE */
+
+#if defined(USE_WIN32_SMALL_FILES)
+#if defined(_UNICODE)
+ if(path_w)
+ result = _wstat(path_w, buffer);
+ else
+#endif /* _UNICODE */
+ result = _stat(path, buffer);
+#else /* USE_WIN32_SMALL_FILES */
+#if defined(_UNICODE)
+ if(path_w)
+ result = _wstati64(path_w, buffer);
+ else
+#endif /* _UNICODE */
+ result = _stati64(path, buffer);
+#endif /* USE_WIN32_SMALL_FILES */
+
+#ifdef _UNICODE
+ free(path_w);
+#endif
+
+ return result;
+}
+
+int curlx_win32_access(const char *path, int mode)
+{
+ int result = -1;
+#ifdef _UNICODE
+ wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
+#endif /* _UNICODE */
+
+#if defined(_UNICODE)
+ if(path_w)
+ result = _waccess(path_w, mode);
+ else
+#endif /* _UNICODE */
+ result = _access(path, mode);
+
+#ifdef _UNICODE
+ free(path_w);
+#endif
+
+ return result;
+}
+
+#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
diff --git a/libs/libcurl/src/curl_multibyte.h b/libs/libcurl/src/curl_multibyte.h
index 3becf41cfa..5f8c05afcc 100644
--- a/libs/libcurl/src/curl_multibyte.h
+++ b/libs/libcurl/src/curl_multibyte.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -23,48 +23,43 @@
***************************************************************************/
#include "curl_setup.h"
-#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
- defined(USE_WIN32_LDAP)) && defined(UNICODE))
+#if defined(WIN32)
/*
* MultiByte conversions using Windows kernel32 library.
*/
-wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
-char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
+wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8);
+char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w);
-#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
-
-
-#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
- defined(USE_WIN32_LDAP)
+#endif /* WIN32 */
/*
- * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
- * and Curl_unicodefree() main purpose is to minimize the number of
+ * Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8()
+ * and curlx_unicodefree() main purpose is to minimize the number of
* preprocessor conditional directives needed by code using these
* to differentiate UNICODE from non-UNICODE builds.
*
- * When building with UNICODE defined, this two macros
- * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * When building with UNICODE defined, these two macros
+ * curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8()
* return a pointer to a newly allocated memory area holding result.
* When the result is no longer needed, allocated memory is intended
- * to be free'ed with Curl_unicodefree().
+ * to be free'ed with curlx_unicodefree().
*
* When building without UNICODE defined, this macros
- * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
- * return the pointer received as argument. Curl_unicodefree() does
+ * curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8()
+ * return the pointer received as argument. curlx_unicodefree() does
* no actual free'ing of this pointer it is simply set to NULL.
*/
-#ifdef UNICODE
+#if defined(UNICODE) && defined(WIN32)
-#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
-#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
-#define Curl_unicodefree(ptr) \
+#define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr))
+#define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr))
+#define curlx_unicodefree(ptr) \
do { \
if(ptr) { \
- free(ptr); \
+ (free)(ptr); \
(ptr) = NULL; \
} \
} while(0)
@@ -78,9 +73,9 @@ typedef union {
#else
-#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
-#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
-#define Curl_unicodefree(ptr) \
+#define curlx_convert_UTF8_to_tchar(ptr) (ptr)
+#define curlx_convert_tchar_to_UTF8(ptr) (ptr)
+#define curlx_unicodefree(ptr) \
do {(ptr) = NULL;} while(0)
typedef union {
@@ -90,8 +85,6 @@ typedef union {
const unsigned char *const_tbyte_ptr;
} xcharp_u;
-#endif /* UNICODE */
-
-#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
+#endif /* UNICODE && WIN32 */
#endif /* HEADER_CURL_MULTIBYTE_H */
diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c
index 32e29a9334..0eefb15879 100644
--- a/libs/libcurl/src/curl_ntlm_core.c
+++ b/libs/libcurl/src/curl_ntlm_core.c
@@ -52,13 +52,18 @@
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
+
+#ifdef USE_WOLFSSL
+#include <wolfssl/options.h>
+#endif
# include <openssl/des.h>
# include <openssl/md5.h>
# include <openssl/ssl.h>
# include <openssl/rand.h>
-# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+# if (defined(OPENSSL_VERSION_NUMBER) && \
+ (OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
# define DES_key_schedule des_key_schedule
# define DES_cblock des_cblock
# define DES_set_odd_parity des_set_odd_parity
@@ -78,14 +83,12 @@
#elif defined(USE_GNUTLS)
# include <gcrypt.h>
-# define MD5_DIGEST_LENGTH 16
#elif defined(USE_NSS)
# include <nss.h>
# include <pk11pub.h>
# include <hasht.h>
-# define MD5_DIGEST_LENGTH MD5_LENGTH
#elif defined(USE_MBEDTLS)
@@ -138,7 +141,7 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key)
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
}
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
/*
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
* key schedule ks is also set.
@@ -387,7 +390,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
const unsigned char *plaintext,
unsigned char *results)
{
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
DES_key_schedule ks;
setup_des_key(keys, DESKEY(ks));
@@ -462,7 +465,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
{
/* Create LanManager hashed password. */
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
DES_key_schedule ks;
setup_des_key(pw, DESKEY(ks));
diff --git a/libs/libcurl/src/curl_ntlm_core.h b/libs/libcurl/src/curl_ntlm_core.h
index e1643d6277..7895b64709 100644
--- a/libs/libcurl/src/curl_ntlm_core.h
+++ b/libs/libcurl/src/curl_ntlm_core.h
@@ -29,6 +29,7 @@
/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
then it must be initialized to be used by NTLM. */
#if !defined(USE_OPENSSL) && \
+ !defined(USE_WOLFSSL) && \
!defined(USE_GNUTLS_NETTLE) && \
!defined(USE_GNUTLS) && \
defined(USE_NSS)
@@ -37,7 +38,10 @@
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
+#ifdef USE_WOLFSSL
+# include <wolfssl/options.h>
+#endif
# include <openssl/ssl.h>
#endif
diff --git a/libs/libcurl/src/curl_ntlm_wb.c b/libs/libcurl/src/curl_ntlm_wb.c
index f820b842e8..17a92f8ca2 100644
--- a/libs/libcurl/src/curl_ntlm_wb.c
+++ b/libs/libcurl/src/curl_ntlm_wb.c
@@ -261,15 +261,11 @@ done:
static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
const char *input, curlntlm state)
{
- char *buf = malloc(NTLM_BUFSIZE);
size_t len_in = strlen(input), len_out = 0;
-
-#if defined(CURL_DISABLE_VERBOSE_STRINGS)
- (void) data;
-#endif
-
- if(!buf)
- return CURLE_OUT_OF_MEMORY;
+ struct dynbuf b;
+ char *ptr = NULL;
+ unsigned char *buf = (unsigned char *)data->state.buffer;
+ Curl_dyn_init(&b, MAX_NTLM_WB_RESPONSE);
while(len_in > 0) {
ssize_t written = swrite(ntlm->ntlm_auth_hlpr_socket, input, len_in);
@@ -285,10 +281,8 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
}
/* Read one line */
while(1) {
- ssize_t size;
- char *newbuf;
-
- size = sread(ntlm->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
+ ssize_t size =
+ sread(ntlm->ntlm_auth_hlpr_socket, buf, data->set.buffer_size);
if(size == -1) {
if(errno == EINTR)
continue;
@@ -297,48 +291,41 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
else if(size == 0)
goto done;
- len_out += size;
- if(buf[len_out - 1] == '\n') {
- buf[len_out - 1] = '\0';
- break;
- }
+ if(Curl_dyn_addn(&b, buf, size))
+ goto done;
- if(len_out > MAX_NTLM_WB_RESPONSE) {
- failf(data, "too large ntlm_wb response!");
- free(buf);
- return CURLE_OUT_OF_MEMORY;
+ len_out = Curl_dyn_len(&b);
+ ptr = Curl_dyn_ptr(&b);
+ if(len_out && ptr[len_out - 1] == '\n') {
+ ptr[len_out - 1] = '\0';
+ break; /* done! */
}
-
- newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
- if(!newbuf)
- return CURLE_OUT_OF_MEMORY;
-
- buf = newbuf;
+ /* loop */
}
/* Samba/winbind installed but not configured */
if(state == NTLMSTATE_TYPE1 &&
len_out == 3 &&
- buf[0] == 'P' && buf[1] == 'W')
+ ptr[0] == 'P' && ptr[1] == 'W')
goto done;
/* invalid response */
if(len_out < 4)
goto done;
if(state == NTLMSTATE_TYPE1 &&
- (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
+ (ptr[0]!='Y' || ptr[1]!='R' || ptr[2]!=' '))
goto done;
if(state == NTLMSTATE_TYPE2 &&
- (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
- (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
+ (ptr[0]!='K' || ptr[1]!='K' || ptr[2]!=' ') &&
+ (ptr[0]!='A' || ptr[1]!='F' || ptr[2]!=' '))
goto done;
- ntlm->response = aprintf("%.*s", len_out - 4, buf + 3);
- free(buf);
+ ntlm->response = strdup(ptr + 3);
+ Curl_dyn_free(&b);
if(!ntlm->response)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
done:
- free(buf);
+ Curl_dyn_free(&b);
return CURLE_REMOTE_ACCESS_DENIED;
}
@@ -389,8 +376,7 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
* This is for creating ntlm header output by delegating challenge/response
* to Samba's winbind daemon helper ntlm_auth.
*/
-CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
- bool proxy)
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy)
{
/* point to the address of the pointer that holds the string to send to the
server, which is for a plain host or for a HTTP proxy */
@@ -400,6 +386,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
struct ntlmdata *ntlm;
curlntlm *state;
struct auth *authp;
+ struct Curl_easy *data = conn->data;
CURLcode res = CURLE_OK;
@@ -407,14 +394,18 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
DEBUGASSERT(conn->data);
if(proxy) {
- allocuserpwd = &conn->allocptr.proxyuserpwd;
+#ifndef CURL_DISABLE_PROXY
+ allocuserpwd = &data->state.aptr.proxyuserpwd;
userp = conn->http_proxy.user;
ntlm = &conn->proxyntlm;
state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
+#else
+ return CURLE_NOT_BUILT_IN;
+#endif
}
else {
- allocuserpwd = &conn->allocptr.userpwd;
+ allocuserpwd = &data->state.aptr.userpwd;
userp = conn->user;
ntlm = &conn->ntlm;
state = &conn->http_ntlm_state;
diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c
index 8c1c86623d..83fe896e35 100644
--- a/libs/libcurl/src/curl_sasl.c
+++ b/libs/libcurl/src/curl_sasl.c
@@ -264,9 +264,14 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
size_t len = 0;
saslstate state1 = SASL_STOP;
saslstate state2 = SASL_FINAL;
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+ const char * const hostname = conn->host.name;
+ const long int port = conn->remote_port;
+#endif
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
@@ -417,18 +422,23 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
struct Curl_easy *data = conn->data;
saslstate newstate = SASL_FINAL;
char *resp = NULL;
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+ const char * const hostname = conn->host.name;
+ const long int port = conn->remote_port;
+#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
char *chlg = NULL;
size_t chlglen = 0;
#endif
-#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
- defined(USE_NTLM)
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
+ defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
- data->set.str[STRING_SERVICE_NAME] :
- sasl->params->service;
+ data->set.str[STRING_SERVICE_NAME] :
+ sasl->params->service;
char *serverdata;
#endif
size_t len = 0;
diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h
index 56e6db83ca..d76c630d05 100644
--- a/libs/libcurl/src/curl_setup.h
+++ b/libs/libcurl/src/curl_setup.h
@@ -331,9 +331,14 @@
# undef fstat
# define fstat(fdes,stp) _fstati64(fdes, stp)
# undef stat
-# define stat(fname,stp) _stati64(fname, stp)
+# define stat(fname,stp) curlx_win32_stat(fname, stp)
# define struct_stat struct _stati64
# define LSEEK_ERROR (__int64)-1
+# define fopen(fname,mode) curlx_win32_fopen(fname, mode)
+# define access(fname,mode) curlx_win32_access(fname, mode)
+ int curlx_win32_stat(const char *path, struct_stat *buffer);
+ FILE *curlx_win32_fopen(const char *filename, const char *mode);
+ int curlx_win32_access(const char *path, int mode);
#endif
/*
@@ -348,8 +353,13 @@
# undef lseek
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
# define fstat(fdes,stp) _fstat(fdes, stp)
-# define stat(fname,stp) _stat(fname, stp)
+# define stat(fname,stp) curlx_win32_stat(fname, stp)
# define struct_stat struct _stat
+# define fopen(fname,mode) curlx_win32_fopen(fname, mode)
+# define access(fname,mode) curlx_win32_access(fname, mode)
+ int curlx_win32_stat(const char *path, struct_stat *buffer);
+ FILE *curlx_win32_fopen(const char *filename, const char *mode);
+ int curlx_win32_access(const char *path, int mode);
# endif
# define LSEEK_ERROR (long)-1
#endif
@@ -627,10 +637,11 @@ int netware_init(void);
/* Single point where USE_NTLM definition might be defined */
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
- defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
- defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
- defined(USE_MBEDTLS)
+#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
+ defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
+ defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
+ defined(USE_MBEDTLS) || \
+ (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_SET_ODD_PARITY))
#define USE_NTLM
diff --git a/libs/libcurl/src/curl_setup_once.h b/libs/libcurl/src/curl_setup_once.h
index 8890f3890d..e7c00deabd 100644
--- a/libs/libcurl/src/curl_setup_once.h
+++ b/libs/libcurl/src/curl_setup_once.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -481,6 +481,8 @@ typedef int sig_atomic_t;
#ifdef __VMS
#define argv_item_t __char_ptr32
+#elif defined(_UNICODE)
+#define argv_item_t wchar_t *
#else
#define argv_item_t char *
#endif
diff --git a/libs/libcurl/src/curl_sspi.c b/libs/libcurl/src/curl_sspi.c
index f7cc10f804..83ece9afdc 100644
--- a/libs/libcurl/src/curl_sspi.c
+++ b/libs/libcurl/src/curl_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -151,7 +151,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
/* Initialize the identity */
memset(identity, 0, sizeof(*identity));
- useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
+ useranddomain.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)userp);
if(!useranddomain.tchar_ptr)
return CURLE_OUT_OF_MEMORY;
@@ -173,7 +173,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
/* Setup the identity's user and length */
dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
if(!dup_user.tchar_ptr) {
- Curl_unicodefree(useranddomain.tchar_ptr);
+ curlx_unicodefree(useranddomain.tchar_ptr);
return CURLE_OUT_OF_MEMORY;
}
identity->User = dup_user.tbyte_ptr;
@@ -183,7 +183,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
/* Setup the identity's domain and length */
dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
if(!dup_domain.tchar_ptr) {
- Curl_unicodefree(useranddomain.tchar_ptr);
+ curlx_unicodefree(useranddomain.tchar_ptr);
return CURLE_OUT_OF_MEMORY;
}
_tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
@@ -192,22 +192,22 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
identity->DomainLength = curlx_uztoul(domlen);
dup_domain.tchar_ptr = NULL;
- Curl_unicodefree(useranddomain.tchar_ptr);
+ curlx_unicodefree(useranddomain.tchar_ptr);
/* Setup the identity's password and length */
- passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
+ passwd.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)passwdp);
if(!passwd.tchar_ptr)
return CURLE_OUT_OF_MEMORY;
dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
if(!dup_passwd.tchar_ptr) {
- Curl_unicodefree(passwd.tchar_ptr);
+ curlx_unicodefree(passwd.tchar_ptr);
return CURLE_OUT_OF_MEMORY;
}
identity->Password = dup_passwd.tbyte_ptr;
identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
dup_passwd.tchar_ptr = NULL;
- Curl_unicodefree(passwd.tchar_ptr);
+ curlx_unicodefree(passwd.tchar_ptr);
/* Setup the identity's flags */
identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
diff --git a/libs/libcurl/src/curl_threads.c b/libs/libcurl/src/curl_threads.c
index 064c075d0e..b5f10a20ec 100644
--- a/libs/libcurl/src/curl_threads.c
+++ b/libs/libcurl/src/curl_threads.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -48,7 +48,7 @@ struct curl_actual_call {
static void *curl_thread_create_thunk(void *arg)
{
- struct curl_actual_call * ac = arg;
+ struct curl_actual_call *ac = arg;
unsigned int (*func)(void *) = ac->func;
void *real_arg = ac->arg;
diff --git a/libs/libcurl/src/curlx.h b/libs/libcurl/src/curlx.h
index 3e9b516f82..a8bae14b90 100644
--- a/libs/libcurl/src/curlx.h
+++ b/libs/libcurl/src/curlx.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -53,6 +53,16 @@
curlx_uztosi()
*/
+#include "curl_multibyte.h"
+/* "curl_multibyte.h" provides these functions and macros:
+
+ curlx_convert_UTF8_to_wchar()
+ curlx_convert_wchar_to_UTF8()
+ curlx_convert_UTF8_to_tchar()
+ curlx_convert_tchar_to_UTF8()
+ curlx_unicodefree()
+*/
+
/* Now setup curlx_ * names for the functions that are to become curlx_ and
be removed from a future libcurl official API:
curlx_getenv
diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c
index 10867cc34b..ebb2c243bc 100644
--- a/libs/libcurl/src/doh.c
+++ b/libs/libcurl/src/doh.c
@@ -35,13 +35,13 @@
#include "curl_base64.h"
#include "connect.h"
#include "strdup.h"
+#include "dynbuf.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
#define DNS_CLASS_IN 0x01
-#define DOH_MAX_RESPONSE_SIZE 3000 /* bytes */
#ifndef CURL_DISABLE_VERBOSE_STRINGS
static const char * const errors[]={
@@ -177,20 +177,11 @@ static size_t
doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
- struct dohresponse *mem = (struct dohresponse *)userp;
+ struct dynbuf *mem = (struct dynbuf *)userp;
- if((mem->size + realsize) > DOH_MAX_RESPONSE_SIZE)
- /* suspiciously much for us */
+ if(Curl_dyn_addn(mem, contents, realsize))
return 0;
- mem->memory = Curl_saferealloc(mem->memory, mem->size + realsize);
- if(!mem->memory)
- /* out of memory! */
- return 0;
-
- memcpy(&(mem->memory[mem->size]), contents, realsize);
- mem->size += realsize;
-
return realsize;
}
@@ -238,10 +229,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
}
p->dnstype = dnstype;
- p->serverdoh.memory = NULL;
- /* the memory will be grown as needed by realloc in the doh_write_cb
- function */
- p->serverdoh.size = 0;
+ Curl_dyn_init(&p->serverdoh, DYN_DOH_RESPONSE);
/* Note: this is code for sending the DoH request with GET but there's still
no logic that actually enables this. We should either add that ability or
@@ -272,7 +260,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
if(!result) {
/* pass in the struct pointer via a local variable to please coverity and
the gcc typecheck helpers */
- struct dohresponse *resp = &p->serverdoh;
+ struct dynbuf *resp = &p->serverdoh;
ERROR_CHECK_SETOPT(CURLOPT_URL, url);
ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb);
ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp);
@@ -385,10 +373,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
* 'Curl_addrinfo *' with the address information.
*/
-Curl_addrinfo *Curl_doh(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
@@ -401,6 +389,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
/* start clean, consider allocating this struct on demand */
memset(&data->req.doh, 0, sizeof(struct dohdata));
+ conn->bits.doh = TRUE;
data->req.doh.host = hostname;
data->req.doh.port = port;
data->req.doh.headers =
@@ -506,38 +495,12 @@ static DOHcode store_aaaa(const unsigned char *doh,
return DOH_OK;
}
-static DOHcode cnameappend(struct cnamestore *c,
- const unsigned char *src,
- size_t len)
-{
- if(!c->alloc) {
- c->allocsize = len + 1;
- c->alloc = malloc(c->allocsize);
- if(!c->alloc)
- return DOH_OUT_OF_MEM;
- }
- else if(c->allocsize < (c->allocsize + len + 1)) {
- char *ptr;
- c->allocsize += len + 1;
- ptr = realloc(c->alloc, c->allocsize);
- if(!ptr) {
- free(c->alloc);
- return DOH_OUT_OF_MEM;
- }
- c->alloc = ptr;
- }
- memcpy(&c->alloc[c->len], src, len);
- c->len += len;
- c->alloc[c->len] = 0; /* keep it zero terminated */
- return DOH_OK;
-}
-
static DOHcode store_cname(const unsigned char *doh,
size_t dohlen,
unsigned int index,
struct dohentry *d)
{
- struct cnamestore *c;
+ struct dynbuf *c;
unsigned int loop = 128; /* a valid DNS name can never loop this much */
unsigned char length;
@@ -566,18 +529,15 @@ static DOHcode store_cname(const unsigned char *doh,
index++;
if(length) {
- DOHcode rc;
- if(c->len) {
- rc = cnameappend(c, (unsigned char *)".", 1);
- if(rc)
- return rc;
+ if(Curl_dyn_len(c)) {
+ if(Curl_dyn_add(c, "."))
+ return DOH_OUT_OF_MEM;
}
if((index + length) > dohlen)
return DOH_DNS_BAD_LABEL;
- rc = cnameappend(c, &doh[index], length);
- if(rc)
- return rc;
+ if(Curl_dyn_addn(c, &doh[index], length))
+ return DOH_OUT_OF_MEM;
index += length;
}
} while(length && --loop);
@@ -630,10 +590,13 @@ static DOHcode rdata(const unsigned char *doh,
return DOH_OK;
}
-static void init_dohentry(struct dohentry *de)
+UNITTEST void de_init(struct dohentry *de)
{
+ int i;
memset(de, 0, sizeof(*de));
de->ttl = INT_MAX;
+ for(i = 0; i < DOH_MAX_CNAME; i++)
+ Curl_dyn_init(&de->cname[i], DYN_DOH_CNAME);
}
@@ -808,7 +771,7 @@ static void showdoh(struct Curl_easy *data,
}
}
for(i = 0; i < d->numcname; i++) {
- infof(data, "CNAME: %s\n", d->cname[i].alloc);
+ infof(data, "CNAME: %s\n", Curl_dyn_ptr(&d->cname[i]));
}
}
#else
@@ -828,18 +791,19 @@ static void showdoh(struct Curl_easy *data,
* must be an associated call later to Curl_freeaddrinfo().
*/
-static Curl_addrinfo *
+static struct Curl_addrinfo *
doh2ai(const struct dohentry *de, const char *hostname, int port)
{
- Curl_addrinfo *ai;
- Curl_addrinfo *prevai = NULL;
- Curl_addrinfo *firstai = NULL;
+ struct Curl_addrinfo *ai;
+ struct Curl_addrinfo *prevai = NULL;
+ struct Curl_addrinfo *firstai = NULL;
struct sockaddr_in *addr;
#ifdef ENABLE_IPV6
struct sockaddr_in6 *addr6;
#endif
CURLcode result = CURLE_OK;
int i;
+ size_t hostlen = strlen(hostname) + 1; /* include zero terminator */
if(!de)
/* no input == no output! */
@@ -862,24 +826,14 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
addrtype = AF_INET;
}
- ai = calloc(1, sizeof(Curl_addrinfo));
+ ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen);
if(!ai) {
result = CURLE_OUT_OF_MEMORY;
break;
}
- ai->ai_canonname = strdup(hostname);
- if(!ai->ai_canonname) {
- result = CURLE_OUT_OF_MEMORY;
- free(ai);
- break;
- }
- ai->ai_addr = calloc(1, ss_size);
- if(!ai->ai_addr) {
- result = CURLE_OUT_OF_MEMORY;
- free(ai->ai_canonname);
- free(ai);
- break;
- }
+ ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
+ ai->ai_canonname = (void *)((char *)ai->ai_addr + ss_size);
+ memcpy(ai->ai_canonname, hostname, hostlen);
if(!firstai)
/* store the pointer we want to return from this function */
@@ -941,7 +895,7 @@ UNITTEST void de_cleanup(struct dohentry *d)
{
int i = 0;
for(i = 0; i < d->numcname; i++) {
- free(d->cname[i].alloc);
+ Curl_dyn_free(&d->cname[i]);
}
}
@@ -959,7 +913,9 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
CURLE_COULDNT_RESOLVE_HOST;
}
else if(!data->req.doh.pending) {
- DOHcode rc[DOH_PROBE_SLOTS];
+ DOHcode rc[DOH_PROBE_SLOTS] = {
+ DOH_OK, DOH_OK
+ };
struct dohentry de;
int slot;
/* remove DOH handles from multi handle and close them */
@@ -968,17 +924,19 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
Curl_close(&data->req.doh.probe[slot].easy);
}
/* parse the responses, create the struct and return it! */
- init_dohentry(&de);
+ de_init(&de);
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
- rc[slot] = doh_decode(data->req.doh.probe[slot].serverdoh.memory,
- data->req.doh.probe[slot].serverdoh.size,
- data->req.doh.probe[slot].dnstype,
+ struct dnsprobe *p = &data->req.doh.probe[slot];
+ if(!p->dnstype)
+ continue;
+ rc[slot] = doh_decode(Curl_dyn_uptr(&p->serverdoh),
+ Curl_dyn_len(&p->serverdoh),
+ p->dnstype,
&de);
- Curl_safefree(data->req.doh.probe[slot].serverdoh.memory);
+ Curl_dyn_free(&p->serverdoh);
if(rc[slot]) {
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]),
- type2name(data->req.doh.probe[slot].dnstype),
- data->req.doh.host);
+ type2name(p->dnstype), data->req.doh.host);
}
} /* next slot */
diff --git a/libs/libcurl/src/doh.h b/libs/libcurl/src/doh.h
index f6154ffd4b..bbd4c1a65e 100644
--- a/libs/libcurl/src/doh.h
+++ b/libs/libcurl/src/doh.h
@@ -32,10 +32,10 @@
* and returns a 'Curl_addrinfo *' with the address information.
*/
-Curl_addrinfo *Curl_doh(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp);
+struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp);
CURLcode Curl_doh_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns);
@@ -70,12 +70,6 @@ typedef enum {
#define DOH_MAX_ADDR 24
#define DOH_MAX_CNAME 4
-struct cnamestore {
- size_t len; /* length of cname */
- char *alloc; /* allocated pointer */
- size_t allocsize; /* allocated size */
-};
-
struct dohaddr {
int type;
union {
@@ -85,11 +79,11 @@ struct dohaddr {
};
struct dohentry {
- unsigned int ttl;
- int numaddr;
+ struct dynbuf cname[DOH_MAX_CNAME];
struct dohaddr addr[DOH_MAX_ADDR];
+ int numaddr;
+ unsigned int ttl;
int numcname;
- struct cnamestore cname[DOH_MAX_CNAME];
};
@@ -103,6 +97,7 @@ DOHcode doh_decode(const unsigned char *doh,
size_t dohlen,
DNStype dnstype,
struct dohentry *d);
+void de_init(struct dohentry *d);
void de_cleanup(struct dohentry *d);
#endif
diff --git a/libs/libcurl/src/dynbuf.c b/libs/libcurl/src/dynbuf.c
new file mode 100644
index 0000000000..dfc1d05c64
--- /dev/null
+++ b/libs/libcurl/src/dynbuf.c
@@ -0,0 +1,227 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, 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.haxx.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.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "strdup.h"
+#include "dynbuf.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MIN_FIRST_ALLOC 32
+
+#define DYNINIT 0xbee51da /* random pattern */
+
+/*
+ * Init a dynbuf struct.
+ */
+void Curl_dyn_init(struct dynbuf *s, size_t toobig)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(toobig);
+ s->bufr = NULL;
+ s->leng = 0;
+ s->allc = 0;
+ s->toobig = toobig;
+#ifdef DEBUGBUILD
+ s->init = DYNINIT;
+#endif
+}
+
+/*
+ * free the buffer and re-init the necessary fields. It doesn't touch the
+ * 'init' field and thus this buffer can be reused to add data to again.
+ */
+void Curl_dyn_free(struct dynbuf *s)
+{
+ DEBUGASSERT(s);
+ Curl_safefree(s->bufr);
+ s->leng = s->allc = 0;
+}
+
+/*
+ * Store/append an chunk of memory to the dynbuf.
+ */
+static CURLcode dyn_nappend(struct dynbuf *s,
+ const unsigned char *mem, size_t len)
+{
+ size_t indx = s->leng;
+ size_t a = s->allc;
+ size_t fit = len + indx + 1; /* new string + old string + zero byte */
+
+ /* try to detect if there's rubbish in the struct */
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(s->toobig);
+ DEBUGASSERT(indx < s->toobig);
+ DEBUGASSERT(!s->leng || s->bufr);
+
+ if(fit > s->toobig) {
+ Curl_dyn_free(s);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else if(!a) {
+ DEBUGASSERT(!indx);
+ /* first invoke */
+ if(fit < MIN_FIRST_ALLOC)
+ a = MIN_FIRST_ALLOC;
+ else
+ a = fit;
+ }
+ else {
+ while(a < fit)
+ a *= 2;
+ }
+
+ if(a != s->allc) {
+ s->bufr = Curl_saferealloc(s->bufr, a);
+ if(!s->bufr) {
+ s->leng = s->allc = 0;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ s->allc = a;
+ }
+
+ if(len)
+ memcpy(&s->bufr[indx], mem, len);
+ s->leng = indx + len;
+ s->bufr[s->leng] = 0;
+ return CURLE_OK;
+}
+
+/*
+ * Clears the string, keeps the allocation. This can also be called on a
+ * buffer that already was freed.
+ */
+void Curl_dyn_reset(struct dynbuf *s)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ if(s->leng)
+ s->bufr[0] = 0;
+ s->leng = 0;
+}
+
+#ifdef USE_NGTCP2
+/*
+ * Specify the size of the tail to keep (number of bytes from the end of the
+ * buffer). The rest will be dropped.
+ */
+CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ if(trail > s->leng)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ else if(trail == s->leng)
+ return CURLE_OK;
+ else if(!trail) {
+ Curl_dyn_reset(s);
+ }
+ else {
+ memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail);
+ s->leng = trail;
+ }
+ return CURLE_OK;
+
+}
+#endif
+
+/*
+ * Appends a buffer with length.
+ */
+CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ return dyn_nappend(s, mem, len);
+}
+
+/*
+ * Append a zero terminated string at the end.
+ */
+CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
+{
+ size_t n = strlen(str);
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ return dyn_nappend(s, (unsigned char *)str, n);
+}
+
+/*
+ * Append a string printf()-style
+ */
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+{
+ char *str;
+ va_list ap;
+ va_start(ap, fmt);
+ str = vaprintf(fmt, ap); /* this allocs a new string to append */
+ va_end(ap);
+
+ if(str) {
+ CURLcode result = dyn_nappend(s, (unsigned char *)str, strlen(str));
+ free(str);
+ return result;
+ }
+ /* If we failed, we cleanup the whole buffer and return error */
+ Curl_dyn_free(s);
+ return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * Returns a pointer to the buffer.
+ */
+char *Curl_dyn_ptr(const struct dynbuf *s)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ return s->bufr;
+}
+
+/*
+ * Returns an unsigned pointer to the buffer.
+ */
+unsigned char *Curl_dyn_uptr(const struct dynbuf *s)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ return (unsigned char *)s->bufr;
+}
+
+/*
+ * Returns the length of the buffer.
+ */
+size_t Curl_dyn_len(const struct dynbuf *s)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ return s->leng;
+}
diff --git a/libs/libcurl/src/dynbuf.h b/libs/libcurl/src/dynbuf.h
new file mode 100644
index 0000000000..7809becfef
--- /dev/null
+++ b/libs/libcurl/src/dynbuf.h
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_DYNBUF_H
+#define HEADER_CURL_DYNBUF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, 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.haxx.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.
+ *
+ ***************************************************************************/
+
+struct dynbuf {
+ char *bufr; /* point to a zero terminated allocated buffer */
+ size_t leng; /* number of bytes *EXCLUDING* the zero terminator */
+ size_t allc; /* size of the current allocation */
+ size_t toobig; /* size limit for the buffer */
+#ifdef DEBUGBUILD
+ int init; /* detect API usage mistakes */
+#endif
+};
+
+void Curl_dyn_init(struct dynbuf *s, size_t toobig);
+void Curl_dyn_free(struct dynbuf *s);
+CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
+ WARN_UNUSED_RESULT;
+CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
+ WARN_UNUSED_RESULT;
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+ WARN_UNUSED_RESULT;
+void Curl_dyn_reset(struct dynbuf *s);
+CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail);
+char *Curl_dyn_ptr(const struct dynbuf *s);
+unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
+size_t Curl_dyn_len(const struct dynbuf *s);
+
+/* Dynamic buffer max sizes */
+#define DYN_DOH_RESPONSE 3000
+#define DYN_DOH_CNAME 256
+#define DYN_PAUSE_BUFFER (64 * 1024 * 1024)
+#define DYN_HAXPROXY 2048
+#define DYN_HTTP_REQUEST (128*1024)
+#define DYN_H2_HEADERS (128*1024)
+#define DYN_H2_TRAILER 4096
+#define DYN_APRINTF 8000000
+#define DYN_RTSP_REQ_HEADER (64*1024)
+#define DYN_TRAILERS (64*1024)
+#define DYN_PROXY_CONNECT_HEADERS 16384
+#define DYN_QLOG_NAME 1024
+#define DYN_H1_TRAILER DYN_H2_TRAILER
+#endif
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index d08c6066c8..292cca7f6f 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -77,6 +77,7 @@
#include "http_digest.h"
#include "system_win32.h"
#include "http2.h"
+#include "dynbuf.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -509,7 +510,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
before = Curl_now();
/* wait for activity or timeout */
- pollrc = Curl_poll(fds, numfds, (int)ev->ms);
+ pollrc = Curl_poll(fds, numfds, ev->ms);
after = Curl_now();
@@ -680,6 +681,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
mcode = curl_multi_add_handle(multi, data);
if(mcode) {
curl_multi_cleanup(multi);
+ data->multi_easy = NULL;
if(mcode == CURLM_OUT_OF_MEMORY)
return CURLE_OUT_OF_MEMORY;
return CURLE_FAILED_INIT;
@@ -762,6 +764,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
{
CURLcode result = CURLE_OK;
enum dupstring i;
+ enum dupblob j;
/* Copy src->set into dst->set first, then deal with the strings
afterwards */
@@ -778,6 +781,16 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
return result;
}
+ /* clear all blob pointers first */
+ memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *));
+ /* duplicate all blobs */
+ for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
+ result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]);
+ /* Curl_setstropt return CURLE_BAD_FUNCTION_ARGUMENT with blob */
+ if(result)
+ return result;
+ }
+
/* duplicate memory areas pointed to */
i = STRING_COPYPOSTFIELDS;
if(src->set.postfieldsize && src->set.str[i]) {
@@ -816,19 +829,13 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
* the likeliness of us forgetting to init a buffer here in the future.
*/
outcurl->set.buffer_size = data->set.buffer_size;
- outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
- if(!outcurl->state.buffer)
- goto fail;
-
- outcurl->state.headerbuff = malloc(HEADERSIZE);
- if(!outcurl->state.headerbuff)
- goto fail;
- outcurl->state.headersize = HEADERSIZE;
/* copy all userdefined values */
if(dupset(outcurl, data))
goto fail;
+ Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
+
/* the connection cache is setup on demand */
outcurl->state.conn_cache = NULL;
@@ -921,7 +928,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
curl_slist_free_all(outcurl->change.cookielist);
outcurl->change.cookielist = NULL;
Curl_safefree(outcurl->state.buffer);
- Curl_safefree(outcurl->state.headerbuff);
+ Curl_dyn_free(&outcurl->state.headerb);
Curl_safefree(outcurl->change.url);
Curl_safefree(outcurl->change.referer);
Curl_freeset(outcurl);
@@ -937,8 +944,6 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
*/
void curl_easy_reset(struct Curl_easy *data)
{
- long old_buffer_size = data->set.buffer_size;
-
Curl_free_request_state(data);
/* zero out UserDefined data: */
@@ -962,18 +967,6 @@ void curl_easy_reset(struct Curl_easy *data)
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
Curl_http_auth_cleanup_digest(data);
#endif
-
- /* resize receive buffer */
- if(old_buffer_size != data->set.buffer_size) {
- char *newbuff = realloc(data->state.buffer, data->set.buffer_size + 1);
- if(!newbuff) {
- DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
- /* nothing we can do here except use the old size */
- data->set.buffer_size = old_buffer_size;
- }
- else
- data->state.buffer = newbuff;
- }
}
/*
@@ -1040,7 +1033,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
/* copy the structs to allow for immediate re-pausing */
for(i = 0; i < data->state.tempcount; i++) {
writebuf[i] = data->state.tempwrite[i];
- data->state.tempwrite[i].buf = NULL;
+ Curl_dyn_init(&data->state.tempwrite[i].b, DYN_PAUSE_BUFFER);
}
data->state.tempcount = 0;
@@ -1054,9 +1047,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
/* even if one function returns error, this loops through and frees
all buffers */
if(!result)
- result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf,
- writebuf[i].len);
- free(writebuf[i].buf);
+ result = Curl_client_write(conn, writebuf[i].type,
+ Curl_dyn_ptr(&writebuf[i].b),
+ Curl_dyn_len(&writebuf[i].b));
+ Curl_dyn_free(&writebuf[i].b);
}
/* recover previous owner of the connection */
diff --git a/libs/libcurl/src/easyif.h b/libs/libcurl/src/easyif.h
index 8a309c55b6..eda0d62e5f 100644
--- a/libs/libcurl/src/easyif.h
+++ b/libs/libcurl/src/easyif.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
diff --git a/libs/libcurl/src/escape.c b/libs/libcurl/src/escape.c
index 7121db31c2..f3c558ed0e 100644
--- a/libs/libcurl/src/escape.c
+++ b/libs/libcurl/src/escape.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -79,57 +79,42 @@ char *curl_unescape(const char *string, int length)
char *curl_easy_escape(struct Curl_easy *data, const char *string,
int inlength)
{
- size_t alloc;
- char *ns;
- char *testing_ptr = NULL;
- size_t newlen;
- size_t strindex = 0;
size_t length;
CURLcode result;
+ struct dynbuf d;
if(inlength < 0)
return NULL;
- alloc = (inlength?(size_t)inlength:strlen(string)) + 1;
- newlen = alloc;
-
- ns = malloc(alloc);
- if(!ns)
- return NULL;
+ Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH);
- length = alloc-1;
+ length = (inlength?(size_t)inlength:strlen(string));
while(length--) {
unsigned char in = *string; /* we need to treat the characters unsigned */
- if(Curl_isunreserved(in))
- /* just copy this */
- ns[strindex++] = in;
+ if(Curl_isunreserved(in)) {
+ /* append this */
+ if(Curl_dyn_addn(&d, &in, 1))
+ return NULL;
+ }
else {
/* encode it */
- newlen += 2; /* the size grows with two, since this'll become a %XX */
- if(newlen > alloc) {
- alloc *= 2;
- testing_ptr = Curl_saferealloc(ns, alloc);
- if(!testing_ptr)
- return NULL;
- ns = testing_ptr;
- }
-
+ char encoded[4];
result = Curl_convert_to_network(data, (char *)&in, 1);
if(result) {
/* Curl_convert_to_network calls failf if unsuccessful */
- free(ns);
+ Curl_dyn_free(&d);
return NULL;
}
- msnprintf(&ns[strindex], 4, "%%%02X", in);
-
- strindex += 3;
+ msnprintf(encoded, sizeof(encoded), "%%%02X", in);
+ if(Curl_dyn_add(&d, encoded))
+ return NULL;
}
string++;
}
- ns[strindex] = 0; /* terminate it */
- return ns;
+
+ return Curl_dyn_ptr(&d);
}
/*
@@ -149,12 +134,17 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
char **ostring, size_t *olen,
bool reject_ctrl)
{
- size_t alloc = (length?length:strlen(string)) + 1;
- char *ns = malloc(alloc);
+ size_t alloc;
+ char *ns;
size_t strindex = 0;
unsigned long hex;
CURLcode result = CURLE_OK;
+ DEBUGASSERT(string);
+
+ alloc = (length?length:strlen(string)) + 1;
+ ns = malloc(alloc);
+
if(!ns)
return CURLE_OUT_OF_MEMORY;
diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c
index 57ec6ad254..dfa44bc762 100644
--- a/libs/libcurl/src/formdata.c
+++ b/libs/libcurl/src/formdata.c
@@ -123,11 +123,11 @@ AddHttpPost(char *name, size_t namelength,
* parent_form_info is NULL.
*
***************************************************************************/
-static FormInfo * AddFormInfo(char *value,
- char *contenttype,
- FormInfo *parent_form_info)
+static struct FormInfo *AddFormInfo(char *value,
+ char *contenttype,
+ struct FormInfo *parent_form_info)
{
- FormInfo *form_info;
+ struct FormInfo *form_info;
form_info = calloc(1, sizeof(struct FormInfo));
if(form_info) {
if(value)
@@ -204,7 +204,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
struct curl_httppost **last_post,
va_list params)
{
- FormInfo *first_form, *current_form, *form = NULL;
+ struct FormInfo *first_form, *current_form, *form = NULL;
CURLFORMcode return_value = CURL_FORMADD_OK;
const char *prevtype = NULL;
struct curl_httppost *post = NULL;
@@ -521,7 +521,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(CURL_FORMADD_OK != return_value) {
/* On error, free allocated fields for all nodes of the FormInfo linked
list without deallocating nodes. List nodes are deallocated later on */
- FormInfo *ptr;
+ struct FormInfo *ptr;
for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
if(ptr->name_alloc) {
Curl_safefree(ptr->name);
@@ -650,7 +650,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
/* On error, free allocated fields for nodes of the FormInfo linked
list which are not already owned by the httppost linked list
without deallocating nodes. List nodes are deallocated later on */
- FormInfo *ptr;
+ struct FormInfo *ptr;
for(ptr = form; ptr != NULL; ptr = ptr->more) {
if(ptr->name_alloc) {
Curl_safefree(ptr->name);
@@ -676,7 +676,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
fields given that these have either been deallocated or are owned
now by the httppost linked list */
while(first_form) {
- FormInfo *ptr = first_form->more;
+ struct FormInfo *ptr = first_form->more;
free(first_form);
first_form = ptr;
}
diff --git a/libs/libcurl/src/formdata.h b/libs/libcurl/src/formdata.h
index cb20805f52..3766d38f2b 100644
--- a/libs/libcurl/src/formdata.h
+++ b/libs/libcurl/src/formdata.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -27,7 +27,7 @@
#ifndef CURL_DISABLE_MIME
/* used by FormAdd for temporary storage */
-typedef struct FormInfo {
+struct FormInfo {
char *name;
bool name_alloc;
size_t namelength;
@@ -45,7 +45,7 @@ typedef struct FormInfo {
char *userp; /* pointer for the read callback */
struct curl_slist *contentheader;
struct FormInfo *more;
-} FormInfo;
+};
CURLcode Curl_getformdata(struct Curl_easy *data,
curl_mimepart *,
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index 57b22ade97..175d2eea78 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.c
@@ -113,7 +113,7 @@ static CURLcode ftp_parse_url_path(struct connectdata *conn);
static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
#ifndef CURL_DISABLE_VERBOSE_STRINGS
static void ftp_pasv_verbose(struct connectdata *conn,
- Curl_addrinfo *ai,
+ struct Curl_addrinfo *ai,
char *newhost, /* ascii version */
int port);
#endif
@@ -136,7 +136,7 @@ static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks);
static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
static CURLcode ftp_doing(struct connectdata *conn,
bool *dophase_done);
-static CURLcode ftp_setup_connection(struct connectdata * conn);
+static CURLcode ftp_setup_connection(struct connectdata *conn);
static CURLcode init_wc_data(struct connectdata *conn);
static CURLcode wc_statemach(struct connectdata *conn);
@@ -221,6 +221,9 @@ static void close_secondarysocket(struct connectdata *conn)
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
}
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+#ifndef CURL_DISABLE_PROXY
+ conn->bits.proxy_ssl_connected[SECONDARYSOCKET] = FALSE;
+#endif
}
/*
@@ -291,7 +294,7 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
conn->sock[SECONDARYSOCKET] = s;
(void)curlx_nonblock(s, TRUE); /* enable non-blocking */
- conn->sock_accepted = TRUE;
+ conn->bits.sock_accepted = TRUE;
if(data->set.fsockopt) {
int error = 0;
@@ -334,7 +337,7 @@ static timediff_t ftp_timeleft_accept(struct Curl_easy *data)
now = Curl_now();
/* check if the generic timeout possibly is set shorter */
- other = Curl_timeleft(data, &now, FALSE);
+ other = Curl_timeleft(data, &now, FALSE);
if(other && (other < timeout_ms))
/* note that this also works fine for when other happens to be negative
due to it already having elapsed */
@@ -386,7 +389,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
/* Data connection could not be established, let's return */
infof(data, "There is negative response in cache while serv connect\n");
- Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ (void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
return CURLE_FTP_ACCEPT_FAILED;
}
@@ -408,7 +411,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
}
else if(result & CURL_CSELECT_IN) {
infof(data, "Ctrl conn has data while waiting for data conn\n");
- Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ (void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(ftpcode/100 > 3)
return CURLE_FTP_ACCEPT_FAILED;
@@ -632,8 +635,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
while(!*ftpcode && !result) {
/* check and reset timeout value every lap */
- time_t timeout = Curl_pp_state_timeout(pp, FALSE);
- time_t interval_ms;
+ timediff_t timeout = Curl_pp_state_timeout(pp, FALSE);
+ timediff_t interval_ms;
if(timeout <= 0) {
failf(data, "FTP response timeout");
@@ -815,6 +818,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
if(FTP_STOP == ftpc->state) {
int bits = GETSOCK_READSOCK(0);
+ bool any = FALSE;
/* if stopped and still in this state, then we're also waiting for a
connect on the secondary connection */
@@ -829,10 +833,11 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
if(conn->tempsock[i] != CURL_SOCKET_BAD) {
socks[s] = conn->tempsock[i];
bits |= GETSOCK_WRITESOCK(s++);
+ any = TRUE;
}
}
}
- else {
+ if(!any) {
socks[1] = conn->sock[SECONDARYSOCKET];
bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
}
@@ -913,7 +918,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
char myhost[MAX_IPADR_LEN + 1] = "";
struct Curl_sockaddr_storage ss;
- Curl_addrinfo *res, *ai;
+ struct Curl_addrinfo *res, *ai;
curl_socklen_t sslen;
char hbuf[NI_MAXHOST];
struct sockaddr *sa = (struct sockaddr *)&ss;
@@ -1293,7 +1298,7 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
/*
- Here's the excecutive summary on what to do:
+ Here's the executive summary on what to do:
PASV is RFC959, expect:
227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
@@ -1759,7 +1764,11 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) {
+ if(conn->bits.ipv6
+#ifndef CURL_DISABLE_PROXY
+ && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)
+#endif
+ ) {
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
failf(conn->data, "Failed EPSV attempt, exiting\n");
return CURLE_WEIRD_SERVER_REPLY;
@@ -1784,9 +1793,10 @@ static char *control_address(struct connectdata *conn)
If a proxy tunnel is used, returns the original host name instead, because
the effective control connection address is the proxy address,
not the ftp host. */
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
return conn->host.name;
-
+#endif
return conn->ip_addr_str;
}
@@ -1903,6 +1913,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_FTP_WEIRD_PASV_REPLY;
}
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy) {
/*
* This connection uses a proxy and we need to connect to the proxy again
@@ -1925,7 +1936,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_COULDNT_RESOLVE_PROXY;
}
}
- else {
+ else
+#endif
+ {
/* normal, direct, ftp connection */
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
if(rc == CURLRESOLV_PENDING)
@@ -2634,9 +2647,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
#endif
if(data->set.use_ssl &&
- (!conn->ssl[FIRSTSOCKET].use ||
- (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
- !conn->proxy_ssl[FIRSTSOCKET].use))) {
+ (!conn->ssl[FIRSTSOCKET].use
+#ifndef CURL_DISABLE_PROXY
+ || (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
+ !conn->proxy_ssl[FIRSTSOCKET].use)
+#endif
+ )) {
/* We don't have a SSL/TLS connection yet, but FTPS is
requested. Try a FTPS connection now */
@@ -3231,9 +3247,9 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
}
if(conn->ssl[SECONDARYSOCKET].use) {
- /* The secondary socket is using SSL so we must close down that part
- first before we close the socket for real */
- Curl_ssl_close(conn, SECONDARYSOCKET);
+ /* The secondary socket used SSL so we must close down that part first
+ before we close the socket for real */
+ result = Curl_ssl_shutdown(conn, SECONDARYSOCKET);
/* Note that we keep "use" set to TRUE since that (next) connection is
still requested to use SSL */
@@ -3249,7 +3265,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
* data has been transferred. This happens when doing through NATs etc that
* abandon old silent connections.
*/
- long old_time = pp->response_time;
+ timediff_t old_time = pp->response_time;
pp->response_time = 60*1000; /* give it only a minute for now */
pp->response = Curl_now(); /* timeout relative now */
@@ -3442,7 +3458,7 @@ static CURLcode ftp_nb_type(struct connectdata *conn,
#ifndef CURL_DISABLE_VERBOSE_STRINGS
static void
ftp_pasv_verbose(struct connectdata *conn,
- Curl_addrinfo *ai,
+ struct Curl_addrinfo *ai,
char *newhost, /* ascii version */
int port)
{
@@ -3500,6 +3516,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
}
}
+#ifndef CURL_DISABLE_PROXY
result = Curl_proxy_connect(conn, SECONDARYSOCKET);
if(result)
return result;
@@ -3510,7 +3527,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
Curl_connect_ongoing(conn))
return result;
-
+#endif
if(ftpc->state) {
/* already in a state so skip the initial commands.
@@ -4337,7 +4354,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
char command;
*type = 0; /* it was in the middle of the hostname */
command = Curl_raw_toupper(type[6]);
- conn->bits.type_set = TRUE;
switch(command) {
case 'A': /* ASCII mode */
diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c
index 84d9fc1c69..6d5bd5fc5b 100644
--- a/libs/libcurl/src/getinfo.c
+++ b/libs/libcurl/src/getinfo.c
@@ -198,9 +198,11 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
case CURLINFO_SSL_VERIFYRESULT:
*param_longp = data->set.ssl.certverifyresult;
break;
+#ifndef CURL_DISABLE_PROXY
case CURLINFO_PROXY_SSL_VERIFYRESULT:
*param_longp = data->set.proxy_ssl.certverifyresult;
break;
+#endif
case CURLINFO_REDIRECT_COUNT:
*param_longp = data->set.followlocation;
break;
@@ -320,7 +322,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
*param_offt = data->progress.downloaded;
break;
case CURLINFO_SPEED_DOWNLOAD_T:
- *param_offt = data->progress.dlspeed;
+ *param_offt = data->progress.dlspeed;
break;
case CURLINFO_SPEED_UPLOAD_T:
*param_offt = data->progress.ulspeed;
@@ -408,13 +410,13 @@ static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
*param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
break;
case CURLINFO_SIZE_UPLOAD:
- *param_doublep = (double)data->progress.uploaded;
+ *param_doublep = (double)data->progress.uploaded;
break;
case CURLINFO_SIZE_DOWNLOAD:
*param_doublep = (double)data->progress.downloaded;
break;
case CURLINFO_SPEED_DOWNLOAD:
- *param_doublep = (double)data->progress.dlspeed;
+ *param_doublep = (double)data->progress.dlspeed;
break;
case CURLINFO_SPEED_UPLOAD:
*param_doublep = (double)data->progress.ulspeed;
diff --git a/libs/libcurl/src/hmac.c b/libs/libcurl/src/hmac.c
index ae68827bea..e4fea8a507 100644
--- a/libs/libcurl/src/hmac.c
+++ b/libs/libcurl/src/hmac.c
@@ -48,13 +48,13 @@ static const unsigned char hmac_opad = 0x5C;
-HMAC_context *
-Curl_HMAC_init(const HMAC_params * hashparams,
+struct HMAC_context *
+Curl_HMAC_init(const struct HMAC_params *hashparams,
const unsigned char *key,
unsigned int keylen)
{
size_t i;
- HMAC_context *ctxt;
+ struct HMAC_context *ctxt;
unsigned char *hkey;
unsigned char b;
@@ -101,7 +101,7 @@ Curl_HMAC_init(const HMAC_params * hashparams,
return ctxt;
}
-int Curl_HMAC_update(HMAC_context * ctxt,
+int Curl_HMAC_update(struct HMAC_context *ctxt,
const unsigned char *data,
unsigned int len)
{
@@ -111,9 +111,9 @@ int Curl_HMAC_update(HMAC_context * ctxt,
}
-int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
+int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *result)
{
- const HMAC_params * hashparams = ctxt->hmac_hash;
+ const struct HMAC_params *hashparams = ctxt->hmac_hash;
/* Do not get result if called with a null parameter: only release
storage. */
@@ -147,12 +147,13 @@ int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_hmacit(const HMAC_params *hashparams,
+CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
const unsigned char *key, const size_t keylen,
const unsigned char *data, const size_t datalen,
unsigned char *output)
{
- HMAC_context *ctxt = Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
+ struct HMAC_context *ctxt =
+ Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
if(!ctxt)
return CURLE_OUT_OF_MEMORY;
diff --git a/libs/libcurl/src/hostasyn.c b/libs/libcurl/src/hostasyn.c
index 99d872b352..ed9190f4c6 100644
--- a/libs/libcurl/src/hostasyn.c
+++ b/libs/libcurl/src/hostasyn.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -117,10 +117,10 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
* name resolve layers (selected at build-time). They all take this same set
* of arguments
*/
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
}
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index c0feb79fb3..dd5916e338 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -120,7 +120,7 @@ static void freednsentry(void *freethis);
/*
* Return # of addresses in a Curl_addrinfo struct
*/
-int Curl_num_addresses(const Curl_addrinfo *addr)
+int Curl_num_addresses(const struct Curl_addrinfo *addr)
{
int i = 0;
while(addr) {
@@ -131,39 +131,36 @@ int Curl_num_addresses(const Curl_addrinfo *addr)
}
/*
- * Curl_printable_address() returns a printable version of the 1st address
+ * Curl_printable_address() stores a printable version of the 1st address
* given in the 'ai' argument. The result will be stored in the buf that is
* bufsize bytes big.
*
- * If the conversion fails, it returns NULL.
+ * If the conversion fails, the target buffer is empty.
*/
-const char *
-Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
+void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf,
+ size_t bufsize)
{
- const struct sockaddr_in *sa4;
- const struct in_addr *ipaddr4;
-#ifdef ENABLE_IPV6
- const struct sockaddr_in6 *sa6;
- const struct in6_addr *ipaddr6;
-#endif
+ DEBUGASSERT(bufsize);
+ buf[0] = 0;
switch(ai->ai_family) {
- case AF_INET:
- sa4 = (const void *)ai->ai_addr;
- ipaddr4 = &sa4->sin_addr;
- return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
- bufsize);
+ case AF_INET: {
+ const struct sockaddr_in *sa4 = (const void *)ai->ai_addr;
+ const struct in_addr *ipaddr4 = &sa4->sin_addr;
+ (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize);
+ break;
+ }
#ifdef ENABLE_IPV6
- case AF_INET6:
- sa6 = (const void *)ai->ai_addr;
- ipaddr6 = &sa6->sin6_addr;
- return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
- bufsize);
+ case AF_INET6: {
+ const struct sockaddr_in6 *sa6 = (const void *)ai->ai_addr;
+ const struct in6_addr *ipaddr6 = &sa6->sin6_addr;
+ (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize);
+ break;
+ }
#endif
- default:
- break;
+ default:
+ break;
}
- return NULL;
}
/*
@@ -337,7 +334,7 @@ Curl_fetch_addr(struct connectdata *conn,
#ifndef CURL_DISABLE_SHUFFLE_DNS
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
- Curl_addrinfo **addr);
+ struct Curl_addrinfo **addr);
/*
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
* struct by re-linking its linked list.
@@ -351,13 +348,13 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
* @unittest: 1608
*/
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
- Curl_addrinfo **addr)
+ struct Curl_addrinfo **addr)
{
CURLcode result = CURLE_OK;
const int num_addrs = Curl_num_addresses(*addr);
if(num_addrs > 1) {
- Curl_addrinfo **nodes;
+ struct Curl_addrinfo **nodes;
infof(data, "Shuffling %i addresses", num_addrs);
nodes = malloc(num_addrs*sizeof(*nodes));
@@ -376,7 +373,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
if(rnd) {
/* Fisher-Yates shuffle */
if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) {
- Curl_addrinfo *swap_tmp;
+ struct Curl_addrinfo *swap_tmp;
for(i = num_addrs - 1; i > 0; i--) {
swap_tmp = nodes[rnd[i] % (i + 1)];
nodes[rnd[i] % (i + 1)] = nodes[i];
@@ -415,7 +412,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
*/
struct Curl_dns_entry *
Curl_cache_addr(struct Curl_easy *data,
- Curl_addrinfo *addr,
+ struct Curl_addrinfo *addr,
const char *hostname,
int port)
{
@@ -495,6 +492,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
*entry = NULL;
+ conn->bits.doh = FALSE; /* default is not */
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
@@ -513,11 +511,13 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
if(!dns) {
/* The entry was not in the cache. Resolve it to IP address */
- Curl_addrinfo *addr = NULL;
+ struct Curl_addrinfo *addr = NULL;
int respwait = 0;
-#ifndef USE_RESOLVE_ON_IPS
struct in_addr in;
+#ifndef USE_RESOLVE_ON_IPS
+ const
#endif
+ bool ipnum = FALSE;
/* notify the resolver start callback */
if(data->set.resolver_start) {
@@ -544,6 +544,22 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
addr = Curl_ip2addr(AF_INET6, &in6, hostname, port);
}
#endif /* ENABLE_IPV6 */
+
+#else /* if USE_RESOLVE_ON_IPS */
+ /* First check if this is an IPv4 address string */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ ipnum = TRUE;
+#ifdef ENABLE_IPV6
+ else {
+ struct in6_addr in6;
+ /* check if this is an IPv6 address string */
+ if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+ /* This is an IPv6 address literal */
+ ipnum = TRUE;
+ }
+#endif /* ENABLE_IPV6 */
+
#endif /* !USE_RESOLVE_ON_IPS */
if(!addr) {
@@ -552,7 +568,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
if(!Curl_ipvalid(conn))
return CURLRESOLV_ERROR;
- if(allowDOH && data->set.doh) {
+ if(allowDOH && data->set.doh && !ipnum) {
addr = Curl_doh(conn, hostname, port, &respwait);
}
else {
@@ -890,7 +906,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
}
else {
struct Curl_dns_entry *dns;
- Curl_addrinfo *head = NULL, *tail = NULL;
+ struct Curl_addrinfo *head = NULL, *tail = NULL;
size_t entry_len;
char address[64];
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -924,7 +940,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
while(*end_ptr) {
size_t alen;
- Curl_addrinfo *ai;
+ struct Curl_addrinfo *ai;
addr_begin = end_ptr + 1;
addr_end = strchr(addr_begin, ',');
@@ -1047,7 +1063,7 @@ CURLcode Curl_resolv_check(struct connectdata *conn,
(void)dns;
#endif
- if(conn->data->set.doh)
+ if(conn->bits.doh)
return Curl_doh_is_resolved(conn, dns);
return Curl_resolver_is_resolved(conn, dns);
}
@@ -1056,7 +1072,7 @@ int Curl_resolv_getsock(struct connectdata *conn,
curl_socket_t *socks)
{
#ifdef CURLRES_ASYNCH
- if(conn->data->set.doh)
+ if(conn->bits.doh)
/* nothing to wait for during DOH resolve, those handles have their own
sockets */
return GETSOCK_BLANK;
@@ -1085,10 +1101,12 @@ CURLcode Curl_once_resolved(struct connectdata *conn,
result = Curl_setup_conn(conn, protocol_done);
- if(result)
- /* We're not allowed to return failure with memory left allocated
- in the connectdata struct, free those here */
- Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
-
+ if(result) {
+ struct Curl_easy *data = conn->data;
+ DEBUGASSERT(data);
+ Curl_detach_connnection(data);
+ Curl_conncache_remove_conn(data, conn, TRUE);
+ Curl_disconnect(data, conn, TRUE);
+ }
return result;
}
diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h
index baf1e5860a..374b06c855 100644
--- a/libs/libcurl/src/hostip.h
+++ b/libs/libcurl/src/hostip.h
@@ -64,7 +64,7 @@ struct connectdata;
struct curl_hash *Curl_global_host_cache_init(void);
struct Curl_dns_entry {
- Curl_addrinfo *addr;
+ struct Curl_addrinfo *addr;
/* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
time_t timestamp;
/* use-counter, use Curl_resolv_unlock to release reference */
@@ -117,10 +117,10 @@ bool Curl_ipvalid(struct connectdata *conn);
* name resolve layers (selected at build-time). They all take this same set
* of arguments
*/
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp);
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp);
/* unlock a previously resolved dns entry */
@@ -134,7 +134,7 @@ int Curl_mk_dnscache(struct curl_hash *hash);
void Curl_hostcache_prune(struct Curl_easy *data);
/* Return # of addresses in a Curl_addrinfo struct */
-int Curl_num_addresses(const Curl_addrinfo *addr);
+int Curl_num_addresses(const struct Curl_addrinfo *addr);
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
@@ -146,7 +146,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
#endif
/* IPv4 threadsafe resolve function used for synch and asynch builds */
-Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
+struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
@@ -158,15 +158,15 @@ CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
*/
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
int status,
- Curl_addrinfo *ai);
+ struct Curl_addrinfo *ai);
/*
* Curl_printable_address() returns a printable version of the 1st address
* given in the 'ip' argument. The result will be stored in the buf that is
* bufsize bytes big.
*/
-const char *Curl_printable_address(const Curl_addrinfo *ip,
- char *buf, size_t bufsize);
+void Curl_printable_address(const struct Curl_addrinfo *ip,
+ char *buf, size_t bufsize);
/*
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
@@ -187,7 +187,7 @@ Curl_fetch_addr(struct connectdata *conn,
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
*/
struct Curl_dns_entry *
-Curl_cache_addr(struct Curl_easy *data, Curl_addrinfo *addr,
+Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr,
const char *hostname, int port);
#ifndef INADDR_NONE
diff --git a/libs/libcurl/src/hostip4.c b/libs/libcurl/src/hostip4.c
index d5009a3efb..eae9416741 100644
--- a/libs/libcurl/src/hostip4.c
+++ b/libs/libcurl/src/hostip4.c
@@ -88,12 +88,12 @@ bool Curl_ipvalid(struct connectdata *conn)
* flavours have thread-safe versions of the plain gethostbyname() etc.
*
*/
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
- Curl_addrinfo *ai = NULL;
+ struct Curl_addrinfo *ai = NULL;
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)conn;
@@ -119,13 +119,13 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
* implying that only threadsafe code and function calls may be used.
*
*/
-Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
- int port)
+struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+ int port)
{
#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
int res;
#endif
- Curl_addrinfo *ai = NULL;
+ struct Curl_addrinfo *ai = NULL;
struct hostent *h = NULL;
struct hostent *buf = NULL;
diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c
index 41ff986964..11215758dd 100644
--- a/libs/libcurl/src/hostip6.c
+++ b/libs/libcurl/src/hostip6.c
@@ -103,20 +103,16 @@ bool Curl_ipvalid(struct connectdata *conn)
#if defined(CURLRES_SYNCH)
#ifdef DEBUG_ADDRINFO
-static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
+static void dump_addrinfo(struct connectdata *conn,
+ const struct Curl_addrinfo *ai)
{
printf("dump_addrinfo:\n");
for(; ai; ai = ai->ai_next) {
char buf[INET6_ADDRSTRLEN];
printf(" fam %2d, CNAME %s, ",
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
- if(Curl_printable_address(ai, buf, sizeof(buf)))
- printf("%s\n", buf);
- else {
- char buffer[STRERROR_LEN];
- printf("failed; %s\n",
- Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
- }
+ Curl_printable_address(ai, buf, sizeof(buf));
+ printf("%s\n", buf);
}
}
#else
@@ -132,13 +128,13 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
* memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*/
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
{
struct addrinfo hints;
- Curl_addrinfo *res;
+ struct Curl_addrinfo *res;
int error;
char sbuf[12];
char *sbufptr = NULL;
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index c3f7c350c4..482f9ad0a5 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -292,12 +292,16 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
char *out;
if(proxy) {
- userp = &conn->allocptr.proxyuserpwd;
+#ifndef CURL_DISABLE_PROXY
+ userp = &data->state.aptr.proxyuserpwd;
user = conn->http_proxy.user;
pwd = conn->http_proxy.passwd;
+#else
+ return CURLE_NOT_BUILT_IN;
+#endif
}
else {
- userp = &conn->allocptr.userpwd;
+ userp = &data->state.aptr.userpwd;
user = conn->user;
pwd = conn->passwd;
}
@@ -340,8 +344,9 @@ static CURLcode http_output_bearer(struct connectdata *conn)
{
char **userp;
CURLcode result = CURLE_OK;
+ struct Curl_easy *data = conn->data;
- userp = &conn->allocptr.userpwd;
+ userp = &data->state.aptr.userpwd;
free(*userp);
*userp = aprintf("Authorization: Bearer %s\r\n",
conn->data->set.str[STRING_BEARER]);
@@ -427,7 +432,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
skip this rewinding stuff */
return CURLE_OK;
- switch(data->set.httpreq) {
+ switch(data->state.httpreq) {
case HTTPREQ_GET:
case HTTPREQ_HEAD:
return CURLE_OK;
@@ -448,7 +453,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
}
else {
/* figure out how much data we are expected to send */
- switch(data->set.httpreq) {
+ switch(data->state.httpreq) {
case HTTPREQ_POST:
case HTTPREQ_PUT:
if(data->state.infilesize != -1)
@@ -578,6 +583,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
}
}
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy_user_passwd &&
((data->req.httpcode == 407) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
@@ -586,10 +592,11 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(!pickproxy)
data->state.authproblem = TRUE;
}
+#endif
if(pickhost || pickproxy) {
- if((data->set.httpreq != HTTPREQ_GET) &&
- (data->set.httpreq != HTTPREQ_HEAD) &&
+ if((data->state.httpreq != HTTPREQ_GET) &&
+ (data->state.httpreq != HTTPREQ_HEAD) &&
!conn->bits.rewindaftersend) {
result = http_perhapsrewind(conn);
if(result)
@@ -610,8 +617,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
authentication is not "done" yet and
no authentication seems to be required and
we didn't try HEAD or GET */
- if((data->set.httpreq != HTTPREQ_GET) &&
- (data->set.httpreq != HTTPREQ_HEAD)) {
+ if((data->state.httpreq != HTTPREQ_GET) &&
+ (data->state.httpreq != HTTPREQ_HEAD)) {
data->req.newurl = strdup(data->change.url); /* clone URL */
if(!data->req.newurl)
return CURLE_OUT_OF_MEMORY;
@@ -689,10 +696,13 @@ output_auth_headers(struct connectdata *conn,
#endif
if(authstatus->picked == CURLAUTH_BASIC) {
/* Basic */
- if((proxy && conn->bits.proxy_user_passwd &&
- !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
- (!proxy && conn->bits.user_passwd &&
- !Curl_checkheaders(conn, "Authorization"))) {
+ if(
+#ifndef CURL_DISABLE_PROXY
+ (proxy && conn->bits.proxy_user_passwd &&
+ !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
+#endif
+ (!proxy && conn->bits.user_passwd &&
+ !Curl_checkheaders(conn, "Authorization"))) {
auth = "Basic";
result = http_output_basic(conn, proxy);
if(result)
@@ -719,10 +729,15 @@ output_auth_headers(struct connectdata *conn,
}
if(auth) {
+#ifndef CURL_DISABLE_PROXY
infof(data, "%s auth using %s with user '%s'\n",
proxy ? "Proxy" : "Server", auth,
proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
- (conn->user ? conn->user : ""));
+ (conn->user ? conn->user : ""));
+#else
+ infof(data, "Server auth using %s with user '%s'\n",
+ auth, conn->user ? conn->user : "");
+#endif
authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
}
else
@@ -762,7 +777,10 @@ Curl_http_output_auth(struct connectdata *conn,
authhost = &data->state.authhost;
authproxy = &data->state.authproxy;
- if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
+ if(
+#ifndef CURL_DISABLE_PROXY
+ (conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
+#endif
conn->bits.user_passwd || data->set.str[STRING_BEARER])
/* continue please */;
else {
@@ -1067,8 +1085,10 @@ static int http_should_fail(struct connectdata *conn)
*/
if((httpcode == 401) && !conn->bits.user_passwd)
return TRUE;
+#ifndef CURL_DISABLE_PROXY
if((httpcode == 407) && !conn->bits.proxy_user_passwd)
return TRUE;
+#endif
return data->state.authproblem;
}
@@ -1125,49 +1145,20 @@ static size_t readmoredata(char *buffer,
return fullsize;
}
-/* ------------------------------------------------------------------------- */
-/* add_buffer functions */
-
-/*
- * Curl_add_buffer_init() sets up and returns a fine buffer struct
- */
-Curl_send_buffer *Curl_add_buffer_init(void)
-{
- return calloc(1, sizeof(Curl_send_buffer));
-}
-
-/*
- * Curl_add_buffer_free() frees all associated resources.
- */
-void Curl_add_buffer_free(Curl_send_buffer **inp)
-{
- Curl_send_buffer *in;
- if(!inp)
- return;
- in = *inp;
- if(in) { /* deal with NULL input */
- free(in->buffer);
- free(in);
- }
- *inp = NULL;
-}
-
/*
- * Curl_add_buffer_send() sends a header buffer and frees all associated
+ * Curl_buffer_send() sends a header buffer and frees all associated
* memory. Body data may be appended to the header data if desired.
*
* Returns CURLcode
*/
-CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
- struct connectdata *conn,
-
- /* add the number of sent bytes to this
- counter */
- curl_off_t *bytes_written,
-
- /* how much of the buffer contains body data */
- size_t included_body_bytes,
- int socketindex)
+CURLcode Curl_buffer_send(struct dynbuf *in,
+ struct connectdata *conn,
+ /* add the number of sent bytes to this
+ counter */
+ curl_off_t *bytes_written,
+ /* how much of the buffer contains body data */
+ size_t included_body_bytes,
+ int socketindex)
{
ssize_t amount;
CURLcode result;
@@ -1178,7 +1169,6 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
size_t sendsize;
curl_socket_t sockfd;
size_t headersize;
- Curl_send_buffer *in = *inp;
DEBUGASSERT(socketindex <= SECONDARYSOCKET);
@@ -1187,8 +1177,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
/* The looping below is required since we use non-blocking sockets, but due
to the circumstances we will just loop and try again and again etc */
- ptr = in->buffer;
- size = in->size_used;
+ ptr = Curl_dyn_ptr(in);
+ size = Curl_dyn_len(in);
headersize = size - included_body_bytes; /* the initial part that isn't body
is header */
@@ -1199,12 +1189,15 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
/* Curl_convert_to_network calls failf if unsuccessful */
if(result) {
/* conversion failed, free memory and return to the caller */
- Curl_add_buffer_free(inp);
+ Curl_dyn_free(in);
return result;
}
- if((conn->handler->flags & PROTOPT_SSL ||
- conn->http_proxy.proxytype == CURLPROXY_HTTPS)
+ if((conn->handler->flags & PROTOPT_SSL
+#ifndef CURL_DISABLE_PROXY
+ || conn->http_proxy.proxytype == CURLPROXY_HTTPS
+#endif
+ )
&& conn->httpversion != 20) {
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
when we speak HTTPS, as if only a fraction of it is sent now, this data
@@ -1223,7 +1216,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
result = Curl_get_upload_buffer(data);
if(result) {
/* malloc failed, free memory and return to the caller */
- Curl_add_buffer_free(&in);
+ Curl_dyn_free(in);
return result;
}
memcpy(data->state.ulbuf, ptr, sendsize);
@@ -1286,7 +1279,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
size -= amount;
- ptr = in->buffer + amount;
+ ptr = Curl_dyn_ptr(in) + amount;
/* backup the currently set pointers */
http->backup.fread_func = data->state.fread_func;
@@ -1300,7 +1293,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
http->postdata = ptr;
http->postsize = (curl_off_t)size;
- http->send_buffer = in;
+ http->send_buffer = *in; /* copy the whole struct */
http->sending = HTTPSEND_REQUEST;
return CURLE_OK;
@@ -1320,87 +1313,11 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
return CURLE_SEND_ERROR;
}
}
- Curl_add_buffer_free(&in);
+ Curl_dyn_free(in);
return result;
}
-
-/*
- * add_bufferf() add the formatted input to the buffer.
- */
-CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
-{
- char *s;
- va_list ap;
- va_start(ap, fmt);
- s = vaprintf(fmt, ap); /* this allocs a new string to append */
- va_end(ap);
-
- if(s) {
- CURLcode result = Curl_add_buffer(inp, s, strlen(s));
- free(s);
- return result;
- }
- /* If we failed, we cleanup the whole buffer and return error */
- Curl_add_buffer_free(inp);
- return CURLE_OUT_OF_MEMORY;
-}
-
-/*
- * Curl_add_buffer() appends a memory chunk to the existing buffer
- */
-CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
- size_t size)
-{
- char *new_rb;
- Curl_send_buffer *in = *inp;
-
- if(~size < in->size_used) {
- /* If resulting used size of send buffer would wrap size_t, cleanup
- the whole buffer and return error. Otherwise the required buffer
- size will fit into a single allocatable memory chunk */
- Curl_add_buffer_free(inp);
- return CURLE_OUT_OF_MEMORY;
- }
-
- if(!in->buffer ||
- ((in->size_used + size) > (in->size_max - 1))) {
- /* If current buffer size isn't enough to hold the result, use a
- buffer size that doubles the required size. If this new size
- would wrap size_t, then just use the largest possible one */
- size_t new_size;
-
- if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
- (~(size * 2) < (in->size_used * 2)))
- new_size = (size_t)-1;
- else
- new_size = (in->size_used + size) * 2;
-
- if(in->buffer)
- /* we have a buffer, enlarge the existing one */
- new_rb = Curl_saferealloc(in->buffer, new_size);
- else
- /* create a new buffer */
- new_rb = malloc(new_size);
-
- if(!new_rb) {
- /* If we failed, we cleanup the whole buffer and return error */
- free(in);
- *inp = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
-
- in->buffer = new_rb;
- in->size_max = new_size;
- }
- memcpy(&in->buffer[in->size_used], inptr, size);
-
- in->size_used += size;
-
- return CURLE_OK;
-}
-
/* end of the add_buffer functions */
/* ------------------------------------------------------------------------- */
@@ -1473,6 +1390,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
function to make the re-use checks properly be able to check this bit. */
connkeep(conn, "HTTP default");
+#ifndef CURL_DISABLE_PROXY
/* the CONNECT procedure might not have been completed */
result = Curl_proxy_connect(conn, FIRSTSOCKET);
if(result)
@@ -1489,7 +1407,6 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
/* nothing else to do except wait right now - we're not done here. */
return CURLE_OK;
-#ifndef CURL_DISABLE_PROXY
if(conn->data->set.haproxyprotocol) {
/* add HAProxy PROXY protocol header */
result = add_haproxy_protocol_header(conn);
@@ -1525,7 +1442,7 @@ static int http_getsock_do(struct connectdata *conn,
static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
{
char proxy_header[128];
- Curl_send_buffer *req_buffer;
+ struct dynbuf req;
CURLcode result;
char tcp_version[5];
@@ -1546,19 +1463,14 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
conn->data->info.conn_local_port,
conn->data->info.conn_primary_port);
- req_buffer = Curl_add_buffer_init();
- if(!req_buffer)
- return CURLE_OUT_OF_MEMORY;
+ Curl_dyn_init(&req, DYN_HAXPROXY);
- result = Curl_add_bufferf(&req_buffer, proxy_header);
+ result = Curl_dyn_add(&req, proxy_header);
if(result)
return result;
- result = Curl_add_buffer_send(&req_buffer,
- conn,
- &conn->data->info.request_size,
- 0,
- FIRSTSOCKET);
+ result = Curl_buffer_send(&req, conn, &conn->data->info.request_size,
+ 0, FIRSTSOCKET);
return result;
}
@@ -1619,14 +1531,11 @@ CURLcode Curl_http_done(struct connectdata *conn,
if(!http)
return CURLE_OK;
- if(http->send_buffer) {
- Curl_add_buffer_free(&http->send_buffer);
- }
-
+ Curl_dyn_free(&http->send_buffer);
Curl_http2_done(data, premature);
Curl_quic_done(data, premature);
-
Curl_mime_cleanpart(&http->form);
+ Curl_dyn_reset(&data->state.headerb);
if(status)
return status;
@@ -1692,7 +1601,7 @@ static const char *get_http_string(const struct Curl_easy *data,
/* check and possibly add an Expect: header */
static CURLcode expect100(struct Curl_easy *data,
struct connectdata *conn,
- Curl_send_buffer *req_buffer)
+ struct dynbuf *req)
{
CURLcode result = CURLE_OK;
data->state.expect100header = FALSE; /* default to false unless it is set
@@ -1708,8 +1617,7 @@ static CURLcode expect100(struct Curl_easy *data,
Curl_compareheader(ptr, "Expect:", "100-continue");
}
else {
- result = Curl_add_bufferf(&req_buffer,
- "Expect: 100-continue\r\n");
+ result = Curl_dyn_add(req, "Expect: 100-continue\r\n");
if(!result)
data->state.expect100header = TRUE;
}
@@ -1728,7 +1636,7 @@ enum proxy_use {
will return an error code if one of the headers is
not formatted correctly */
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
- Curl_send_buffer **buffer,
+ struct dynbuf *b,
struct Curl_easy *handle)
{
char *ptr = NULL;
@@ -1754,8 +1662,10 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
/* only add correctly formatted trailers */
ptr = strchr(trailers->data, ':');
if(ptr && *(ptr + 1) == ' ') {
- result = Curl_add_bufferf(buffer, "%s%s", trailers->data,
- endofline_native);
+ result = Curl_dyn_add(b, trailers->data);
+ if(result)
+ return result;
+ result = Curl_dyn_add(b, endofline_native);
if(result)
return result;
}
@@ -1763,14 +1673,13 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
infof(handle, "Malformatted trailing header ! Skipping trailer.");
trailers = trailers->next;
}
- result = Curl_add_buffer(buffer, endofline_network,
- strlen(endofline_network));
+ result = Curl_dyn_add(b, endofline_network);
return result;
}
CURLcode Curl_add_custom_headers(struct connectdata *conn,
bool is_connect,
- Curl_send_buffer *req_buffer)
+ struct dynbuf *req)
{
char *ptr;
struct curl_slist *h[2];
@@ -1779,6 +1688,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
struct Curl_easy *data = conn->data;
int i;
+#ifndef CURL_DISABLE_PROXY
enum proxy_use proxy;
if(is_connect)
@@ -1805,6 +1715,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
h[0] = data->set.headers;
break;
}
+#else
+ (void)is_connect;
+ h[0] = data->set.headers;
+#endif
/* loop through one or two lists */
for(i = 0; i < numlists; i++) {
@@ -1832,7 +1746,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
/* copy the source */
semicolonp = strdup(headers->data);
if(!semicolonp) {
- Curl_add_buffer_free(&req_buffer);
+ Curl_dyn_free(req);
return CURLE_OUT_OF_MEMORY;
}
/* put a colon where the semicolon is */
@@ -1856,16 +1770,16 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
CURLcode result = CURLE_OK;
char *compare = semicolonp ? semicolonp : headers->data;
- if(conn->allocptr.host &&
+ if(data->state.aptr.host &&
/* a Host: header was sent already, don't pass on any custom Host:
header as that will produce *two* in the same request! */
checkprefix("Host:", compare))
;
- else if(data->set.httpreq == HTTPREQ_POST_FORM &&
+ else if(data->state.httpreq == HTTPREQ_POST_FORM &&
/* this header (extended by formdata.c) is sent later */
checkprefix("Content-Type:", compare))
;
- else if(data->set.httpreq == HTTPREQ_POST_MIME &&
+ else if(data->state.httpreq == HTTPREQ_POST_MIME &&
/* this header is sent later */
checkprefix("Content-Type:", compare))
;
@@ -1874,7 +1788,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
we will force length zero then */
checkprefix("Content-Length:", compare))
;
- else if(conn->allocptr.te &&
+ else if(data->state.aptr.te &&
/* when asking for Transfer-Encoding, don't pass on a custom
Connection: */
checkprefix("Connection:", compare))
@@ -1893,7 +1807,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
!strcasecompare(data->state.first_host, conn->host.name)))
;
else {
- result = Curl_add_bufferf(&req_buffer, "%s\r\n", compare);
+ result = Curl_dyn_addf(req, "%s\r\n", compare);
}
if(semicolonp)
free(semicolonp);
@@ -1910,7 +1824,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
#ifndef CURL_DISABLE_PARSEDATE
CURLcode Curl_add_timecondition(const struct connectdata *conn,
- Curl_send_buffer *req_buffer)
+ struct dynbuf *req)
{
struct Curl_easy *data = conn->data;
const struct tm *tm;
@@ -1969,17 +1883,17 @@ CURLcode Curl_add_timecondition(const struct connectdata *conn,
tm->tm_min,
tm->tm_sec);
- result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr));
+ result = Curl_dyn_add(req, datestr);
return result;
}
#else
/* disabled */
CURLcode Curl_add_timecondition(const struct connectdata *conn,
- Curl_send_buffer *req_buffer)
+ struct dynbuf *req)
{
(void)conn;
- (void)req_buffer;
+ (void)req;
return CURLE_OK;
}
#endif
@@ -2002,13 +1916,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
const char *te = ""; /* transfer-encoding */
const char *ptr;
const char *request;
- Curl_HttpReq httpreq = data->set.httpreq;
+ Curl_HttpReq httpreq = data->state.httpreq;
#if !defined(CURL_DISABLE_COOKIES)
char *addcookies = NULL;
#endif
curl_off_t included_body = 0;
const char *httpstring;
- Curl_send_buffer *req_buffer;
+ struct dynbuf req;
curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
char *altused = NULL;
@@ -2036,13 +1950,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
#ifdef USE_NGHTTP2
if(conn->data->set.httpversion ==
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
/* We don't support HTTP/2 proxies yet. Also it's debatable
whether or not this setting should apply to HTTP/2 proxies. */
infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
break;
}
-
+#endif
DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
conn->httpversion = 20;
@@ -2116,8 +2031,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
with the user-agent string specified, we erase the previously made string
here. */
if(Curl_checkheaders(conn, "User-Agent")) {
- free(conn->allocptr.uagent);
- conn->allocptr.uagent = NULL;
+ free(data->state.aptr.uagent);
+ data->state.aptr.uagent = NULL;
}
/* setup the authentication headers */
@@ -2145,14 +2060,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
else
conn->bits.authneg = FALSE;
- Curl_safefree(conn->allocptr.ref);
+ Curl_safefree(data->state.aptr.ref);
if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
- conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
- if(!conn->allocptr.ref)
+ data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+ if(!data->state.aptr.ref)
return CURLE_OUT_OF_MEMORY;
}
else
- conn->allocptr.ref = NULL;
+ data->state.aptr.ref = NULL;
#if !defined(CURL_DISABLE_COOKIES)
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
@@ -2161,15 +2076,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(!Curl_checkheaders(conn, "Accept-Encoding") &&
data->set.str[STRING_ENCODING]) {
- Curl_safefree(conn->allocptr.accept_encoding);
- conn->allocptr.accept_encoding =
+ Curl_safefree(data->state.aptr.accept_encoding);
+ data->state.aptr.accept_encoding =
aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
- if(!conn->allocptr.accept_encoding)
+ if(!data->state.aptr.accept_encoding)
return CURLE_OUT_OF_MEMORY;
}
else {
- Curl_safefree(conn->allocptr.accept_encoding);
- conn->allocptr.accept_encoding = NULL;
+ Curl_safefree(data->state.aptr.accept_encoding);
+ data->state.aptr.accept_encoding = NULL;
}
#ifdef HAVE_LIBZ
@@ -2185,7 +2100,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
char *cptr = Curl_checkheaders(conn, "Connection");
#define TE_HEADER "TE: gzip\r\n"
- Curl_safefree(conn->allocptr.te);
+ Curl_safefree(data->state.aptr.te);
if(cptr) {
cptr = Curl_copy_header_value(cptr);
@@ -2194,11 +2109,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
/* Create the (updated) Connection: header */
- conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
+ data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
free(cptr);
- if(!conn->allocptr.te)
+ if(!data->state.aptr.te)
return CURLE_OUT_OF_MEMORY;
}
#endif
@@ -2281,7 +2196,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
te = "Transfer-Encoding: chunked\r\n";
}
- Curl_safefree(conn->allocptr.host);
+ Curl_safefree(data->state.aptr.host);
ptr = Curl_checkheaders(conn, "Host");
if(ptr && (!data->state.this_is_a_follow ||
@@ -2316,19 +2231,19 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(colon)
*colon = 0; /* The host must not include an embedded port number */
}
- Curl_safefree(conn->allocptr.cookiehost);
- conn->allocptr.cookiehost = cookiehost;
+ Curl_safefree(data->state.aptr.cookiehost);
+ data->state.aptr.cookiehost = cookiehost;
}
#endif
if(strcmp("Host:", ptr)) {
- conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]);
- if(!conn->allocptr.host)
+ data->state.aptr.host = aprintf("Host:%s\r\n", &ptr[5]);
+ if(!data->state.aptr.host)
return CURLE_OUT_OF_MEMORY;
}
else
/* when clearing the header */
- conn->allocptr.host = NULL;
+ data->state.aptr.host = NULL;
}
else {
/* When building Host: headers, we must put the host name within
@@ -2340,18 +2255,18 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(conn->remote_port == PORT_HTTP)) )
/* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
the port number in the host string */
- conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+ data->state.aptr.host = aprintf("Host: %s%s%s\r\n",
conn->bits.ipv6_ip?"[":"",
host,
conn->bits.ipv6_ip?"]":"");
else
- conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
+ data->state.aptr.host = aprintf("Host: %s%s%s:%d\r\n",
conn->bits.ipv6_ip?"[":"",
host,
conn->bits.ipv6_ip?"]":"",
conn->remote_port);
- if(!conn->allocptr.host)
+ if(!data->state.aptr.host)
/* without Host: we can't make a nice request */
return CURLE_OUT_OF_MEMORY;
}
@@ -2432,7 +2347,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->set.prefer_ascii ? 'a' : 'i');
}
}
- if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
+ if(conn->bits.user_passwd)
paste_ftp_userpwd = TRUE;
}
}
@@ -2522,21 +2437,21 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
!Curl_checkheaders(conn, "Range")) {
/* if a line like this was already allocated, free the previous one */
- free(conn->allocptr.rangeline);
- conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
+ free(data->state.aptr.rangeline);
+ data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
data->state.range);
}
else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
!Curl_checkheaders(conn, "Content-Range")) {
/* if a line like this was already allocated, free the previous one */
- free(conn->allocptr.rangeline);
+ free(data->state.aptr.rangeline);
if(data->set.set_resume_from < 0) {
/* Upload resume was asked for, but we don't know the size of the
remote part so we tell the server (and act accordingly) that we
upload the whole file (again) */
- conn->allocptr.rangeline =
+ data->state.aptr.rangeline =
aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
"/%" CURL_FORMAT_CURL_OFF_T "\r\n",
data->state.infilesize - 1, data->state.infilesize);
@@ -2546,7 +2461,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* This is because "resume" was selected */
curl_off_t total_expected_size =
data->state.resume_from + data->state.infilesize;
- conn->allocptr.rangeline =
+ data->state.aptr.rangeline =
aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
"/%" CURL_FORMAT_CURL_OFF_T "\r\n",
data->state.range, total_expected_size-1,
@@ -2555,11 +2470,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
else {
/* Range was selected and then we just pass the incoming range and
append total size */
- conn->allocptr.rangeline =
+ data->state.aptr.rangeline =
aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
data->state.range, data->state.infilesize);
}
- if(!conn->allocptr.rangeline)
+ if(!data->state.aptr.rangeline)
return CURLE_OUT_OF_MEMORY;
}
}
@@ -2567,14 +2482,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
httpstring = get_http_string(data, conn);
/* initialize a dynamic send-buffer */
- req_buffer = Curl_add_buffer_init();
-
- if(!req_buffer)
- return CURLE_OUT_OF_MEMORY;
+ Curl_dyn_init(&req, DYN_HTTP_REQUEST);
/* add the main request stuff */
/* GET/HEAD/POST/PUT */
- result = Curl_add_bufferf(&req_buffer, "%s ", request);
+ result = Curl_dyn_addf(&req, "%s ", request);
if(result)
return result;
@@ -2587,21 +2499,20 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* url */
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
char *url = data->set.str[STRING_TEMP_URL];
- result = Curl_add_buffer(&req_buffer, url, strlen(url));
+ result = Curl_dyn_add(&req, url);
Curl_safefree(data->set.str[STRING_TEMP_URL]);
}
else
#endif
if(paste_ftp_userpwd)
- result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s",
- conn->user, conn->passwd,
- path + sizeof("ftp://") - 1);
+ result = Curl_dyn_addf(&req, "ftp://%s:%s@%s", conn->user, conn->passwd,
+ path + sizeof("ftp://") - 1);
else {
- result = Curl_add_buffer(&req_buffer, path, strlen(path));
+ result = Curl_dyn_add(&req, path);
if(result)
return result;
if(query)
- result = Curl_add_bufferf(&req_buffer, "?%s", query);
+ result = Curl_dyn_addf(&req, "?%s", query);
}
if(result)
return result;
@@ -2611,60 +2522,64 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
altused = aprintf("Alt-Used: %s:%d\r\n",
conn->conn_to_host.name, conn->conn_to_port);
if(!altused) {
- Curl_add_buffer_free(&req_buffer);
+ Curl_dyn_free(&req);
return CURLE_OUT_OF_MEMORY;
}
}
#endif
result =
- Curl_add_bufferf(&req_buffer,
- "%s" /* ftp typecode (;type=x) */
- " HTTP/%s\r\n" /* HTTP version */
- "%s" /* host */
- "%s" /* proxyuserpwd */
- "%s" /* userpwd */
- "%s" /* range */
- "%s" /* user agent */
- "%s" /* accept */
- "%s" /* TE: */
- "%s" /* accept-encoding */
- "%s" /* referer */
- "%s" /* Proxy-Connection */
- "%s" /* transfer-encoding */
- "%s",/* Alt-Used */
-
- ftp_typecode,
- httpstring,
- (conn->allocptr.host?conn->allocptr.host:""),
- conn->allocptr.proxyuserpwd?
- conn->allocptr.proxyuserpwd:"",
- conn->allocptr.userpwd?conn->allocptr.userpwd:"",
- (data->state.use_range && conn->allocptr.rangeline)?
- conn->allocptr.rangeline:"",
- (data->set.str[STRING_USERAGENT] &&
- *data->set.str[STRING_USERAGENT] &&
- conn->allocptr.uagent)?
- conn->allocptr.uagent:"",
- http->p_accept?http->p_accept:"",
- conn->allocptr.te?conn->allocptr.te:"",
- (data->set.str[STRING_ENCODING] &&
- *data->set.str[STRING_ENCODING] &&
- conn->allocptr.accept_encoding)?
- conn->allocptr.accept_encoding:"",
- (data->change.referer && conn->allocptr.ref)?
- conn->allocptr.ref:"" /* Referer: <data> */,
- (conn->bits.httpproxy &&
- !conn->bits.tunnel_proxy &&
- !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
- "Proxy-Connection: Keep-Alive\r\n":"",
- te,
- altused ? altused : ""
+ Curl_dyn_addf(&req,
+ "%s" /* ftp typecode (;type=x) */
+ " HTTP/%s\r\n" /* HTTP version */
+ "%s" /* host */
+ "%s" /* proxyuserpwd */
+ "%s" /* userpwd */
+ "%s" /* range */
+ "%s" /* user agent */
+ "%s" /* accept */
+ "%s" /* TE: */
+ "%s" /* accept-encoding */
+ "%s" /* referer */
+ "%s" /* Proxy-Connection */
+ "%s" /* transfer-encoding */
+ "%s",/* Alt-Used */
+
+ ftp_typecode,
+ httpstring,
+ (data->state.aptr.host?data->state.aptr.host:""),
+ data->state.aptr.proxyuserpwd?
+ data->state.aptr.proxyuserpwd:"",
+ data->state.aptr.userpwd?data->state.aptr.userpwd:"",
+ (data->state.use_range && data->state.aptr.rangeline)?
+ data->state.aptr.rangeline:"",
+ (data->set.str[STRING_USERAGENT] &&
+ *data->set.str[STRING_USERAGENT] &&
+ data->state.aptr.uagent)?
+ data->state.aptr.uagent:"",
+ http->p_accept?http->p_accept:"",
+ data->state.aptr.te?data->state.aptr.te:"",
+ (data->set.str[STRING_ENCODING] &&
+ *data->set.str[STRING_ENCODING] &&
+ data->state.aptr.accept_encoding)?
+ data->state.aptr.accept_encoding:"",
+ (data->change.referer && data->state.aptr.ref)?
+ data->state.aptr.ref:"" /* Referer: <data> */,
+#ifndef CURL_DISABLE_PROXY
+ (conn->bits.httpproxy &&
+ !conn->bits.tunnel_proxy &&
+ !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
+ "Proxy-Connection: Keep-Alive\r\n":"",
+#else
+ "",
+#endif
+ te,
+ altused ? altused : ""
);
/* clear userpwd and proxyuserpwd to avoid re-using old credentials
* from re-used connections */
- Curl_safefree(conn->allocptr.userpwd);
- Curl_safefree(conn->allocptr.proxyuserpwd);
+ Curl_safefree(data->state.aptr.userpwd);
+ Curl_safefree(data->state.aptr.proxyuserpwd);
free(altused);
if(result)
@@ -2675,7 +2590,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(data->set.httpversion == CURL_HTTP_VERSION_2)) {
/* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
over SSL */
- result = Curl_http2_request_upgrade(req_buffer, conn);
+ result = Curl_http2_request_upgrade(&req, conn);
if(result)
return result;
}
@@ -2688,8 +2603,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(data->cookies && data->state.cookie_engine) {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
co = Curl_cookie_getlist(data->cookies,
- conn->allocptr.cookiehost?
- conn->allocptr.cookiehost:host,
+ data->state.aptr.cookiehost?
+ data->state.aptr.cookiehost:host,
data->state.up.path,
(conn->handler->protocol&CURLPROTO_HTTPS)?
TRUE:FALSE);
@@ -2701,13 +2616,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
while(co) {
if(co->value) {
if(0 == count) {
- result = Curl_add_bufferf(&req_buffer, "Cookie: ");
+ result = Curl_dyn_add(&req, "Cookie: ");
if(result)
break;
}
- result = Curl_add_bufferf(&req_buffer,
- "%s%s=%s", count?"; ":"",
- co->name, co->value);
+ result = Curl_dyn_addf(&req, "%s%s=%s", count?"; ":"",
+ co->name, co->value);
if(result)
break;
count++;
@@ -2718,26 +2632,25 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
if(addcookies && !result) {
if(!count)
- result = Curl_add_bufferf(&req_buffer, "Cookie: ");
+ result = Curl_dyn_add(&req, "Cookie: ");
if(!result) {
- result = Curl_add_bufferf(&req_buffer, "%s%s", count?"; ":"",
- addcookies);
+ result = Curl_dyn_addf(&req, "%s%s", count?"; ":"", addcookies);
count++;
}
}
if(count && !result)
- result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
}
#endif
- result = Curl_add_timecondition(conn, req_buffer);
+ result = Curl_add_timecondition(conn, &req);
if(result)
return result;
- result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+ result = Curl_add_custom_headers(conn, FALSE, &req);
if(result)
return result;
@@ -2760,20 +2673,20 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if((postsize != -1) && !data->req.upload_chunky &&
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
/* only add Content-Length if not uploading chunked */
- result = Curl_add_bufferf(&req_buffer,
- "Content-Length: %" CURL_FORMAT_CURL_OFF_T
- "\r\n", postsize);
+ result = Curl_dyn_addf(&req, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+ "\r\n", postsize);
if(result)
return result;
}
if(postsize != 0) {
- result = expect100(data, conn, req_buffer);
+ result = expect100(data, conn, &req);
if(result)
return result;
}
- result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers */
+ /* end of headers */
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
@@ -2781,8 +2694,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_pgrsSetUploadSize(data, postsize);
/* this sends the buffer and frees all the buffer resources */
- result = Curl_add_buffer_send(&req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
+ result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+ FIRSTSOCKET);
if(result)
failf(data, "Failed sending PUT request");
else
@@ -2798,12 +2711,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* This is form posting using mime data. */
if(conn->bits.authneg) {
/* nothing to post! */
- result = Curl_add_bufferf(&req_buffer, "Content-Length: 0\r\n\r\n");
+ result = Curl_dyn_add(&req, "Content-Length: 0\r\n\r\n");
if(result)
return result;
- result = Curl_add_buffer_send(&req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
+ result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+ FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
else
@@ -2821,9 +2734,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
/* we allow replacing this header if not during auth negotiation,
although it isn't very wise to actually set your own */
- result = Curl_add_bufferf(&req_buffer,
- "Content-Length: %" CURL_FORMAT_CURL_OFF_T
- "\r\n", postsize);
+ result = Curl_dyn_addf(&req,
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+ "\r\n", postsize);
if(result)
return result;
}
@@ -2834,7 +2747,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
struct curl_slist *hdr;
for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
- result = Curl_add_bufferf(&req_buffer, "%s\r\n", hdr->data);
+ result = Curl_dyn_addf(&req, "%s\r\n", hdr->data);
if(result)
return result;
}
@@ -2851,7 +2764,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_compareheader(ptr, "Expect:", "100-continue");
}
else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
- result = expect100(data, conn, req_buffer);
+ result = expect100(data, conn, &req);
if(result)
return result;
}
@@ -2859,7 +2772,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->state.expect100header = FALSE;
/* make the request end in a true CRLF */
- result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
@@ -2872,8 +2785,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
http->sending = HTTPSEND_BODY;
/* this sends the buffer and frees all the buffer resources */
- result = Curl_add_buffer_send(&req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
+ result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+ FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
else
@@ -2901,17 +2814,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
/* we allow replacing this header if not during auth negotiation,
although it isn't very wise to actually set your own */
- result = Curl_add_bufferf(&req_buffer,
- "Content-Length: %" CURL_FORMAT_CURL_OFF_T
- "\r\n", postsize);
+ result = Curl_dyn_addf(&req, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+ "\r\n", postsize);
if(result)
return result;
}
if(!Curl_checkheaders(conn, "Content-Type")) {
- result = Curl_add_bufferf(&req_buffer,
- "Content-Type: application/"
- "x-www-form-urlencoded\r\n");
+ result = Curl_dyn_add(&req, "Content-Type: application/"
+ "x-www-form-urlencoded\r\n");
if(result)
return result;
}
@@ -2926,7 +2837,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_compareheader(ptr, "Expect:", "100-continue");
}
else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
- result = expect100(data, conn, req_buffer);
+ result = expect100(data, conn, &req);
if(result)
return result;
}
@@ -2947,31 +2858,32 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
is no magic limit but only set to prevent really huge POSTs to
get the data duplicated with malloc() and family. */
- result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
+ /* end of headers! */
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
if(!data->req.upload_chunky) {
/* We're not sending it 'chunked', append it to the request
already now to reduce the number if send() calls */
- result = Curl_add_buffer(&req_buffer, data->set.postfields,
- (size_t)postsize);
+ result = Curl_dyn_addn(&req, data->set.postfields,
+ (size_t)postsize);
included_body = postsize;
}
else {
if(postsize) {
/* Append the POST data chunky-style */
- result = Curl_add_bufferf(&req_buffer, "%x\r\n", (int)postsize);
+ result = Curl_dyn_addf(&req, "%x\r\n", (int)postsize);
if(!result) {
- result = Curl_add_buffer(&req_buffer, data->set.postfields,
- (size_t)postsize);
+ result = Curl_dyn_addn(&req, data->set.postfields,
+ (size_t)postsize);
if(!result)
- result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+ result = Curl_dyn_add(&req, "\r\n");
included_body = postsize + 2;
}
}
if(!result)
- result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
+ result = Curl_dyn_add(&req, "\x30\x0d\x0a\x0d\x0a");
/* 0 CR LF CR LF */
included_body += 5;
}
@@ -2993,21 +2905,22 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
- result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
+ /* end of headers! */
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
}
}
else {
- result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
+ /* end of headers! */
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
if(data->req.upload_chunky && conn->bits.authneg) {
/* Chunky upload is selected and we're negotiating auth still, send
end-of-data only */
- result = Curl_add_buffer(&req_buffer,
- "\x30\x0d\x0a\x0d\x0a", 5);
+ result = Curl_dyn_add(&req, (char *)"\x30\x0d\x0a\x0d\x0a");
/* 0 CR LF CR LF */
if(result)
return result;
@@ -3027,8 +2940,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
}
/* issue the request */
- result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size,
- (size_t)included_body, FIRSTSOCKET);
+ result = Curl_buffer_send(&req, conn, &data->info.request_size,
+ (size_t)included_body, FIRSTSOCKET);
if(result)
failf(data, "Failed sending HTTP POST request");
@@ -3038,13 +2951,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
break;
default:
- result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+ result = Curl_dyn_add(&req, "\r\n");
if(result)
return result;
/* issue the request */
- result = Curl_add_buffer_send(&req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
+ result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+ FIRSTSOCKET);
if(result)
failf(data, "Failed sending HTTP request");
@@ -3189,55 +3102,10 @@ checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
return checkhttpprefix(data, s, len);
}
-/*
- * header_append() copies a chunk of data to the end of the already received
- * header. We make sure that the full string fit in the allocated header
- * buffer, or else we enlarge it.
- */
-static CURLcode header_append(struct Curl_easy *data,
- struct SingleRequest *k,
- size_t length)
-{
- /* length is at most the size of a full read buffer, for which the upper
- bound is CURL_MAX_READ_SIZE. There is thus no chance of overflow in this
- calculation. */
- size_t newsize = k->hbuflen + length;
- if(newsize > CURL_MAX_HTTP_HEADER) {
- /* The reason to have a max limit for this is to avoid the risk of a bad
- server feeding libcurl with a never-ending header that will cause
- reallocs infinitely */
- failf(data, "Rejected %zu bytes header (max is %d)!", newsize,
- CURL_MAX_HTTP_HEADER);
- return CURLE_OUT_OF_MEMORY;
- }
- if(newsize >= data->state.headersize) {
- /* We enlarge the header buffer as it is too small */
- char *newbuff;
- size_t hbufp_index;
-
- newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2);
- hbufp_index = k->hbufp - data->state.headerbuff;
- newbuff = realloc(data->state.headerbuff, newsize);
- if(!newbuff) {
- failf(data, "Failed to alloc memory for big header!");
- return CURLE_OUT_OF_MEMORY;
- }
- data->state.headersize = newsize;
- data->state.headerbuff = newbuff;
- k->hbufp = data->state.headerbuff + hbufp_index;
- }
- memcpy(k->hbufp, k->str_start, length);
- k->hbufp += length;
- k->hbuflen += length;
- *k->hbufp = 0;
-
- return CURLE_OK;
-}
-
static void print_http_error(struct Curl_easy *data)
{
struct SingleRequest *k = &data->req;
- char *beg = k->p;
+ char *beg = Curl_dyn_ptr(&data->state.headerb);
/* make sure that data->req.p points to the HTTP status line */
if(!strncmp(beg, "HTTP", 4)) {
@@ -3275,14 +3143,17 @@ static void print_http_error(struct Curl_easy *data)
* Read any HTTP header lines from the server and pass them to the client app.
*/
CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
- struct connectdata *conn,
- ssize_t *nread,
- bool *stop_reading)
+ struct connectdata *conn,
+ ssize_t *nread,
+ bool *stop_reading)
{
CURLcode result;
struct SingleRequest *k = &data->req;
ssize_t onread = *nread;
char *ostr = k->str;
+ char *headp;
+ char *str_start;
+ char *end_ptr;
/* header line within buffer loop */
do {
@@ -3291,22 +3162,25 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
int writetype;
/* str_start is start of line within buf */
- k->str_start = k->str;
+ str_start = k->str;
/* data is in network encoding so use 0x0a instead of '\n' */
- k->end_ptr = memchr(k->str_start, 0x0a, *nread);
+ end_ptr = memchr(str_start, 0x0a, *nread);
- if(!k->end_ptr) {
+ if(!end_ptr) {
/* Not a complete header line within buffer, append the data to
the end of the headerbuff. */
- result = header_append(data, k, *nread);
+ result = Curl_dyn_addn(&data->state.headerb, str_start, *nread);
if(result)
return result;
if(!k->headerline) {
/* check if this looks like a protocol header */
- statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
- k->hbuflen);
+ statusline st =
+ checkprotoprefix(data, conn,
+ Curl_dyn_ptr(&data->state.headerb),
+ Curl_dyn_len(&data->state.headerb));
+
if(st == STATUS_BAD) {
/* this is not the beginning of a protocol first header line */
k->header = FALSE;
@@ -3324,28 +3198,26 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
/* decrease the size of the remaining (supposed) header line */
- rest_length = (k->end_ptr - k->str) + 1;
+ rest_length = (end_ptr - k->str) + 1;
*nread -= (ssize_t)rest_length;
- k->str = k->end_ptr + 1; /* move past new line */
+ k->str = end_ptr + 1; /* move past new line */
- full_length = k->str - k->str_start;
+ full_length = k->str - str_start;
- result = header_append(data, k, full_length);
+ result = Curl_dyn_addn(&data->state.headerb, str_start, full_length);
if(result)
return result;
- k->end_ptr = k->hbufp;
- k->p = data->state.headerbuff;
-
/****
- * We now have a FULL header line that p points to
+ * We now have a FULL header line in 'headerb'.
*****/
if(!k->headerline) {
/* the first read header */
- statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
- k->hbuflen);
+ statusline st = checkprotoprefix(data, conn,
+ Curl_dyn_ptr(&data->state.headerb),
+ Curl_dyn_len(&data->state.headerb));
if(st == STATUS_BAD) {
streamclose(conn, "bad HTTP: No end-of-message indicator");
/* this is not the beginning of a protocol first header line */
@@ -3368,26 +3240,27 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
- /* headers are in network encoding so
- use 0x0a and 0x0d instead of '\n' and '\r' */
- if((0x0a == *k->p) || (0x0d == *k->p)) {
+ /* headers are in network encoding so use 0x0a and 0x0d instead of '\n'
+ and '\r' */
+ headp = Curl_dyn_ptr(&data->state.headerb);
+ if((0x0a == *headp) || (0x0d == *headp)) {
size_t headerlen;
/* Zero-length header line means end of headers! */
#ifdef CURL_DOES_CONVERSIONS
- if(0x0d == *k->p) {
- *k->p = '\r'; /* replace with CR in host encoding */
- k->p++; /* pass the CR byte */
+ if(0x0d == *headp) {
+ *headp = '\r'; /* replace with CR in host encoding */
+ headp++; /* pass the CR byte */
}
- if(0x0a == *k->p) {
- *k->p = '\n'; /* replace with LF in host encoding */
- k->p++; /* pass the LF byte */
+ if(0x0a == *headp) {
+ *headp = '\n'; /* replace with LF in host encoding */
+ headp++; /* pass the LF byte */
}
#else
- if('\r' == *k->p)
- k->p++; /* pass the \r byte */
- if('\n' == *k->p)
- k->p++; /* pass the \n byte */
+ if('\r' == *headp)
+ headp++; /* pass the \r byte */
+ if('\n' == *headp)
+ headp++; /* pass the \n byte */
#endif /* CURL_DOES_CONVERSIONS */
if(100 <= k->httpcode && 199 >= k->httpcode) {
@@ -3448,7 +3321,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if((k->size == -1) && !k->chunk && !conn->bits.close &&
(conn->httpversion == 11) &&
!(conn->handler->protocol & CURLPROTO_RTSP) &&
- data->set.httpreq != HTTPREQ_HEAD) {
+ data->state.httpreq != HTTPREQ_HEAD) {
/* On HTTP 1.1, when connection is not to get closed, but no
Content-Length nor Transfer-Encoding chunked have been
received, according to RFC2616 section 4.4 point 5, we
@@ -3506,10 +3379,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
- headerlen = k->p - data->state.headerbuff;
-
+ headerlen = Curl_dyn_len(&data->state.headerb);
result = Curl_client_write(conn, writetype,
- data->state.headerbuff,
+ Curl_dyn_ptr(&data->state.headerb),
headerlen);
if(result)
return result;
@@ -3544,7 +3416,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* continue sending even if it gets discarded
*/
- switch(data->set.httpreq) {
+ switch(data->state.httpreq) {
case HTTPREQ_PUT:
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
@@ -3662,14 +3534,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
- k->str_start, headerlen);
+ str_start, headerlen);
break; /* exit header line loop */
}
- /* We continue reading headers, so reset the line-based
- header parsing variables hbufp && hbuflen */
- k->hbufp = data->state.headerbuff;
- k->hbuflen = 0;
+ /* We continue reading headers, reset the line-based header */
+ Curl_dyn_reset(&data->state.headerb);
continue;
}
@@ -3688,12 +3558,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
#define SCRATCHSIZE 21
CURLcode res;
char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
- /* We can't really convert this yet because we
- don't know if it's the 1st header line or the body.
- So we do a partial conversion into a scratch area,
- leaving the data at k->p as-is.
+ /* We can't really convert this yet because we don't know if it's the
+ 1st header line or the body. So we do a partial conversion into a
+ scratch area, leaving the data at 'headp' as-is.
*/
- strncpy(&scratch[0], k->p, SCRATCHSIZE);
+ strncpy(&scratch[0], headp, SCRATCHSIZE);
scratch[SCRATCHSIZE] = 0; /* null terminate */
res = Curl_convert_from_network(data,
&scratch[0],
@@ -3702,7 +3571,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
/* Curl_convert_from_network calls failf if unsuccessful */
return res;
#else
-#define HEADER1 k->p /* no conversion needed, just use k->p */
+#define HEADER1 headp /* no conversion needed, just use headp */
#endif /* CURL_DOES_CONVERSIONS */
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
@@ -3753,7 +3622,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
compare header line against list of aliases
*/
if(!nc) {
- if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) {
+ statusline check =
+ checkhttpprefix(data,
+ Curl_dyn_ptr(&data->state.headerb),
+ Curl_dyn_len(&data->state.headerb));
+ if(check == STATUS_DONE) {
nc = 1;
k->httpcode = 200;
conn->httpversion = 10;
@@ -3799,15 +3672,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* depending on how authentication is working. Other codes
* are definitely errors, so give up here.
*/
- if(data->state.resume_from && data->set.httpreq == HTTPREQ_GET &&
+ if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET &&
k->httpcode == 416) {
/* "Requested Range Not Satisfiable", just proceed and
pretend this is no error */
k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
}
else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
- ((k->httpcode != 401) || !conn->bits.user_passwd) &&
- ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
+ ((k->httpcode != 401) || !conn->bits.user_passwd)
+#ifndef CURL_DISABLE_PROXY
+ && ((k->httpcode != 407) || !conn->bits.proxy_user_passwd)
+#endif
+ ) {
/* serious error, go home! */
print_http_error(data);
return CURLE_HTTP_RETURNED_ERROR;
@@ -3823,9 +3699,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
else if(conn->httpversion == 20 ||
(k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
-
- /* HTTP/2 cannot blacklist multiplexing since it is a core
- functionality of the protocol */
+ /* HTTP/2 cannot avoid multiplexing since it is a core functionality
+ of the protocol */
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
}
else if(conn->httpversion >= 11 &&
@@ -3865,16 +3740,16 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
- result = Curl_convert_from_network(data, k->p, strlen(k->p));
+ result = Curl_convert_from_network(data, headp, strlen(headp));
/* Curl_convert_from_network calls failf if unsuccessful */
if(result)
return result;
/* Check for Content-Length: header lines to get size */
if(!k->http_bodyless &&
- !data->set.ignorecl && checkprefix("Content-Length:", k->p)) {
+ !data->set.ignorecl && checkprefix("Content-Length:", headp)) {
curl_off_t contentlength;
- CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength);
+ CURLofft offt = curlx_strtoofft(headp + 15, NULL, 10, &contentlength);
if(offt == CURL_OFFT_OK) {
if(data->set.max_filesize &&
@@ -3905,8 +3780,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
/* check for Content-Type: header lines to get the MIME-type */
- else if(checkprefix("Content-Type:", k->p)) {
- char *contenttype = Curl_copy_header_value(k->p);
+ else if(checkprefix("Content-Type:", headp)) {
+ char *contenttype = Curl_copy_header_value(headp);
if(!contenttype)
return CURLE_OUT_OF_MEMORY;
if(!*contenttype)
@@ -3917,10 +3792,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
data->info.contenttype = contenttype;
}
}
+#ifndef CURL_DISABLE_PROXY
else if((conn->httpversion == 10) &&
conn->bits.httpproxy &&
- Curl_compareheader(k->p,
- "Proxy-Connection:", "keep-alive")) {
+ Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
/*
* When a HTTP/1.0 reply comes when using a proxy, the
* 'Proxy-Connection: keep-alive' line tells us the
@@ -3932,8 +3807,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
else if((conn->httpversion == 11) &&
conn->bits.httpproxy &&
- Curl_compareheader(k->p,
- "Proxy-Connection:", "close")) {
+ Curl_compareheader(headp, "Proxy-Connection:", "close")) {
/*
* We get a HTTP/1.1 response from a proxy and it says it'll
* close down after this transfer.
@@ -3941,8 +3815,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
connclose(conn, "Proxy-Connection: asked to close after done");
infof(data, "HTTP/1.1 proxy connection set close!\n");
}
+#endif
else if((conn->httpversion == 10) &&
- Curl_compareheader(k->p, "Connection:", "keep-alive")) {
+ Curl_compareheader(headp, "Connection:", "keep-alive")) {
/*
* A HTTP/1.0 reply with the 'Connection: keep-alive' line
* tells us the connection will be kept alive for our
@@ -3952,7 +3827,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
connkeep(conn, "Connection keep-alive");
infof(data, "HTTP/1.0 connection set to keep alive!\n");
}
- else if(Curl_compareheader(k->p, "Connection:", "close")) {
+ else if(Curl_compareheader(headp, "Connection:", "close")) {
/*
* [RFC 2616, section 8.1.2.1]
* "Connection: close" is HTTP/1.1 language and means that
@@ -3961,7 +3836,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
*/
streamclose(conn, "Connection: close used");
}
- else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", k->p)) {
+ else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", headp)) {
/* One or more encodings. We check for chunked and/or a compression
algorithm. */
/*
@@ -3973,11 +3848,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* of chunks, and a chunk-data set to zero signals the
* end-of-chunks. */
- result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE);
+ result = Curl_build_unencoding_stack(conn, headp + 18, TRUE);
if(result)
return result;
}
- else if(!k->http_bodyless && checkprefix("Content-Encoding:", k->p) &&
+ else if(!k->http_bodyless && checkprefix("Content-Encoding:", headp) &&
data->set.str[STRING_ENCODING]) {
/*
* Process Content-Encoding. Look for the values: identity,
@@ -3986,24 +3861,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* 2616). zlib cannot handle compress. However, errors are
* handled further down when the response body is processed
*/
- result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE);
+ result = Curl_build_unencoding_stack(conn, headp + 17, FALSE);
if(result)
return result;
}
- else if(checkprefix("Retry-After:", k->p)) {
+ else if(checkprefix("Retry-After:", headp)) {
/* Retry-After = HTTP-date / delay-seconds */
curl_off_t retry_after = 0; /* zero for unknown or "now" */
- time_t date = Curl_getdate_capped(&k->p[12]);
+ time_t date = Curl_getdate_capped(&headp[12]);
if(-1 == date) {
/* not a date, try it as a decimal number */
- (void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
+ (void)curlx_strtoofft(&headp[12], NULL, 10, &retry_after);
}
else
/* convert date to number of seconds into the future */
retry_after = date - time(NULL);
data->info.retry_after = retry_after; /* store it */
}
- else if(!k->http_bodyless && checkprefix("Content-Range:", k->p)) {
+ else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) {
/* Content-Range: bytes [num]-
Content-Range: bytes: [num]-
Content-Range: [num]-
@@ -4015,7 +3890,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
The forth means the requested range was unsatisfied.
*/
- char *ptr = k->p + 14;
+ char *ptr = headp + 14;
/* Move forward until first digit or asterisk */
while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
@@ -4034,34 +3909,34 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
#if !defined(CURL_DISABLE_COOKIES)
else if(data->cookies && data->state.cookie_engine &&
- checkprefix("Set-Cookie:", k->p)) {
+ checkprefix("Set-Cookie:", headp)) {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
CURL_LOCK_ACCESS_SINGLE);
Curl_cookie_add(data,
- data->cookies, TRUE, FALSE, k->p + 11,
+ data->cookies, TRUE, FALSE, headp + 11,
/* If there is a custom-set Host: name, use it
here, or else use real peer host name. */
- conn->allocptr.cookiehost?
- conn->allocptr.cookiehost:conn->host.name,
+ data->state.aptr.cookiehost?
+ data->state.aptr.cookiehost:conn->host.name,
data->state.up.path,
(conn->handler->protocol&CURLPROTO_HTTPS)?
TRUE:FALSE);
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
#endif
- else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) &&
+ else if(!k->http_bodyless && checkprefix("Last-Modified:", headp) &&
(data->set.timecondition || data->set.get_filetime) ) {
- k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:"));
+ k->timeofdoc = Curl_getdate_capped(headp + strlen("Last-Modified:"));
if(data->set.get_filetime)
data->info.filetime = k->timeofdoc;
}
- else if((checkprefix("WWW-Authenticate:", k->p) &&
+ else if((checkprefix("WWW-Authenticate:", headp) &&
(401 == k->httpcode)) ||
- (checkprefix("Proxy-authenticate:", k->p) &&
+ (checkprefix("Proxy-authenticate:", headp) &&
(407 == k->httpcode))) {
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
- char *auth = Curl_copy_header_value(k->p);
+ char *auth = Curl_copy_header_value(headp);
if(!auth)
return CURLE_OUT_OF_MEMORY;
@@ -4073,11 +3948,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
return result;
}
#ifdef USE_SPNEGO
- else if(checkprefix("Persistent-Auth", k->p)) {
+ else if(checkprefix("Persistent-Auth", headp)) {
struct negotiatedata *negdata = &conn->negotiate;
struct auth *authp = &data->state.authhost;
if(authp->picked == CURLAUTH_NEGOTIATE) {
- char *persistentauth = Curl_copy_header_value(k->p);
+ char *persistentauth = Curl_copy_header_value(headp);
if(!persistentauth)
return CURLE_OUT_OF_MEMORY;
negdata->noauthpersist = checkprefix("false", persistentauth)?
@@ -4090,10 +3965,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
#endif
else if((k->httpcode >= 300 && k->httpcode < 400) &&
- checkprefix("Location:", k->p) &&
+ checkprefix("Location:", headp) &&
!data->req.location) {
/* this is the URL that the server advises us to use instead */
- char *location = Curl_copy_header_value(k->p);
+ char *location = Curl_copy_header_value(headp);
if(!location)
return CURLE_OUT_OF_MEMORY;
if(!*location)
@@ -4118,7 +3993,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
#ifdef USE_ALTSVC
/* If enabled, the header is incoming and this is over HTTPS */
- else if(data->asi && checkprefix("Alt-Svc:", k->p) &&
+ else if(data->asi && checkprefix("Alt-Svc:", headp) &&
((conn->handler->flags & PROTOPT_SSL) ||
#ifdef CURLDEBUG
/* allow debug builds to circumvent the HTTPS restriction */
@@ -4130,7 +4005,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
/* the ALPN of the current request */
enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
result = Curl_altsvc_parse(data, data->asi,
- &k->p[ strlen("Alt-Svc:") ],
+ &headp[ strlen("Alt-Svc:") ],
id, conn->host.name,
curlx_uitous(conn->remote_port));
if(result)
@@ -4138,7 +4013,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
#endif
else if(conn->handler->protocol & CURLPROTO_RTSP) {
- result = Curl_rtsp_parseheader(conn, k->p);
+ result = Curl_rtsp_parseheader(conn, headp);
if(result)
return result;
}
@@ -4152,18 +4027,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
writetype |= CLIENTWRITE_BODY;
if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, k->p, (size_t)k->hbuflen);
+ Curl_debug(data, CURLINFO_HEADER_IN, headp,
+ Curl_dyn_len(&data->state.headerb));
- result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
+ result = Curl_client_write(conn, writetype, headp,
+ Curl_dyn_len(&data->state.headerb));
if(result)
return result;
- data->info.header_size += (long)k->hbuflen;
- data->req.headerbytecount += (long)k->hbuflen;
+ data->info.header_size += Curl_dyn_len(&data->state.headerb);
+ data->req.headerbytecount += Curl_dyn_len(&data->state.headerb);
- /* reset hbufp pointer && hbuflen */
- k->hbufp = data->state.headerbuff;
- k->hbuflen = 0;
+ Curl_dyn_reset(&data->state.headerb);
}
while(*k->str); /* header line within buffer */
diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h
index 4c1825f60f..641bc0b93a 100644
--- a/libs/libcurl/src/http.h
+++ b/libs/libcurl/src/http.h
@@ -44,38 +44,19 @@ char *Curl_copy_header_value(const char *header);
char *Curl_checkProxyheaders(const struct connectdata *conn,
const char *thisheader);
-/* ------------------------------------------------------------------------- */
-/*
- * The add_buffer series of functions are used to build one large memory chunk
- * from repeated function invokes. Used so that the entire HTTP request can
- * be sent in one go.
- */
-struct Curl_send_buffer {
- char *buffer;
- size_t size_max;
- size_t size_used;
-};
-typedef struct Curl_send_buffer Curl_send_buffer;
-
-Curl_send_buffer *Curl_add_buffer_init(void);
-void Curl_add_buffer_free(Curl_send_buffer **inp);
-CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
- WARN_UNUSED_RESULT;
-CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
- size_t size) WARN_UNUSED_RESULT;
-CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
- struct connectdata *conn,
- curl_off_t *bytes_written,
- size_t included_body_bytes,
- int socketindex);
+CURLcode Curl_buffer_send(struct dynbuf *in,
+ struct connectdata *conn,
+ curl_off_t *bytes_written,
+ size_t included_body_bytes,
+ int socketindex);
CURLcode Curl_add_timecondition(const struct connectdata *conn,
- Curl_send_buffer *buf);
+ struct dynbuf *buf);
CURLcode Curl_add_custom_headers(struct connectdata *conn,
bool is_connect,
- Curl_send_buffer *req_buffer);
+ struct dynbuf *req_buffer);
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
- Curl_send_buffer **buffer,
+ struct dynbuf *buf,
struct Curl_easy *handle);
/* protocol-specific functions set up to be called by the main engine */
@@ -154,9 +135,9 @@ struct HTTP {
} sending;
#ifndef CURL_DISABLE_HTTP
- Curl_send_buffer *send_buffer; /* used if the request couldn't be sent in
- one chunk, points to an allocated
- send_buffer struct */
+ struct dynbuf send_buffer; /* used if the request couldn't be sent in one
+ chunk, points to an allocated send_buffer
+ struct */
#endif
#ifdef USE_NGHTTP2
/*********** for HTTP/2 we store stream-local data here *************/
@@ -164,10 +145,9 @@ struct HTTP {
bool bodystarted;
/* We store non-final and final response headers here, per-stream */
- Curl_send_buffer *header_recvbuf;
+ struct dynbuf header_recvbuf;
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
upper layer */
- Curl_send_buffer *trailer_recvbuf;
int status_code; /* HTTP status code */
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
size_t pauselen; /* the number of bytes left in data */
@@ -201,9 +181,7 @@ struct HTTP {
#ifdef USE_NGHTTP3
size_t unacked_window;
struct h3out *h3out; /* per-stream buffers for upload */
- char *overflow_buf; /* excess data received during a single Curl_read */
- size_t overflow_buflen; /* amount of data currently in overflow_buf */
- size_t overflow_bufsize; /* size of the overflow_buf allocation */
+ struct dynbuf overflow; /* excess data received during a single Curl_read */
#endif
};
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index 93dfbdb7d6..61990019e7 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -36,6 +36,7 @@
#include "connect.h"
#include "strtoofft.h"
#include "strdup.h"
+#include "dynbuf.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -124,8 +125,7 @@ static int http2_getsock(struct connectdata *conn,
static void http2_stream_free(struct HTTP *http)
{
if(http) {
- Curl_add_buffer_free(&http->header_recvbuf);
- Curl_add_buffer_free(&http->trailer_recvbuf);
+ Curl_dyn_free(&http->header_recvbuf);
for(; http->push_headers_used > 0; --http->push_headers_used) {
free(http->push_headers[http->push_headers_used - 1]);
}
@@ -258,16 +258,14 @@ static unsigned int http2_conncheck(struct connectdata *check,
void Curl_http2_setup_req(struct Curl_easy *data)
{
struct HTTP *http = data->req.protop;
-
- http->nread_header_recvbuf = 0;
http->bodystarted = FALSE;
http->status_code = -1;
http->pausedata = NULL;
http->pauselen = 0;
http->closed = FALSE;
http->close_handled = FALSE;
- http->mem = data->state.buffer;
- http->len = data->set.buffer_size;
+ http->mem = NULL;
+ http->len = 0;
http->memlen = 0;
}
@@ -463,15 +461,9 @@ static struct Curl_easy *duphandle(struct Curl_easy *data)
}
else {
second->req.protop = http;
- http->header_recvbuf = Curl_add_buffer_init();
- if(!http->header_recvbuf) {
- free(http);
- (void)Curl_close(&second);
- }
- else {
- Curl_http2_setup_req(second);
- second->state.stream_weight = data->state.stream_weight;
- }
+ Curl_dyn_init(&http->header_recvbuf, DYN_H2_HEADERS);
+ Curl_http2_setup_req(second);
+ second->state.stream_weight = data->state.stream_weight;
}
}
return second;
@@ -668,15 +660,17 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
stream->status_code = -1;
}
- result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
+ result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+ left = Curl_dyn_len(&stream->header_recvbuf) -
+ stream->nread_header_recvbuf;
ncopy = CURLMIN(stream->len, left);
memcpy(&stream->mem[stream->memlen],
- stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+ Curl_dyn_ptr(&stream->header_recvbuf) +
+ stream->nread_header_recvbuf,
ncopy);
stream->nread_header_recvbuf += ncopy;
@@ -852,12 +846,6 @@ static int on_begin_headers(nghttp2_session *session,
return 0;
}
- if(!stream->trailer_recvbuf) {
- stream->trailer_recvbuf = Curl_add_buffer_init();
- if(!stream->trailer_recvbuf) {
- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
- }
- }
return 0;
}
@@ -973,26 +961,19 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
}
if(stream->bodystarted) {
- /* This is trailer fields. */
- /* 4 is for ": " and "\r\n". */
- uint32_t n = (uint32_t)(namelen + valuelen + 4);
-
+ /* This is a trailer */
+ struct dynbuf trail;
H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
value));
-
- result = Curl_add_buffer(&stream->trailer_recvbuf, &n, sizeof(n));
- if(result)
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->trailer_recvbuf, name, namelen);
- if(result)
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->trailer_recvbuf, ": ", 2);
- if(result)
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->trailer_recvbuf, value, valuelen);
- if(result)
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->trailer_recvbuf, "\r\n\0", 3);
+ Curl_dyn_init(&trail, DYN_H2_TRAILER);
+ result = Curl_dyn_addf(&trail,
+ "%.*s: %.*s\r\n", namelen, name,
+ valuelen, value);
+ if(!result)
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+ Curl_dyn_ptr(&trail),
+ Curl_dyn_len(&trail));
+ Curl_dyn_free(&trail);
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -1007,14 +988,14 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
stream->status_code = decode_status_code(value, valuelen);
DEBUGASSERT(stream->status_code != -1);
- result = Curl_add_buffer(&stream->header_recvbuf, "HTTP/2 ", 7);
+ result = Curl_dyn_add(&stream->header_recvbuf, "HTTP/2 ");
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
+ result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
/* the space character after the status code is mandatory */
- result = Curl_add_buffer(&stream->header_recvbuf, " \r\n", 3);
+ result = Curl_dyn_add(&stream->header_recvbuf, " \r\n");
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
/* if we receive data for another handle, wake that up */
@@ -1029,16 +1010,16 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
/* nghttp2 guarantees that namelen > 0, and :status was already
received, and this is not pseudo-header field . */
/* convert to a HTTP1-style header */
- result = Curl_add_buffer(&stream->header_recvbuf, name, namelen);
+ result = Curl_dyn_addn(&stream->header_recvbuf, name, namelen);
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->header_recvbuf, ": ", 2);
+ result = Curl_dyn_add(&stream->header_recvbuf, ": ");
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
+ result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
+ result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
if(result)
return NGHTTP2_ERR_CALLBACK_FAILURE;
/* if we receive data for another handle, wake that up */
@@ -1139,17 +1120,14 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
/* there might be allocated resources done before this got the 'h2' pointer
setup */
- if(http->header_recvbuf) {
- Curl_add_buffer_free(&http->header_recvbuf);
- Curl_add_buffer_free(&http->trailer_recvbuf);
- if(http->push_headers) {
- /* if they weren't used and then freed before */
- for(; http->push_headers_used > 0; --http->push_headers_used) {
- free(http->push_headers[http->push_headers_used - 1]);
- }
- free(http->push_headers);
- http->push_headers = NULL;
+ Curl_dyn_free(&http->header_recvbuf);
+ if(http->push_headers) {
+ /* if they weren't used and then freed before */
+ for(; http->push_headers_used > 0; --http->push_headers_used) {
+ free(http->push_headers[http->push_headers_used - 1]);
}
+ free(http->push_headers);
+ http->push_headers = NULL;
}
if(!httpc->h2) /* not HTTP/2 ? */
@@ -1238,7 +1216,7 @@ static CURLcode http2_init(struct connectdata *conn)
/*
* Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
*/
-CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
struct connectdata *conn)
{
CURLcode result;
@@ -1257,7 +1235,7 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
httpc->local_settings_num);
if(!binlen) {
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
- Curl_add_buffer_free(&req);
+ Curl_dyn_free(req);
return CURLE_FAILED_INIT;
}
conn->proto.httpc.binlen = binlen;
@@ -1265,15 +1243,15 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
&base64, &blen);
if(result) {
- Curl_add_buffer_free(&req);
+ Curl_dyn_free(req);
return result;
}
- result = Curl_add_bufferf(&req,
- "Connection: Upgrade, HTTP2-Settings\r\n"
- "Upgrade: %s\r\n"
- "HTTP2-Settings: %s\r\n",
- NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
+ result = Curl_dyn_addf(req,
+ "Connection: Upgrade, HTTP2-Settings\r\n"
+ "Upgrade: %s\r\n"
+ "HTTP2-Settings: %s\r\n",
+ NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
free(base64);
k->upgr101 = UPGR101_REQUESTED;
@@ -1367,10 +1345,11 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
struct HTTP *stream = conn->data->req.protop;
+ struct http_conn *httpc = &conn->proto.httpc;
+ nghttp2_session *h2 = httpc->h2;
+
if(stream->upload_left) {
/* If the stream still thinks there's data left to upload. */
- struct http_conn *httpc = &conn->proto.httpc;
- nghttp2_session *h2 = httpc->h2;
stream->upload_left = 0; /* DONE! */
@@ -1380,6 +1359,23 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
(void)h2_process_pending_input(conn, httpc, &result);
}
+
+ /* If nghttp2 still has pending frames unsent */
+ if(nghttp2_session_want_write(h2)) {
+ struct Curl_easy *data = conn->data;
+ struct SingleRequest *k = &data->req;
+ int rv;
+
+ H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data));
+
+ /* re-set KEEP_SEND to make sure we are called again */
+ k->keepon |= KEEP_SEND;
+
+ /* and attempt to send the pending frames */
+ rv = h2_session_send(data, h2);
+ if(rv != 0)
+ result = CURLE_SEND_ERROR;
+ }
}
return result;
}
@@ -1388,8 +1384,6 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
struct Curl_easy *data,
struct HTTP *stream, CURLcode *err)
{
- char *trailer_pos, *trailer_end;
- CURLcode result;
struct http_conn *httpc = &conn->proto.httpc;
if(httpc->pause_stream_id == stream->stream_id) {
@@ -1432,25 +1426,6 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
return -1;
}
- if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) {
- trailer_pos = stream->trailer_recvbuf->buffer;
- trailer_end = trailer_pos + stream->trailer_recvbuf->size_used;
-
- for(; trailer_pos < trailer_end;) {
- uint32_t n;
- memcpy(&n, trailer_pos, sizeof(n));
- trailer_pos += sizeof(n);
-
- result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n);
- if(result) {
- *err = result;
- return -1;
- }
-
- trailer_pos += n + 1;
- }
- }
-
stream->close_handled = TRUE;
H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
@@ -1541,13 +1516,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
*/
if(stream->bodystarted &&
- stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
- /* If there is body data pending for this stream to return, do that */
+ stream->nread_header_recvbuf < Curl_dyn_len(&stream->header_recvbuf)) {
+ /* If there is header data pending for this stream to return, do that */
size_t left =
- stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+ Curl_dyn_len(&stream->header_recvbuf) - stream->nread_header_recvbuf;
size_t ncopy = CURLMIN(len, left);
- memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
- ncopy);
+ memcpy(mem, Curl_dyn_ptr(&stream->header_recvbuf) +
+ stream->nread_header_recvbuf, ncopy);
stream->nread_header_recvbuf += ncopy;
H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
@@ -2056,7 +2031,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
h2_pri_spec(conn->data, &pri_spec);
- switch(conn->data->set.httpreq) {
+ switch(conn->data->state.httpreq) {
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
case HTTPREQ_POST_MIME:
@@ -2127,13 +2102,11 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
struct http_conn *httpc = &conn->proto.httpc;
struct HTTP *stream = conn->data->req.protop;
+ DEBUGASSERT(conn->data->state.buffer);
+
stream->stream_id = -1;
- if(!stream->header_recvbuf) {
- stream->header_recvbuf = Curl_add_buffer_init();
- if(!stream->header_recvbuf)
- return CURLE_OUT_OF_MEMORY;
- }
+ Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
if((conn->handler == &Curl_handler_http2_ssl) ||
(conn->handler == &Curl_handler_http2))
@@ -2146,7 +2119,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
result = http2_init(conn);
if(result) {
- Curl_add_buffer_free(&stream->header_recvbuf);
+ Curl_dyn_free(&stream->header_recvbuf);
return result;
}
@@ -2154,6 +2127,8 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
stream->upload_left = 0;
stream->upload_mem = NULL;
stream->upload_len = 0;
+ stream->mem = conn->data->state.buffer;
+ stream->len = conn->data->set.buffer_size;
httpc->inbuflen = 0;
httpc->nread_inbuf = 0;
diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h
index 1989aff826..e82b212809 100644
--- a/libs/libcurl/src/http2.h
+++ b/libs/libcurl/src/http2.h
@@ -42,7 +42,7 @@ const char *Curl_http2_strerror(uint32_t err);
CURLcode Curl_http2_init(struct connectdata *conn);
void Curl_http2_init_state(struct UrlState *state);
void Curl_http2_init_userset(struct UserDefined *set);
-CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
struct connectdata *conn);
CURLcode Curl_http2_setup(struct connectdata *conn);
CURLcode Curl_http2_switched(struct connectdata *conn,
diff --git a/libs/libcurl/src/http_chunks.c b/libs/libcurl/src/http_chunks.c
index b6ffa41854..767f806c81 100644
--- a/libs/libcurl/src/http_chunks.c
+++ b/libs/libcurl/src/http_chunks.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -26,7 +26,7 @@
#include "urldata.h" /* it includes http_chunks.h */
#include "sendf.h" /* for the client write stuff */
-
+#include "dynbuf.h"
#include "content_encoding.h"
#include "http.h"
#include "non-ascii.h" /* for Curl_convert_to_network prototype */
@@ -93,6 +93,7 @@ void Curl_httpchunk_init(struct connectdata *conn)
chunk->hexindex = 0; /* start at 0 */
chunk->dataleft = 0; /* no data left yet! */
chunk->state = CHUNK_HEX; /* we get hex first! */
+ Curl_dyn_init(&conn->trailer, DYN_H1_TRAILER);
}
/*
@@ -177,7 +178,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
/* we're now expecting data to come, unless size was zero! */
if(0 == ch->datasize) {
ch->state = CHUNK_TRAILER; /* now check for trailers */
- conn->trlPos = 0;
}
else
ch->state = CHUNK_DATA;
@@ -229,32 +229,33 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
case CHUNK_TRAILER:
if((*datap == 0x0d) || (*datap == 0x0a)) {
+ char *tr = Curl_dyn_ptr(&conn->trailer);
/* this is the end of a trailer, but if the trailer was zero bytes
there was no trailer and we move on */
- if(conn->trlPos) {
- /* we allocate trailer with 3 bytes extra room to fit this */
- conn->trailer[conn->trlPos++] = 0x0d;
- conn->trailer[conn->trlPos++] = 0x0a;
- conn->trailer[conn->trlPos] = 0;
+ if(tr) {
+ size_t trlen;
+ result = Curl_dyn_add(&conn->trailer, (char *)"\x0d\x0a");
+ if(result)
+ return CHUNKE_OUT_OF_MEMORY;
+ tr = Curl_dyn_ptr(&conn->trailer);
+ trlen = Curl_dyn_len(&conn->trailer);
/* Convert to host encoding before calling Curl_client_write */
- result = Curl_convert_from_network(conn->data, conn->trailer,
- conn->trlPos);
+ result = Curl_convert_from_network(conn->data, tr, trlen);
if(result)
/* Curl_convert_from_network calls failf if unsuccessful */
/* Treat it as a bad chunk */
return CHUNKE_BAD_CHUNK;
if(!data->set.http_te_skip) {
- result = Curl_client_write(conn, CLIENTWRITE_HEADER,
- conn->trailer, conn->trlPos);
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER, tr, trlen);
if(result) {
*extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
}
- conn->trlPos = 0;
+ Curl_dyn_reset(&conn->trailer);
ch->state = CHUNK_TRAILER_CR;
if(*datap == 0x0a)
/* already on the LF */
@@ -267,25 +268,9 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
}
}
else {
- /* conn->trailer is assumed to be freed in url.c on a
- connection basis */
- if(conn->trlPos >= conn->trlMax) {
- /* we always allocate three extra bytes, just because when the full
- header has been received we append CRLF\0 */
- char *ptr;
- if(conn->trlMax) {
- conn->trlMax *= 2;
- ptr = realloc(conn->trailer, conn->trlMax + 3);
- }
- else {
- conn->trlMax = 128;
- ptr = malloc(conn->trlMax + 3);
- }
- if(!ptr)
- return CHUNKE_OUT_OF_MEMORY;
- conn->trailer = ptr;
- }
- conn->trailer[conn->trlPos++]=*datap;
+ result = Curl_dyn_addn(&conn->trailer, datap, 1);
+ if(result)
+ return CHUNKE_OUT_OF_MEMORY;
}
datap++;
length--;
diff --git a/libs/libcurl/src/http_digest.c b/libs/libcurl/src/http_digest.c
index 9616c30ed4..b06dc0d825 100644
--- a/libs/libcurl/src/http_digest.c
+++ b/libs/libcurl/src/http_digest.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -94,15 +94,19 @@ CURLcode Curl_output_digest(struct connectdata *conn,
struct auth *authp;
if(proxy) {
+#ifdef CURL_DISABLE_PROXY
+ return CURLE_NOT_BUILT_IN;
+#else
digest = &data->state.proxydigest;
- allocuserpwd = &conn->allocptr.proxyuserpwd;
+ allocuserpwd = &data->state.aptr.proxyuserpwd;
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
authp = &data->state.authproxy;
+#endif
}
else {
digest = &data->state.digest;
- allocuserpwd = &conn->allocptr.userpwd;
+ allocuserpwd = &data->state.aptr.userpwd;
userp = conn->user;
passwdp = conn->passwd;
authp = &data->state.authhost;
diff --git a/libs/libcurl/src/http_digest.h b/libs/libcurl/src/http_digest.h
index 73410ae88e..96e39a7dcc 100644
--- a/libs/libcurl/src/http_digest.h
+++ b/libs/libcurl/src/http_digest.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c
index 8e1f3bf685..0a19ec2afa 100644
--- a/libs/libcurl/src/http_negotiate.c
+++ b/libs/libcurl/src/http_negotiate.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -52,6 +52,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
curlnegotiate state;
if(proxy) {
+#ifndef CURL_DISABLE_PROXY
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
@@ -59,6 +60,9 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
host = conn->http_proxy.host.name;
neg_ctx = &conn->proxyneg;
state = conn->proxy_negotiate_state;
+#else
+ return CURLE_NOT_BUILT_IN;
+#endif
}
else {
userp = conn->user;
@@ -119,7 +123,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
struct auth *authp = proxy ? &conn->data->state.authproxy :
&conn->data->state.authhost;
curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
- &conn->http_negotiate_state;
+ &conn->http_negotiate_state;
+ struct Curl_easy *data = conn->data;
char *base64 = NULL;
size_t len = 0;
char *userp;
@@ -164,15 +169,15 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
return result;
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
- base64);
+ base64);
if(proxy) {
- Curl_safefree(conn->allocptr.proxyuserpwd);
- conn->allocptr.proxyuserpwd = userp;
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+ data->state.aptr.proxyuserpwd = userp;
}
else {
- Curl_safefree(conn->allocptr.userpwd);
- conn->allocptr.userpwd = userp;
+ Curl_safefree(data->state.aptr.userpwd);
+ data->state.aptr.userpwd = userp;
}
free(base64);
diff --git a/libs/libcurl/src/http_negotiate.h b/libs/libcurl/src/http_negotiate.h
index 4f0ac1686a..a737f6f781 100644
--- a/libs/libcurl/src/http_negotiate.h
+++ b/libs/libcurl/src/http_negotiate.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -33,6 +33,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
void Curl_http_auth_cleanup_negotiate(struct connectdata *conn);
-#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
+#else /* !CURL_DISABLE_HTTP && USE_SPNEGO */
+#define Curl_http_auth_cleanup_negotiate(x)
+#endif
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c
index 342b2424f3..cab543c757 100644
--- a/libs/libcurl/src/http_ntlm.c
+++ b/libs/libcurl/src/http_ntlm.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -131,12 +131,15 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
struct ntlmdata *ntlm;
curlntlm *state;
struct auth *authp;
+ struct Curl_easy *data = conn->data;
+
DEBUGASSERT(conn);
- DEBUGASSERT(conn->data);
+ DEBUGASSERT(data);
if(proxy) {
- allocuserpwd = &conn->allocptr.proxyuserpwd;
+#ifndef CURL_DISABLE_PROXY
+ allocuserpwd = &data->state.aptr.proxyuserpwd;
userp = conn->http_proxy.user;
passwdp = conn->http_proxy.passwd;
service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ?
@@ -145,9 +148,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
ntlm = &conn->proxyntlm;
state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
+#else
+ return CURLE_NOT_BUILT_IN;
+#endif
}
else {
- allocuserpwd = &conn->allocptr.userpwd;
+ allocuserpwd = &data->state.aptr.userpwd;
userp = conn->user;
passwdp = conn->passwd;
service = conn->data->set.str[STRING_SERVICE_NAME] ?
diff --git a/libs/libcurl/src/http_ntlm.h b/libs/libcurl/src/http_ntlm.h
index 003714dbde..3ebdf979e4 100644
--- a/libs/libcurl/src/http_ntlm.h
+++ b/libs/libcurl/src/http_ntlm.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -35,6 +35,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
void Curl_http_auth_cleanup_ntlm(struct connectdata *conn);
-#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
+#else /* !CURL_DISABLE_HTTP && USE_NTLM */
+#define Curl_http_auth_cleanup_ntlm(x)
+#endif
#endif /* HEADER_CURL_HTTP_NTLM_H */
diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c
index 75c7a60c35..f188cbfc60 100644
--- a/libs/libcurl/src/http_proxy.c
+++ b/libs/libcurl/src/http_proxy.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -72,6 +72,7 @@ static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
{
+ struct Curl_easy *data = conn->data;
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
const CURLcode result = https_proxy_connect(conn, sockindex);
if(result)
@@ -127,7 +128,7 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
conn->data->req.protop = prot_save;
if(CURLE_OK != result)
return result;
- Curl_safefree(conn->allocptr.proxyuserpwd);
+ Curl_safefree(data->state.aptr.proxyuserpwd);
#else
return CURLE_NOT_BUILT_IN;
#endif
@@ -158,15 +159,15 @@ static CURLcode connect_init(struct connectdata *conn, bool reinit)
return CURLE_OUT_OF_MEMORY;
infof(conn->data, "allocate connect buffer!\n");
conn->connect_state = s;
+ Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
}
else {
DEBUGASSERT(conn->connect_state);
s = conn->connect_state;
+ Curl_dyn_reset(&s->rcvbuf);
}
s->tunnel_state = TUNNEL_INIT;
s->keepon = TRUE;
- s->line_start = s->connect_buffer;
- s->ptr = s->line_start;
s->cl = 0;
s->close_connection = FALSE;
return CURLE_OK;
@@ -176,6 +177,7 @@ static void connect_done(struct connectdata *conn)
{
struct http_connect_state *s = conn->connect_state;
s->tunnel_state = TUNNEL_COMPLETE;
+ Curl_dyn_free(&s->rcvbuf);
infof(conn->data, "CONNECT phase completed!\n");
}
@@ -190,6 +192,8 @@ static CURLcode CONNECT(struct connectdata *conn,
CURLcode result;
curl_socket_t tunnelsocket = conn->sock[sockindex];
struct http_connect_state *s = conn->connect_state;
+ char *linep;
+ size_t perline;
#define SELECT_OK 0
#define SELECT_ERROR 1
@@ -204,7 +208,7 @@ static CURLcode CONNECT(struct connectdata *conn,
if(TUNNEL_INIT == s->tunnel_state) {
/* BEGIN CONNECT PHASE */
char *host_port;
- Curl_send_buffer *req_buffer;
+ struct dynbuf req;
infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
hostname, remote_port);
@@ -215,17 +219,12 @@ static CURLcode CONNECT(struct connectdata *conn,
free(data->req.newurl);
data->req.newurl = NULL;
- /* initialize a dynamic send-buffer */
- req_buffer = Curl_add_buffer_init();
-
- if(!req_buffer)
- return CURLE_OUT_OF_MEMORY;
-
host_port = aprintf("%s:%d", hostname, remote_port);
- if(!host_port) {
- Curl_add_buffer_free(&req_buffer);
+ if(!host_port)
return CURLE_OUT_OF_MEMORY;
- }
+
+ /* initialize a dynamic send-buffer */
+ Curl_dyn_init(&req, DYN_HTTP_REQUEST);
/* Setup the proxy-authorization header, if any */
result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
@@ -236,8 +235,8 @@ static CURLcode CONNECT(struct connectdata *conn,
char *host = NULL;
const char *proxyconn = "";
const char *useragent = "";
- const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
- "1.0" : "1.1";
+ const char *httpv =
+ (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
bool ipv6_ip = conn->bits.ipv6_ip;
char *hostheader;
@@ -248,7 +247,7 @@ static CURLcode CONNECT(struct connectdata *conn,
aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
remote_port);
if(!hostheader) {
- Curl_add_buffer_free(&req_buffer);
+ Curl_dyn_free(&req);
return CURLE_OUT_OF_MEMORY;
}
@@ -256,7 +255,7 @@ static CURLcode CONNECT(struct connectdata *conn,
host = aprintf("Host: %s\r\n", hostheader);
if(!host) {
free(hostheader);
- Curl_add_buffer_free(&req_buffer);
+ Curl_dyn_free(&req);
return CURLE_OUT_OF_MEMORY;
}
}
@@ -265,52 +264,49 @@ static CURLcode CONNECT(struct connectdata *conn,
if(!Curl_checkProxyheaders(conn, "User-Agent") &&
data->set.str[STRING_USERAGENT])
- useragent = conn->allocptr.uagent;
+ useragent = data->state.aptr.uagent;
result =
- Curl_add_bufferf(&req_buffer,
- "CONNECT %s HTTP/%s\r\n"
- "%s" /* Host: */
- "%s" /* Proxy-Authorization */
- "%s" /* User-Agent */
- "%s", /* Proxy-Connection */
- hostheader,
- http,
- host?host:"",
- conn->allocptr.proxyuserpwd?
- conn->allocptr.proxyuserpwd:"",
- useragent,
- proxyconn);
+ Curl_dyn_addf(&req,
+ "CONNECT %s HTTP/%s\r\n"
+ "%s" /* Host: */
+ "%s" /* Proxy-Authorization */
+ "%s" /* User-Agent */
+ "%s", /* Proxy-Connection */
+ hostheader,
+ httpv,
+ host?host:"",
+ data->state.aptr.proxyuserpwd?
+ data->state.aptr.proxyuserpwd:"",
+ useragent,
+ proxyconn);
if(host)
free(host);
free(hostheader);
if(!result)
- result = Curl_add_custom_headers(conn, TRUE, req_buffer);
+ result = Curl_add_custom_headers(conn, TRUE, &req);
if(!result)
/* CRLF terminate the request */
- result = Curl_add_bufferf(&req_buffer, "\r\n");
+ result = Curl_dyn_add(&req, "\r\n");
if(!result) {
/* Send the connect request to the proxy */
/* BLOCKING */
- result =
- Curl_add_buffer_send(&req_buffer, conn,
- &data->info.request_size, 0, sockindex);
+ result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+ sockindex);
}
- req_buffer = NULL;
if(result)
failf(data, "Failed sending CONNECT to proxy");
}
- Curl_add_buffer_free(&req_buffer);
+ Curl_dyn_free(&req);
if(result)
return result;
s->tunnel_state = TUNNEL_CONNECT;
- s->perline = 0;
} /* END CONNECT PHASE */
check = Curl_timeleft(data, NULL, TRUE);
@@ -330,16 +326,11 @@ static CURLcode CONNECT(struct connectdata *conn,
while(s->keepon) {
ssize_t gotbytes;
-
- /* make sure we have space to read more data */
- if(s->ptr >= &s->connect_buffer[CONNECT_BUFFER_SIZE]) {
- failf(data, "CONNECT response too large!");
- return CURLE_RECV_ERROR;
- }
+ char byte;
/* Read one byte at a time to avoid a race condition. Wait at most one
second before looping to ensure continuous pgrsUpdates. */
- result = Curl_read(conn, tunnelsocket, s->ptr, 1, &gotbytes);
+ result = Curl_read(conn, tunnelsocket, &byte, 1, &gotbytes);
if(result == CURLE_AGAIN)
/* socket buffer drained, return */
return CURLE_OK;
@@ -366,11 +357,9 @@ static CURLcode CONNECT(struct connectdata *conn,
break;
}
-
if(s->keepon > TRUE) {
/* This means we are currently ignoring a response-body */
- s->ptr = s->connect_buffer;
if(s->cl) {
/* A Content-Length based body: simply count down the counter
and make sure to break out of the loop when we're done! */
@@ -390,7 +379,7 @@ static CURLcode CONNECT(struct connectdata *conn,
/* now parse the chunked piece of data so that we can
properly tell when the stream ends */
- r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof, &extra);
+ r = Curl_httpchunk_read(conn, &byte, 1, &tookcareof, &extra);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
@@ -402,25 +391,27 @@ static CURLcode CONNECT(struct connectdata *conn,
continue;
}
- s->perline++; /* amount of bytes in this line so far */
+ if(Curl_dyn_addn(&s->rcvbuf, &byte, 1)) {
+ failf(data, "CONNECT response too large!");
+ return CURLE_RECV_ERROR;
+ }
/* if this is not the end of a header line then continue */
- if(*s->ptr != 0x0a) {
- s->ptr++;
+ if(byte != 0x0a)
continue;
- }
+
+ linep = Curl_dyn_ptr(&s->rcvbuf);
+ perline = Curl_dyn_len(&s->rcvbuf); /* amount of bytes in this line */
/* convert from the network encoding */
- result = Curl_convert_from_network(data, s->line_start,
- (size_t)s->perline);
+ result = Curl_convert_from_network(data, linep, perline);
/* Curl_convert_from_network calls failf if unsuccessful */
if(result)
return result;
/* output debug if that is requested */
if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- s->line_start, (size_t)s->perline);
+ Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
if(!data->set.suppress_connect_headers) {
/* send the header to the callback */
@@ -428,23 +419,22 @@ static CURLcode CONNECT(struct connectdata *conn,
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
- result = Curl_client_write(conn, writetype,
- s->line_start, s->perline);
+ result = Curl_client_write(conn, writetype, linep, perline);
if(result)
return result;
}
- data->info.header_size += (long)s->perline;
- data->req.headerbytecount += (long)s->perline;
+ data->info.header_size += (long)perline;
+ data->req.headerbytecount += (long)perline;
/* Newlines are CRLF, so the CR is ignored as the line isn't
really terminated until the LF comes. Treat a following CR
as end-of-headers as well.*/
- if(('\r' == s->line_start[0]) ||
- ('\n' == s->line_start[0])) {
+ if(('\r' == linep[0]) ||
+ ('\n' == linep[0])) {
/* end of response-headers from the proxy */
- s->ptr = s->connect_buffer;
+
if((407 == k->httpcode) && !data->state.authproblem) {
/* If we get a 407 response code with content length
when we have no auth problem, we must ignore the
@@ -461,21 +451,18 @@ static CURLcode CONNECT(struct connectdata *conn,
infof(data, "Ignore chunked response-body\n");
- /* We set ignorebody true here since the chunked
- decoder function will acknowledge that. Pay
- attention so that this is cleared again when this
- function returns! */
+ /* We set ignorebody true here since the chunked decoder
+ function will acknowledge that. Pay attention so that this is
+ cleared again when this function returns! */
k->ignorebody = TRUE;
- if(s->line_start[1] == '\n') {
- /* this can only be a LF if the letter at index 0
- was a CR */
- s->line_start++;
- }
+ if(linep[1] == '\n')
+ /* this can only be a LF if the letter at index 0 was a CR */
+ linep++;
- /* now parse the chunked piece of data so that we can
- properly tell when the stream ends */
- r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes,
+ /* now parse the chunked piece of data so that we can properly
+ tell when the stream ends */
+ r = Curl_httpchunk_read(conn, linep + 1, 1, &gotbytes,
&extra);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
@@ -500,14 +487,13 @@ static CURLcode CONNECT(struct connectdata *conn,
continue;
}
- s->line_start[s->perline] = 0; /* zero terminate the buffer */
- if((checkprefix("WWW-Authenticate:", s->line_start) &&
+ if((checkprefix("WWW-Authenticate:", linep) &&
(401 == k->httpcode)) ||
- (checkprefix("Proxy-authenticate:", s->line_start) &&
+ (checkprefix("Proxy-authenticate:", linep) &&
(407 == k->httpcode))) {
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
- char *auth = Curl_copy_header_value(s->line_start);
+ char *auth = Curl_copy_header_value(linep);
if(!auth)
return CURLE_OUT_OF_MEMORY;
@@ -518,7 +504,7 @@ static CURLcode CONNECT(struct connectdata *conn,
if(result)
return result;
}
- else if(checkprefix("Content-Length:", s->line_start)) {
+ else if(checkprefix("Content-Length:", linep)) {
if(k->httpcode/100 == 2) {
/* A client MUST ignore any Content-Length or Transfer-Encoding
header fields received in a successful response to CONNECT.
@@ -527,13 +513,13 @@ static CURLcode CONNECT(struct connectdata *conn,
k->httpcode);
}
else {
- (void)curlx_strtoofft(s->line_start +
+ (void)curlx_strtoofft(linep +
strlen("Content-Length:"), NULL, 10, &s->cl);
}
}
- else if(Curl_compareheader(s->line_start, "Connection:", "close"))
+ else if(Curl_compareheader(linep, "Connection:", "close"))
s->close_connection = TRUE;
- else if(checkprefix("Transfer-Encoding:", s->line_start)) {
+ else if(checkprefix("Transfer-Encoding:", linep)) {
if(k->httpcode/100 == 2) {
/* A client MUST ignore any Content-Length or Transfer-Encoding
header fields received in a successful response to CONNECT.
@@ -541,7 +527,7 @@ static CURLcode CONNECT(struct connectdata *conn,
infof(data, "Ignoring Transfer-Encoding in "
"CONNECT %03d response\n", k->httpcode);
}
- else if(Curl_compareheader(s->line_start,
+ else if(Curl_compareheader(linep,
"Transfer-Encoding:", "chunked")) {
infof(data, "CONNECT responded chunked\n");
s->chunked_encoding = TRUE;
@@ -549,19 +535,16 @@ static CURLcode CONNECT(struct connectdata *conn,
Curl_httpchunk_init(conn);
}
}
- else if(Curl_compareheader(s->line_start,
- "Proxy-Connection:", "close"))
+ else if(Curl_compareheader(linep, "Proxy-Connection:", "close"))
s->close_connection = TRUE;
- else if(2 == sscanf(s->line_start, "HTTP/1.%d %d",
+ else if(2 == sscanf(linep, "HTTP/1.%d %d",
&subversion,
&k->httpcode)) {
/* store the HTTP code from the proxy */
data->info.httpproxycode = k->httpcode;
}
- s->perline = 0; /* line starts over here */
- s->ptr = s->connect_buffer;
- s->line_start = s->ptr;
+ Curl_dyn_reset(&s->rcvbuf);
} /* while there's buffer left and loop is requested */
if(Curl_pgrsUpdate(conn))
@@ -622,6 +605,7 @@ static CURLcode CONNECT(struct connectdata *conn,
if(conn->bits.proxy_connect_closed)
/* this is not an error, just part of the connection negotiation */
return CURLE_OK;
+ Curl_dyn_free(&s->rcvbuf);
failf(data, "Received HTTP code %d from proxy after CONNECT",
data->req.httpcode);
return CURLE_RECV_ERROR;
@@ -632,8 +616,8 @@ static CURLcode CONNECT(struct connectdata *conn,
/* If a proxy-authorization header was used for the proxy, then we should
make sure that it isn't accidentally used for the document request
after we've connected. So let's free and clear it here. */
- Curl_safefree(conn->allocptr.proxyuserpwd);
- conn->allocptr.proxyuserpwd = NULL;
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+ data->state.aptr.proxyuserpwd = NULL;
data->state.authproxy.done = TRUE;
data->state.authproxy.multipass = FALSE;
@@ -643,6 +627,7 @@ static CURLcode CONNECT(struct connectdata *conn,
data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
document request */
+ Curl_dyn_free(&s->rcvbuf);
return CURLE_OK;
}
diff --git a/libs/libcurl/src/http_proxy.h b/libs/libcurl/src/http_proxy.h
index e19fa859a0..29988a6963 100644
--- a/libs/libcurl/src/http_proxy.h
+++ b/libs/libcurl/src/http_proxy.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -47,5 +47,6 @@ bool Curl_connect_ongoing(struct connectdata *conn);
#endif
void Curl_connect_free(struct Curl_easy *data);
+void Curl_connect_done(struct Curl_easy *data);
#endif /* HEADER_CURL_HTTP_PROXY_H */
diff --git a/libs/libcurl/src/idn_win32.c b/libs/libcurl/src/idn_win32.c
index 8dc300b36d..2f5850dd06 100644
--- a/libs/libcurl/src/idn_win32.c
+++ b/libs/libcurl/src/idn_win32.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -72,13 +72,13 @@ bool curl_win32_idn_to_ascii(const char *in, char **out)
{
bool success = FALSE;
- wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+ wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
if(in_w) {
wchar_t punycode[IDN_MAX_LENGTH];
int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
free(in_w);
if(chars) {
- *out = Curl_convert_wchar_to_UTF8(punycode);
+ *out = curlx_convert_wchar_to_UTF8(punycode);
if(*out)
success = TRUE;
}
@@ -91,7 +91,7 @@ bool curl_win32_ascii_to_idn(const char *in, char **out)
{
bool success = FALSE;
- wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+ wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
if(in_w) {
size_t in_len = wcslen(in_w) + 1;
wchar_t unicode[IDN_MAX_LENGTH];
@@ -99,7 +99,7 @@ bool curl_win32_ascii_to_idn(const char *in, char **out)
unicode, IDN_MAX_LENGTH);
free(in_w);
if(chars) {
- *out = Curl_convert_wchar_to_UTF8(unicode);
+ *out = curlx_convert_wchar_to_UTF8(unicode);
if(*out)
success = TRUE;
}
diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c
index 66172bddcc..14c76f08e7 100644
--- a/libs/libcurl/src/imap.c
+++ b/libs/libcurl/src/imap.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -187,7 +187,7 @@ static void imap_to_imaps(struct connectdata *conn)
conn->handler = &Curl_handler_imaps;
/* Set the connection's upgraded to TLS flag */
- conn->tls_upgraded = TRUE;
+ conn->bits.tls_upgraded = TRUE;
}
#else
#define imap_to_imaps(x) Curl_nop_stmt
@@ -1710,7 +1710,7 @@ static CURLcode imap_setup_connection(struct connectdata *conn)
return result;
/* Clear the TLS upgraded flag */
- conn->tls_upgraded = FALSE;
+ conn->bits.tls_upgraded = FALSE;
return CURLE_OK;
}
diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c
index 771edb4e98..27306580d9 100644
--- a/libs/libcurl/src/ldap.c
+++ b/libs/libcurl/src/ldap.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -75,7 +75,7 @@
/* Use our own implementation. */
-typedef struct {
+struct ldap_urldesc {
char *lud_host;
int lud_port;
#if defined(USE_WIN32_LDAP)
@@ -95,10 +95,10 @@ typedef struct {
size_t lud_attrs_dups; /* how many were dup'ed, this field is not in the
"real" struct so can only be used in code
without HAVE_LDAP_URL_PARSE defined */
-} CURL_LDAPURLDesc;
+};
#undef LDAPURLDesc
-#define LDAPURLDesc CURL_LDAPURLDesc
+#define LDAPURLDesc struct ldap_urldesc
static int _ldap_url_parse(const struct connectdata *conn,
LDAPURLDesc **ludp);
@@ -239,13 +239,13 @@ static int ldap_win_bind(struct connectdata *conn, LDAP *server,
PTCHAR inpass = NULL;
if(user && passwd && (conn->data->set.httpauth & CURLAUTH_BASIC)) {
- inuser = Curl_convert_UTF8_to_tchar((char *) user);
- inpass = Curl_convert_UTF8_to_tchar((char *) passwd);
+ inuser = curlx_convert_UTF8_to_tchar((char *) user);
+ inpass = curlx_convert_UTF8_to_tchar((char *) passwd);
rc = ldap_simple_bind_s(server, inuser, inpass);
- Curl_unicodefree(inuser);
- Curl_unicodefree(inpass);
+ curlx_unicodefree(inuser);
+ curlx_unicodefree(inpass);
}
#if defined(USE_WINDOWS_SSPI)
else {
@@ -306,7 +306,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
ldap_ssl ? "encrypted" : "cleartext");
#if defined(USE_WIN32_LDAP)
- host = Curl_convert_UTF8_to_tchar(conn->host.name);
+ host = curlx_convert_UTF8_to_tchar(conn->host.name);
if(!host) {
result = CURLE_OUT_OF_MEMORY;
@@ -517,7 +517,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
size_t name_len;
#if defined(USE_WIN32_LDAP)
TCHAR *dn = ldap_get_dn(server, entryIterator);
- name = Curl_convert_tchar_to_UTF8(dn);
+ name = curlx_convert_tchar_to_UTF8(dn);
if(!name) {
ldap_memfree(dn);
@@ -533,7 +533,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
if(result) {
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(name);
+ curlx_unicodefree(name);
#endif
ldap_memfree(dn);
@@ -544,7 +544,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
name_len);
if(result) {
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(name);
+ curlx_unicodefree(name);
#endif
ldap_memfree(dn);
@@ -554,7 +554,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
if(result) {
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(name);
+ curlx_unicodefree(name);
#endif
ldap_memfree(dn);
@@ -564,7 +564,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
dlsize += name_len + 5;
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(name);
+ curlx_unicodefree(name);
#endif
ldap_memfree(dn);
}
@@ -576,7 +576,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
BerValue **vals;
size_t attr_len;
#if defined(USE_WIN32_LDAP)
- char *attr = Curl_convert_tchar_to_UTF8(attribute);
+ char *attr = curlx_convert_tchar_to_UTF8(attribute);
if(!attr) {
if(ber)
ber_free(ber, 0);
@@ -597,7 +597,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -611,7 +611,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -624,7 +624,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -646,7 +646,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -662,7 +662,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -680,7 +680,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -696,7 +696,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
if(result) {
ldap_value_free_len(vals);
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
if(ber)
@@ -714,7 +714,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
/* Free the attribute as we are done with it */
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(attr);
+ curlx_unicodefree(attr);
#endif
ldap_memfree(attribute);
@@ -746,7 +746,7 @@ quit:
#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
#if defined(USE_WIN32_LDAP)
- Curl_unicodefree(host);
+ curlx_unicodefree(host);
#endif
/* no data to transfer */
@@ -892,10 +892,10 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
#if defined(USE_WIN32_LDAP)
/* Convert the unescaped string to a tchar */
- ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
+ ludp->lud_dn = curlx_convert_UTF8_to_tchar(unescaped);
/* Free the unescaped string as we are done with it */
- Curl_unicodefree(unescaped);
+ curlx_unicodefree(unescaped);
if(!ludp->lud_dn) {
rc = LDAP_NO_MEMORY;
@@ -960,10 +960,10 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
#if defined(USE_WIN32_LDAP)
/* Convert the unescaped string to a tchar */
- ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
+ ludp->lud_attrs[i] = curlx_convert_UTF8_to_tchar(unescaped);
/* Free the unescaped string as we are done with it */
- Curl_unicodefree(unescaped);
+ curlx_unicodefree(unescaped);
if(!ludp->lud_attrs[i]) {
free(attributes);
@@ -1027,10 +1027,10 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
#if defined(USE_WIN32_LDAP)
/* Convert the unescaped string to a tchar */
- ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
+ ludp->lud_filter = curlx_convert_UTF8_to_tchar(unescaped);
/* Free the unescaped string as we are done with it */
- Curl_unicodefree(unescaped);
+ curlx_unicodefree(unescaped);
if(!ludp->lud_filter) {
rc = LDAP_NO_MEMORY;
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index a02dfaa728..74dc728932 100644
--- a/libs/libcurl/src/libcurl.plist
+++ b/libs/libcurl/src/libcurl.plist
@@ -15,7 +15,7 @@
<string>se.haxx.curl.libcurl</string>
<key>CFBundleVersion</key>
- <string>7.70.0</string>
+ <string>7.71.0</string>
<key>CFBundleName</key>
<string>libcurl</string>
@@ -27,9 +27,9 @@
<string>????</string>
<key>CFBundleShortVersionString</key>
- <string>libcurl 7.70.0</string>
+ <string>libcurl 7.71.0</string>
<key>CFBundleGetInfoString</key>
- <string>libcurl.plist 7.70.0</string>
+ <string>libcurl.plist 7.71.0</string>
</dict>
</plist>
diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c
index 10e6fc5377..0fab52def7 100644
--- a/libs/libcurl/src/md4.c
+++ b/libs/libcurl/src/md4.c
@@ -139,10 +139,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
-typedef struct {
+struct md4_ctx {
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
-} MD4_CTX;
+};
+typedef struct md4_ctx MD4_CTX;
static void MD4_Init(MD4_CTX *ctx)
{
@@ -184,10 +185,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
-typedef struct {
+struct md4_ctx {
void *data;
unsigned long size;
-} MD4_CTX;
+};
+typedef struct md4_ctx MD4_CTX;
static void MD4_Init(MD4_CTX *ctx)
{
@@ -266,12 +268,13 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
/* Any 32-bit or wider unsigned integer data type will do */
typedef unsigned int MD4_u32plus;
-typedef struct {
+struct md4_ctx {
MD4_u32plus lo, hi;
MD4_u32plus a, b, c, d;
unsigned char buffer[64];
MD4_u32plus block[16];
-} MD4_CTX;
+};
+typedef struct md4_ctx MD4_CTX;
static void MD4_Init(MD4_CTX *ctx);
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c
index 7661587861..557a51e6c0 100644
--- a/libs/libcurl/src/md5.c
+++ b/libs/libcurl/src/md5.c
@@ -179,10 +179,11 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
-typedef struct {
+struct md5_ctx {
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
-} MD5_CTX;
+};
+typedef struct md5_ctx MD5_CTX;
static void MD5_Init(MD5_CTX *ctx)
{
@@ -261,12 +262,13 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
/* Any 32-bit or wider unsigned integer data type will do */
typedef unsigned int MD5_u32plus;
-typedef struct {
+struct md5_ctx {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
-} MD5_CTX;
+};
+typedef struct md5_ctx MD5_CTX;
static void MD5_Init(MD5_CTX *ctx);
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
@@ -528,7 +530,7 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
#endif /* CRYPTO LIBS */
-const HMAC_params Curl_HMAC_MD5[] = {
+const struct HMAC_params Curl_HMAC_MD5[] = {
{
/* Hash initialization function. */
CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
@@ -545,7 +547,7 @@ const HMAC_params Curl_HMAC_MD5[] = {
}
};
-const MD5_params Curl_DIGEST_MD5[] = {
+const struct MD5_params Curl_DIGEST_MD5[] = {
{
/* Digest initialization function */
CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
@@ -573,9 +575,9 @@ void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
MD5_Final(outbuffer, &ctx);
}
-MD5_context *Curl_MD5_init(const MD5_params *md5params)
+struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
{
- MD5_context *ctxt;
+ struct MD5_context *ctxt;
/* Create MD5 context */
ctxt = malloc(sizeof(*ctxt));
@@ -597,7 +599,7 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
return ctxt;
}
-CURLcode Curl_MD5_update(MD5_context *context,
+CURLcode Curl_MD5_update(struct MD5_context *context,
const unsigned char *data,
unsigned int len)
{
@@ -606,7 +608,7 @@ CURLcode Curl_MD5_update(MD5_context *context,
return CURLE_OK;
}
-CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result)
+CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result)
{
(*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index e13d92e948..4a87c4a3f3 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.c
@@ -71,7 +71,7 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
curl_mimepart *part);
static curl_off_t encoder_qp_size(curl_mimepart *part);
-static const mime_encoder encoders[] = {
+static const struct mime_encoder encoders[] = {
{"binary", encoder_nop_read, encoder_nop_size},
{"8bit", encoder_nop_read, encoder_nop_size},
{"7bit", encoder_7bit_read, encoder_nop_size},
@@ -269,7 +269,8 @@ static char *Curl_basename(char *path)
/* Set readback state. */
-static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr)
+static void mimesetstate(struct mime_state *state,
+ enum mimestate tok, void *ptr)
{
state->state = tok;
state->ptr = ptr;
@@ -342,7 +343,7 @@ static char *strippath(const char *fullfile)
}
/* Initialize data encoder state. */
-static void cleanup_encoder_state(mime_encoder_state *p)
+static void cleanup_encoder_state(struct mime_encoder_state *p)
{
p->pos = 0;
p->bufbeg = 0;
@@ -352,9 +353,9 @@ static void cleanup_encoder_state(mime_encoder_state *p)
/* Dummy encoder. This is used for 8bit and binary content encodings. */
static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
- curl_mimepart *part)
+ struct curl_mimepart *part)
{
- mime_encoder_state *st = &part->encstate;
+ struct mime_encoder_state *st = &part->encstate;
size_t insize = st->bufend - st->bufbeg;
(void) ateof;
@@ -382,7 +383,7 @@ static curl_off_t encoder_nop_size(curl_mimepart *part)
static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
curl_mimepart *part)
{
- mime_encoder_state *st = &part->encstate;
+ struct mime_encoder_state *st = &part->encstate;
size_t cursize = st->bufend - st->bufbeg;
(void) ateof;
@@ -408,7 +409,7 @@ static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
curl_mimepart *part)
{
- mime_encoder_state *st = &part->encstate;
+ struct mime_encoder_state *st = &part->encstate;
size_t cursize = 0;
int i;
char *ptr = buffer;
@@ -512,7 +513,7 @@ static curl_off_t encoder_base64_size(curl_mimepart *part)
* Check if a CRLF or end of data is in input buffer at current position + n.
* Return -1 if more data needed, 1 if CRLF or end of data, else 0.
*/
-static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
+static int qp_lookahead_eol(struct mime_encoder_state *st, int ateof, size_t n)
{
n += st->bufbeg;
if(n >= st->bufend && ateof)
@@ -529,7 +530,7 @@ static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
curl_mimepart *part)
{
- mime_encoder_state *st = &part->encstate;
+ struct mime_encoder_state *st = &part->encstate;
char *ptr = buffer;
size_t cursize = 0;
int softlinebreak;
@@ -594,7 +595,6 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
switch(qp_lookahead_eol(st, ateof, consumed)) {
case -1: /* Need more data. */
return cursize;
- break;
case 0: /* Not followed by a CRLF. */
softlinebreak = 1;
break;
@@ -685,7 +685,7 @@ static void mime_mem_free(void *ptr)
/* Named file callbacks. */
/* Argument is a pointer to the mime part. */
-static int mime_open_file(curl_mimepart * part)
+static int mime_open_file(curl_mimepart *part)
{
/* Open a MIMEKIND_FILE part. */
@@ -740,7 +740,7 @@ static void mime_file_free(void *ptr)
/* Argument is a pointer to the mime structure. */
/* Readback a byte string segment. */
-static size_t readback_bytes(mime_state *state,
+static size_t readback_bytes(struct mime_state *state,
char *buffer, size_t bufsize,
const char *bytes, size_t numbytes,
const char *trail)
@@ -839,7 +839,7 @@ static size_t read_part_content(curl_mimepart *part,
static size_t read_encoded_part_content(curl_mimepart *part, char *buffer,
size_t bufsize, bool *hasread)
{
- mime_encoder_state *st = &part->encstate;
+ struct mime_encoder_state *st = &part->encstate;
size_t cursize = 0;
size_t sz;
bool ateof = FALSE;
@@ -1502,7 +1502,7 @@ CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
{
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
- const mime_encoder *mep;
+ const struct mime_encoder *mep;
if(!part)
return result;
diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h
index d7f25132e3..50b7ea6b06 100644
--- a/libs/libcurl/src/mime.h
+++ b/libs/libcurl/src/mime.h
@@ -69,43 +69,43 @@ enum mimestrategy {
};
/* Content transfer encoder. */
-typedef struct {
+struct mime_encoder {
const char * name; /* Encoding name. */
size_t (*encodefunc)(char *buffer, size_t size, bool ateof,
curl_mimepart *part); /* Encoded read. */
curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */
-} mime_encoder;
+};
/* Content transfer encoder state. */
-typedef struct {
+struct mime_encoder_state {
size_t pos; /* Position on output line. */
size_t bufbeg; /* Next data index in input buffer. */
size_t bufend; /* First unused byte index in input buffer. */
char buf[ENCODING_BUFFER_SIZE]; /* Input buffer. */
-} mime_encoder_state;
+};
/* Mime readback state. */
-typedef struct {
+struct mime_state {
enum mimestate state; /* Current state token. */
void *ptr; /* State-dependent pointer. */
curl_off_t offset; /* State-dependent offset. */
-} mime_state;
+};
/* minimum buffer size for the boundary string */
#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1)
/* A mime multipart. */
-struct curl_mime_s {
+struct curl_mime {
struct Curl_easy *easy; /* The associated easy handle. */
curl_mimepart *parent; /* Parent part. */
curl_mimepart *firstpart; /* First part. */
curl_mimepart *lastpart; /* Last part. */
char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
- mime_state state; /* Current readback state. */
+ struct mime_state state; /* Current readback state. */
};
/* A mime part. */
-struct curl_mimepart_s {
+struct curl_mimepart {
struct Curl_easy *easy; /* The associated easy handle. */
curl_mime *parent; /* Parent mime structure. */
curl_mimepart *nextpart; /* Forward linked list. */
@@ -123,9 +123,9 @@ struct curl_mimepart_s {
char *name; /* Data name. */
curl_off_t datasize; /* Expected data size. */
unsigned int flags; /* Flags. */
- mime_state state; /* Current readback state. */
- const mime_encoder *encoder; /* Content data encoder. */
- mime_encoder_state encstate; /* Data encoder state. */
+ struct mime_state state; /* Current readback state. */
+ const struct mime_encoder *encoder; /* Content data encoder. */
+ struct mime_encoder_state encstate; /* Data encoder state. */
size_t lastreadstatus; /* Last read callback returned status. */
};
@@ -135,21 +135,23 @@ CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
!defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
/* Prototypes. */
-void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
-void Curl_mime_cleanpart(curl_mimepart *part);
-CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src);
-CURLcode Curl_mime_set_subparts(curl_mimepart *part,
- curl_mime *subparts, int take_ownership);
-CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
+void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy);
+void Curl_mime_cleanpart(struct curl_mimepart *part);
+CURLcode Curl_mime_duppart(struct curl_mimepart *dst,
+ const curl_mimepart *src);
+CURLcode Curl_mime_set_subparts(struct curl_mimepart *part,
+ struct curl_mime *subparts,
+ int take_ownership);
+CURLcode Curl_mime_prepare_headers(struct curl_mimepart *part,
const char *contenttype,
const char *disposition,
enum mimestrategy strategy);
-curl_off_t Curl_mime_size(curl_mimepart *part);
+curl_off_t Curl_mime_size(struct curl_mimepart *part);
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
void *instream);
-CURLcode Curl_mime_rewind(curl_mimepart *part);
+CURLcode Curl_mime_rewind(struct curl_mimepart *part);
const char *Curl_mime_contenttype(const char *filename);
-void Curl_mime_unpause(curl_mimepart *part);
+void Curl_mime_unpause(struct curl_mimepart *part);
#else
/* if disabled */
diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c
index bc0091351d..63c9d11a5a 100644
--- a/libs/libcurl/src/mprintf.c
+++ b/libs/libcurl/src/mprintf.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1999 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1999 - 2020, 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
@@ -36,6 +36,7 @@
*/
#include "curl_setup.h"
+#include "dynbuf.h"
#include <curl/mprintf.h>
#include "curl_memory.h"
@@ -145,7 +146,7 @@ enum {
FLAGS_FLOATG = 1<<19 /* %g or %G */
};
-typedef struct {
+struct va_stack {
FormatType type;
int flags;
long width; /* width OR width parameter number */
@@ -159,7 +160,7 @@ typedef struct {
} num;
double dnum;
} data;
-} va_stack_t;
+};
struct nsprintf {
char *buffer;
@@ -168,11 +169,9 @@ struct nsprintf {
};
struct asprintf {
- char *buffer; /* allocated buffer */
- size_t len; /* length of string */
- size_t alloc; /* length of alloc */
- int fail; /* (!= 0) if an alloc has failed and thus
- the output is not the complete data */
+ struct dynbuf b;
+ bool fail; /* if an alloc has failed and thus the output is not the complete
+ data */
};
static long dprintf_DollarString(char *input, char **end)
@@ -224,8 +223,8 @@ static bool dprintf_IsQualifierNoDollar(const char *fmt)
*
******************************************************************/
-static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
- va_list arglist)
+static int dprintf_Pass1(const char *format, struct va_stack *vto,
+ char **endpos, va_list arglist)
{
char *fmt = (char *)format;
int param_num = 0;
@@ -571,13 +570,11 @@ static int dprintf_formatf(
long param; /* current parameter to read */
long param_num = 0; /* parameter counter */
- va_stack_t vto[MAX_PARAMETERS];
+ struct va_stack vto[MAX_PARAMETERS];
char *endpos[MAX_PARAMETERS];
char **end;
-
char work[BUFFSIZE];
-
- va_stack_t *p;
+ struct va_stack *p;
/* 'workend' points to the final buffer byte position, but with an extra
byte as margin to avoid the (false?) warning Coverity gives us
@@ -1031,35 +1028,10 @@ static int alloc_addbyter(int output, FILE *data)
struct asprintf *infop = (struct asprintf *)data;
unsigned char outc = (unsigned char)output;
- if(!infop->buffer) {
- infop->buffer = malloc(32);
- if(!infop->buffer) {
- infop->fail = 1;
- return -1; /* fail */
- }
- infop->alloc = 32;
- infop->len = 0;
- }
- else if(infop->len + 1 >= infop->alloc) {
- char *newptr = NULL;
- size_t newsize = infop->alloc*2;
-
- /* detect wrap-around or other overflow problems */
- if(newsize > infop->alloc)
- newptr = realloc(infop->buffer, newsize);
-
- if(!newptr) {
- infop->fail = 1;
- return -1; /* fail */
- }
- infop->buffer = newptr;
- infop->alloc = newsize;
+ if(Curl_dyn_addn(&infop->b, &outc, 1)) {
+ infop->fail = 1;
+ return -1; /* fail */
}
-
- infop->buffer[ infop->len ] = outc;
-
- infop->len++;
-
return outc; /* fputc() returns like this on success */
}
@@ -1068,24 +1040,18 @@ char *curl_maprintf(const char *format, ...)
va_list ap_save; /* argument pointer */
int retcode;
struct asprintf info;
-
- info.buffer = NULL;
- info.len = 0;
- info.alloc = 0;
+ Curl_dyn_init(&info.b, DYN_APRINTF);
info.fail = 0;
va_start(ap_save, format);
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
va_end(ap_save);
if((-1 == retcode) || info.fail) {
- if(info.alloc)
- free(info.buffer);
+ Curl_dyn_free(&info.b);
return NULL;
}
- if(info.alloc) {
- info.buffer[info.len] = 0; /* we terminate this with a zero byte */
- return info.buffer;
- }
+ if(Curl_dyn_len(&info.b))
+ return Curl_dyn_ptr(&info.b);
return strdup("");
}
@@ -1093,23 +1059,16 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
{
int retcode;
struct asprintf info;
-
- info.buffer = NULL;
- info.len = 0;
- info.alloc = 0;
+ Curl_dyn_init(&info.b, DYN_APRINTF);
info.fail = 0;
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
if((-1 == retcode) || info.fail) {
- if(info.alloc)
- free(info.buffer);
+ Curl_dyn_free(&info.b);
return NULL;
}
-
- if(info.alloc) {
- info.buffer[info.len] = 0; /* we terminate this with a zero byte */
- return info.buffer;
- }
+ if(Curl_dyn_len(&info.b))
+ return Curl_dyn_ptr(&info.b);
return strdup("");
}
diff --git a/libs/libcurl/src/mqtt.c b/libs/libcurl/src/mqtt.c
index 43a3b6e532..d09aab4eef 100644
--- a/libs/libcurl/src/mqtt.c
+++ b/libs/libcurl/src/mqtt.c
@@ -591,7 +591,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
if(result)
break;
- if(conn->data->set.httpreq == HTTPREQ_POST) {
+ if(conn->data->state.httpreq == HTTPREQ_POST) {
result = mqtt_publish(conn);
if(!result) {
result = mqtt_disconnect(conn);
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index d4f031873c..b106c94951 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -79,7 +79,6 @@ static CURLMcode add_next_timeout(struct curltime now,
static CURLMcode multi_timeout(struct Curl_multi *multi,
long *timeout_ms);
static void process_pending_handles(struct Curl_multi *multi);
-static void detach_connnection(struct Curl_easy *data);
#ifdef DEBUGBUILD
static const char * const statename[]={
@@ -112,7 +111,7 @@ static void Curl_init_completed(struct Curl_easy *data)
/* Important: reset the conn pointer so that we don't point to memory
that could be freed anytime */
- detach_connnection(data);
+ Curl_detach_connnection(data);
Curl_expire_clear(data); /* stop all timers */
}
@@ -169,9 +168,11 @@ static void mstate(struct Curl_easy *data, CURLMstate state
}
#endif
- if(state == CURLM_STATE_COMPLETED)
+ if(state == CURLM_STATE_COMPLETED) {
/* changing to COMPLETED means there's one less easy handle 'alive' */
+ DEBUGASSERT(data->multi->num_alive > 0);
data->multi->num_alive--;
+ }
/* if this state has an init-function, run it */
if(finit[state])
@@ -373,6 +374,11 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->max_concurrent_streams = 100;
multi->ipv6_works = Curl_ipv6works(NULL);
+#ifdef USE_WINSOCK
+ multi->wsa_event = WSACreateEvent();
+ if(multi->wsa_event == WSA_INVALID_EVENT)
+ goto error;
+#else
#ifdef ENABLE_WAKEUP
if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
multi->wakeup_pair[0] = CURL_SOCKET_BAD;
@@ -386,6 +392,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->wakeup_pair[1] = CURL_SOCKET_BAD;
}
#endif
+#endif
return multi;
@@ -506,6 +513,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
easy handle is added */
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+ CONNCACHE_LOCK(data);
/* The closure handle only ever has default timeouts set. To improve the
state somewhat we clone the timeouts from each added handle so that the
closure handle always has the same timeouts as the most recently added
@@ -515,6 +523,7 @@ 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;
+ CONNCACHE_UNLOCK(data);
Curl_update_timer(multi);
return CURLM_OK;
@@ -589,14 +598,14 @@ static CURLcode multi_done(struct Curl_easy *data,
process_pending_handles(data->multi); /* connection / multiplex */
- CONN_LOCK(data);
- detach_connnection(data);
+ CONNCACHE_LOCK(data);
+ Curl_detach_connnection(data);
if(CONN_INUSE(conn)) {
/* Stop if still used. */
/* conn->data must not remain pointing to this transfer since it is going
away! Find another to own it! */
conn->data = conn->easyq.head->ptr;
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
DEBUGF(infof(data, "Connection still in use %zu, "
"no more multi_done now!\n",
conn->easyq.size));
@@ -615,7 +624,7 @@ static CURLcode multi_done(struct Curl_easy *data,
/* if the transfer was completed in a paused state there can be buffered
data left to free */
for(i = 0; i < data->state.tempcount; i++) {
- free(data->state.tempwrite[i].buf);
+ Curl_dyn_free(&data->state.tempwrite[i].b);
}
data->state.tempcount = 0;
@@ -647,7 +656,8 @@ static CURLcode multi_done(struct Curl_easy *data,
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
CURLcode res2;
connclose(conn, "disconnecting");
- CONN_UNLOCK(data);
+ Curl_conncache_remove_conn(data, conn, FALSE);
+ CONNCACHE_UNLOCK(data);
res2 = Curl_disconnect(data, conn, premature);
/* If we had an error already, make sure we return that one. But
@@ -657,16 +667,20 @@ static CURLcode multi_done(struct Curl_easy *data,
}
else {
char buffer[256];
+ const char *host =
+#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;
/* create string before returning the connection */
msnprintf(buffer, sizeof(buffer),
"Connection #%ld to host %s left intact",
- conn->connection_id,
- conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
- conn->bits.httpproxy ? conn->http_proxy.host.dispname :
- conn->bits.conn_to_host ? conn->conn_to_host.dispname :
- conn->host.dispname);
+ conn->connection_id, host);
/* the connection is no longer in use by this transfer */
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
if(Curl_conncache_return_conn(data, conn)) {
/* remember the most recently used connection */
data->state.lastconnect = conn;
@@ -676,6 +690,7 @@ static CURLcode multi_done(struct Curl_easy *data,
data->state.lastconnect = NULL;
}
+ Curl_safefree(data->state.buffer);
Curl_free_request_state(data);
return result;
}
@@ -778,8 +793,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
vanish with this handle */
/* Remove the association between the connection and the handle */
- if(data->conn)
- detach_connnection(data);
+ Curl_detach_connnection(data);
#ifdef USE_LIBPSL
/* Remove the PSL association. */
@@ -828,9 +842,13 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi)
return (multi && (multi->multiplexing));
}
-/* This is the only function that should clear data->conn. This will
- occasionally be called with the pointer already cleared. */
-static void detach_connnection(struct Curl_easy *data)
+/*
+ * Curl_detach_connnection() removes the given transfer from the connection.
+ *
+ * This is the only function that should clear data->conn. This will
+ * occasionally be called with the data->conn pointer already cleared.
+ */
+void Curl_detach_connnection(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
if(conn)
@@ -838,7 +856,11 @@ static void detach_connnection(struct Curl_easy *data)
data->conn = NULL;
}
-/* This is the only function that should assign data->conn */
+/*
+ * Curl_attach_connnection() attaches this transfer to this connection.
+ *
+ * This is the only function that should assign data->conn
+ */
void Curl_attach_connnection(struct Curl_easy *data,
struct connectdata *conn)
{
@@ -857,9 +879,11 @@ static int waitconnect_getsock(struct connectdata *conn,
int rc = 0;
#ifdef USE_SSL
+#ifndef CURL_DISABLE_PROXY
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
return Curl_ssl_getsock(conn, sock);
#endif
+#endif
if(SOCKS_STATE(conn->cnnct.state))
return Curl_SOCKS_getsock(conn, sock, FIRSTSOCKET);
@@ -1049,11 +1073,15 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
unsigned int i;
unsigned int nfds = 0;
unsigned int curlfds;
- bool ufds_malloc = FALSE;
long timeout_internal;
int retcode = 0;
+#ifndef USE_WINSOCK
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
struct pollfd *ufds = &a_few_on_stack[0];
+ bool ufds_malloc = FALSE;
+#else
+ DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
+#endif
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
@@ -1099,11 +1127,16 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
nfds += extra_nfds; /* add the externally provided ones */
#ifdef ENABLE_WAKEUP
+#ifdef USE_WINSOCK
+ if(use_wakeup) {
+#else
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+#endif
++nfds;
}
#endif
+#ifndef USE_WINSOCK
if(nfds > NUM_POLLS_ON_STACK) {
/* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
big, so at 2^29 sockets this value might wrap. When a process gets
@@ -1114,7 +1147,9 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
return CURLM_OUT_OF_MEMORY;
ufds_malloc = TRUE;
}
+
nfds = 0;
+#endif
/* only do the second loop if we found descriptors in the first stage run
above */
@@ -1127,22 +1162,36 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
-
+#ifdef USE_WINSOCK
+ long mask = 0;
+#endif
if(bitmap & GETSOCK_READSOCK(i)) {
+#ifdef USE_WINSOCK
+ mask |= FD_READ;
+#else
ufds[nfds].fd = sockbunch[i];
ufds[nfds].events = POLLIN;
++nfds;
+#endif
s = sockbunch[i];
}
if(bitmap & GETSOCK_WRITESOCK(i)) {
+#ifdef USE_WINSOCK
+ mask |= FD_WRITE;
+#else
ufds[nfds].fd = sockbunch[i];
ufds[nfds].events = POLLOUT;
++nfds;
+#endif
s = sockbunch[i];
}
if(s == CURL_SOCKET_BAD) {
break;
}
+#ifdef USE_WINSOCK
+ if(WSAEventSelect(s, multi->wsa_event, mask) != 0)
+ return CURLM_INTERNAL_ERROR;
+#endif
}
data = data->next; /* check next handle */
@@ -1151,6 +1200,17 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
/* Add external file descriptions from poll-like struct curl_waitfd */
for(i = 0; i < extra_nfds; i++) {
+#ifdef USE_WINSOCK
+ long events = 0;
+ if(extra_fds[i].events & CURL_WAIT_POLLIN)
+ events |= FD_READ;
+ if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+ events |= FD_OOB;
+ if(extra_fds[i].events & CURL_WAIT_POLLOUT)
+ events |= FD_WRITE;
+ if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, events) != 0)
+ return CURLM_INTERNAL_ERROR;
+#else
ufds[nfds].fd = extra_fds[i].fd;
ufds[nfds].events = 0;
if(extra_fds[i].events & CURL_WAIT_POLLIN)
@@ -1160,28 +1220,61 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
if(extra_fds[i].events & CURL_WAIT_POLLOUT)
ufds[nfds].events |= POLLOUT;
++nfds;
+#endif
}
#ifdef ENABLE_WAKEUP
+#ifndef USE_WINSOCK
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
ufds[nfds].fd = multi->wakeup_pair[0];
ufds[nfds].events = POLLIN;
++nfds;
}
#endif
+#endif
if(nfds) {
int pollrc;
/* wait... */
+#ifdef USE_WINSOCK
+ DWORD waitrc = WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE,
+ timeout_ms, FALSE);
+ /* WSA_WAIT_EVENT_0 is 0, so waitrc >= WSA_WAIT_EVENT_0 warns */
+ if(waitrc == WSA_WAIT_EVENT_0)
+ pollrc = 1;
+ else
+ pollrc = -1;
+#else
pollrc = Curl_poll(ufds, nfds, timeout_ms);
+#endif
if(pollrc > 0) {
+#ifdef USE_WINSOCK
+ retcode = 0;
+#else
retcode = pollrc;
+#endif
/* copy revents results from the poll to the curl_multi_wait poll
struct, the bit values of the actual underlying poll() implementation
may not be the same as the ones in the public libcurl API! */
for(i = 0; i < extra_nfds; i++) {
unsigned short mask = 0;
+#ifdef USE_WINSOCK
+ WSANETWORKEVENTS events = {0};
+ if(WSAEnumNetworkEvents(extra_fds[i].fd, multi->wsa_event,
+ &events) == 0) {
+ if(events.lNetworkEvents & FD_READ)
+ mask |= CURL_WAIT_POLLIN;
+ if(events.lNetworkEvents & FD_WRITE)
+ mask |= CURL_WAIT_POLLOUT;
+ if(events.lNetworkEvents & FD_OOB)
+ mask |= CURL_WAIT_POLLPRI;
+
+ if(events.lNetworkEvents != 0)
+ retcode++;
+ }
+ WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
+#else
unsigned r = ufds[curlfds + i].revents;
if(r & POLLIN)
@@ -1190,10 +1283,39 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
mask |= CURL_WAIT_POLLOUT;
if(r & POLLPRI)
mask |= CURL_WAIT_POLLPRI;
+#endif
extra_fds[i].revents = mask;
}
+#ifdef USE_WINSOCK
+ /* Count up all our own sockets that had activity,
+ and remove them from the event. */
+ if(curlfds) {
+ data = multi->easyp;
+ while(data) {
+ bitmap = multi_getsock(data, sockbunch);
+
+ for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
+ if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
+ WSANETWORKEVENTS events = {0};
+ if(WSAEnumNetworkEvents(sockbunch[i], multi->wsa_event,
+ &events) == 0) {
+ if(events.lNetworkEvents != 0)
+ retcode++;
+ }
+ WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
+ }
+ else
+ break;
+ }
+
+ data = data->next;
+ }
+ }
+
+ WSAResetEvent(multi->wsa_event);
+#else
#ifdef ENABLE_WAKEUP
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
if(ufds[curlfds + extra_nfds].revents & POLLIN) {
@@ -1206,10 +1328,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
when there is no more data, breaking the loop. */
nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
if(nread <= 0) {
-#ifndef USE_WINSOCK
if(nread < 0 && EINTR == SOCKERRNO)
continue;
-#endif
break;
}
}
@@ -1218,11 +1338,14 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
}
}
#endif
+#endif
}
}
+#ifndef USE_WINSOCK
if(ufds_malloc)
free(ufds);
+#endif
if(ret)
*ret = retcode;
if(!extrawait || nfds)
@@ -1239,7 +1362,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
timeout */
else if((sleep_ms < 0) && extrawait)
sleep_ms = timeout_ms;
- Curl_wait_ms((int)sleep_ms);
+ Curl_wait_ms(sleep_ms);
}
}
@@ -1277,6 +1400,10 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
return CURLM_BAD_HANDLE;
#ifdef ENABLE_WAKEUP
+#ifdef USE_WINSOCK
+ if(WSASetEvent(multi->wsa_event))
+ return CURLM_OK;
+#else
/* the wakeup_pair variable is only written during init and cleanup,
making it safe to access from another thread after the init part
and before cleanup */
@@ -1310,6 +1437,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
}
}
#endif
+#endif
return CURLM_WAKEUP_FAILURE;
}
@@ -1480,7 +1608,7 @@ static CURLcode protocol_connect(struct connectdata *conn,
}
if(!conn->bits.protoconnstart) {
-
+#ifndef CURL_DISABLE_PROXY
result = Curl_proxy_connect(conn, FIRSTSOCKET);
if(result)
return result;
@@ -1494,7 +1622,7 @@ static CURLcode protocol_connect(struct connectdata *conn,
/* when using an HTTP tunnel proxy, await complete tunnel establishment
before proceeding further. Return CURLE_OK so we'll be called again */
return CURLE_OK;
-
+#endif
if(conn->handler->connect_it) {
/* is there a protocol-specific connect() procedure? */
@@ -1513,6 +1641,21 @@ static CURLcode protocol_connect(struct connectdata *conn,
return result; /* pass back status */
}
+/*
+ * Curl_preconnect() is called immediately before a connect starts. When a
+ * redirect is followed, this is then called multiple times during a single
+ * transfer.
+ */
+CURLcode Curl_preconnect(struct Curl_easy *data)
+{
+ if(!data->state.buffer) {
+ data->state.buffer = malloc(data->set.buffer_size + 1);
+ if(!data->state.buffer)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ return CURLE_OK;
+}
+
static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct curltime now,
@@ -1540,19 +1683,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
bool stream_error = FALSE;
rc = CURLM_OK;
- DEBUGASSERT((data->mstate <= CURLM_STATE_CONNECT) ||
- (data->mstate >= CURLM_STATE_DONE) ||
- data->conn);
- if(!data->conn &&
- data->mstate > CURLM_STATE_CONNECT &&
- data->mstate < CURLM_STATE_DONE) {
- /* In all these states, the code will blindly access 'data->conn'
- so this is precaution that it isn't NULL. And it silences static
- analyzers. */
- failf(data, "In state %d with no conn, bail out!\n", data->mstate);
- return CURLM_INTERNAL_ERROR;
- }
-
if(multi_ischanged(multi, TRUE)) {
DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
process_pending_handles(multi); /* multiplexed */
@@ -1633,6 +1763,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case CURLM_STATE_CONNECT:
/* Connect. We want to get a connection identifier filled in. */
+ /* init this transfer. */
+ result = Curl_preconnect(data);
+ if(result)
+ break;
+
Curl_pgrsTime(data, TIMER_STARTSINGLE);
if(data->set.timeout)
Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
@@ -1690,9 +1825,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
const char *hostname;
DEBUGASSERT(conn);
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy)
hostname = conn->http_proxy.host.name;
- else if(conn->bits.conn_to_host)
+ else
+#endif
+ if(conn->bits.conn_to_host)
hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;
@@ -1758,7 +1896,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
DEBUGASSERT(data->conn);
result = Curl_http_connect(data->conn, &protocol_connected);
-
+#ifndef CURL_DISABLE_PROXY
if(data->conn->bits.proxy_connect_closed) {
rc = CURLM_CALL_MULTI_PERFORM;
/* connect back to proxy again */
@@ -1766,15 +1904,20 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multi_done(data, CURLE_OK, FALSE);
multistate(data, CURLM_STATE_CONNECT);
}
- else if(!result) {
- if((data->conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
- data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
- Curl_connect_complete(data->conn)) {
- rc = CURLM_CALL_MULTI_PERFORM;
- /* initiate protocol connect phase */
- multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+ else
+#endif
+ if(!result) {
+ if(
+#ifndef CURL_DISABLE_PROXY
+ (data->conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
+ data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
+#endif
+ Curl_connect_complete(data->conn)) {
+ rc = CURLM_CALL_MULTI_PERFORM;
+ /* initiate protocol connect phase */
+ multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+ }
}
- }
else if(result)
stream_error = TRUE;
break;
@@ -1786,17 +1929,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected);
if(connected && !result) {
#ifndef CURL_DISABLE_HTTP
- if((data->conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
- !data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
- Curl_connect_ongoing(data->conn)) {
+ if(
+#ifndef CURL_DISABLE_PROXY
+ (data->conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
+ !data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
+#endif
+ Curl_connect_ongoing(data->conn)) {
multistate(data, CURLM_STATE_WAITPROXYCONNECT);
break;
}
#endif
rc = CURLM_CALL_MULTI_PERFORM;
- multistate(data, data->conn->bits.tunnel_proxy?
+#ifndef CURL_DISABLE_PROXY
+ multistate(data,
+ data->conn->bits.tunnel_proxy?
CURLM_STATE_WAITPROXYCONNECT:
CURLM_STATE_SENDPROTOCONNECT);
+#else
+ multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+#endif
}
else if(result) {
/* failure detected */
@@ -2062,7 +2213,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
char *newurl = NULL;
bool retry = FALSE;
bool comeback = FALSE;
-
+ DEBUGASSERT(data->state.buffer);
/* check if over send speed */
send_timeout_ms = 0;
if(data->set.max_send_speed > 0)
@@ -2235,8 +2386,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
* access free'd data, if the connection is free'd and the handle
* removed before we perform the processing in CURLM_STATE_COMPLETED
*/
- if(data->conn)
- detach_connnection(data);
+ Curl_detach_connnection(data);
}
#ifndef CURL_DISABLE_FTP
@@ -2288,7 +2438,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* This is where we make sure that the conn pointer is reset.
We don't have to do this in every case block above where a
failure is detected */
- detach_connnection(data);
+ Curl_detach_connnection(data);
+
+ /* remove connection from cache */
+ Curl_conncache_remove_conn(data, conn, TRUE);
/* disconnect properly */
Curl_disconnect(data, conn, dead_connection);
@@ -2443,10 +2596,14 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_hash_destroy(&multi->hostcache);
Curl_psl_destroy(&multi->psl);
+#ifdef USE_WINSOCK
+ WSACloseEvent(multi->wsa_event);
+#else
#ifdef ENABLE_WAKEUP
sclose(multi->wakeup_pair[0]);
sclose(multi->wakeup_pair[1]);
#endif
+#endif
free(multi);
return CURLM_OK;
diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h
index 91eca16c4a..94bbad77a0 100644
--- a/libs/libcurl/src/multihandle.h
+++ b/libs/libcurl/src/multihandle.h
@@ -138,10 +138,14 @@ struct Curl_multi {
previous callback */
unsigned int max_concurrent_streams;
+#ifdef USE_WINSOCK
+ WSAEVENT wsa_event; /* winsock event used for waits */
+#else
#ifdef ENABLE_WAKEUP
curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup
0 is used for read, 1 is used for write */
#endif
+#endif
/* multiplexing wanted */
bool multiplexing;
bool recheckstate; /* see Curl_multi_connchanged */
diff --git a/libs/libcurl/src/multiif.h b/libs/libcurl/src/multiif.h
index bde755ee0f..7d574df924 100644
--- a/libs/libcurl/src/multiif.h
+++ b/libs/libcurl/src/multiif.h
@@ -33,9 +33,11 @@ void Curl_expire_done(struct Curl_easy *data, expire_id id);
void Curl_update_timer(struct Curl_multi *multi);
void Curl_attach_connnection(struct Curl_easy *data,
struct connectdata *conn);
+void Curl_detach_connnection(struct Curl_easy *data);
bool Curl_multiplex_wanted(const struct Curl_multi *multi);
void Curl_set_in_callback(struct Curl_easy *data, bool value);
bool Curl_is_in_callback(struct Curl_easy *easy);
+CURLcode Curl_preconnect(struct Curl_easy *data);
/* Internal version of curl_multi_init() accepts size parameters for the
socket and connection hashes */
diff --git a/libs/libcurl/src/nwlib.c b/libs/libcurl/src/nwlib.c
index 7bf5f51c36..beec0b3889 100644
--- a/libs/libcurl/src/nwlib.c
+++ b/libs/libcurl/src/nwlib.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -36,21 +36,19 @@
/* The last #include file should be: */
#include "memdebug.h"
-typedef struct
-{
+struct libthreaddata {
int _errno;
void *twentybytes;
-} libthreaddata_t;
+};
-typedef struct
-{
+struct libdata {
int x;
int y;
int z;
void *tenbytes;
NXKey_t perthreadkey; /* if -1, no key obtained... */
NXMutex_t *lock;
-} libdata_t;
+};
int gLibId = -1;
void *gLibHandle = (void *) NULL;
@@ -60,7 +58,8 @@ NXMutex_t *gLibLock = (NXMutex_t *) NULL;
/* internal library function prototypes... */
int DisposeLibraryData(void *);
void DisposeThreadData(void *);
-int GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata);
+int GetOrSetUpData(int id, struct libdata **data,
+ struct libthreaddata **threaddata);
int _NonAppStart(void *NLMHandle,
@@ -154,24 +153,24 @@ int _NonAppCheckUnload(void)
return 0;
}
-int GetOrSetUpData(int id, libdata_t **appData,
- libthreaddata_t **threadData)
+int GetOrSetUpData(int id, struct libdata **appData,
+ struct libthreaddata **threadData)
{
int err;
- libdata_t *app_data;
- libthreaddata_t *thread_data;
+ struct libdata *app_data;
+ struct libthreaddata *thread_data;
NXKey_t key;
NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
err = 0;
- thread_data = (libthreaddata_t *) NULL;
+ thread_data = (struct libthreaddata_t *) NULL;
/*
* Attempt to get our data for the application calling us. This is where we
* store whatever application-specific information we need to carry in
* support of calling applications.
*/
- app_data = (libdata_t *) get_app_data(id);
+ app_data = (struct libdata *) get_app_data(id);
if(!app_data) {
/*
@@ -184,9 +183,9 @@ int GetOrSetUpData(int id, libdata_t **appData,
*/
NXLock(gLibLock);
- app_data = (libdata_t *) get_app_data(id);
+ app_data = (struct libdata *) get_app_data(id);
if(!app_data) {
- app_data = calloc(1, sizeof(libdata_t));
+ app_data = calloc(1, sizeof(struct libdata));
if(app_data) {
app_data->tenbytes = malloc(10);
@@ -249,7 +248,7 @@ int GetOrSetUpData(int id, libdata_t **appData,
* a pointer is not very important, this just helps to demonstrate that
* we can have arbitrarily complex per-thread data.
*/
- thread_data = malloc(sizeof(libthreaddata_t));
+ thread_data = malloc(sizeof(struct libthreaddata));
if(thread_data) {
thread_data->_errno = 0;
@@ -257,7 +256,7 @@ int GetOrSetUpData(int id, libdata_t **appData,
if(!thread_data->twentybytes) {
free(thread_data);
- thread_data = (libthreaddata_t *) NULL;
+ thread_data = (struct libthreaddata *) NULL;
err = ENOMEM;
}
@@ -265,7 +264,7 @@ int GetOrSetUpData(int id, libdata_t **appData,
if(err) {
free(thread_data->twentybytes);
free(thread_data);
- thread_data = (libthreaddata_t *) NULL;
+ thread_data = (struct libthreaddata *) NULL;
}
}
}
@@ -295,7 +294,7 @@ int DisposeLibraryData(void *data)
void DisposeThreadData(void *data)
{
if(data) {
- void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
+ void *twentybytes = ((struct libthreaddata *) data)->twentybytes;
free(twentybytes);
free(data);
diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c
index 734ca5fa0c..782d6a08e7 100644
--- a/libs/libcurl/src/openldap.c
+++ b/libs/libcurl/src/openldap.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
- * Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2020, 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
@@ -162,10 +162,10 @@ struct ldapconninfo {
bool didbind;
};
-typedef struct ldapreqinfo {
+struct ldapreqinfo {
int msgid;
int nument;
-} ldapreqinfo;
+};
static CURLcode ldap_setup_connection(struct connectdata *conn)
{
@@ -374,7 +374,7 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
static CURLcode ldap_do(struct connectdata *conn, bool *done)
{
struct ldapconninfo *li = conn->proto.ldapc;
- ldapreqinfo *lr;
+ struct ldapreqinfo *lr;
CURLcode status = CURLE_OK;
int rc = 0;
LDAPURLDesc *ludp = NULL;
@@ -406,7 +406,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
return CURLE_LDAP_SEARCH_FAILED;
}
- lr = calloc(1, sizeof(ldapreqinfo));
+ lr = calloc(1, sizeof(struct ldapreqinfo));
if(!lr)
return CURLE_OUT_OF_MEMORY;
lr->msgid = msgid;
@@ -419,7 +419,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
bool premature)
{
- ldapreqinfo *lr = conn->data->req.protop;
+ struct ldapreqinfo *lr = conn->data->req.protop;
(void)res;
(void)premature;
@@ -443,7 +443,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
{
struct ldapconninfo *li = conn->proto.ldapc;
struct Curl_easy *data = conn->data;
- ldapreqinfo *lr = data->req.protop;
+ struct ldapreqinfo *lr = data->req.protop;
int rc, ret;
LDAPMessage *msg = NULL;
LDAPMessage *ent;
diff --git a/libs/libcurl/src/pingpong.c b/libs/libcurl/src/pingpong.c
index d0710053bd..ced832ecf5 100644
--- a/libs/libcurl/src/pingpong.c
+++ b/libs/libcurl/src/pingpong.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -44,12 +44,12 @@
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
-time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
+timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
{
struct connectdata *conn = pp->conn;
struct Curl_easy *data = conn->data;
- time_t timeout_ms; /* in milliseconds */
- long response_time = (data->set.server_response_timeout)?
+ timediff_t timeout_ms; /* in milliseconds */
+ timediff_t response_time = (data->set.server_response_timeout)?
data->set.server_response_timeout: pp->response_time;
/* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
@@ -60,12 +60,12 @@ time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
/* Without a requested timeout, we only wait 'response_time' seconds for the
full response to arrive before we bail out */
timeout_ms = response_time -
- (time_t)Curl_timediff(Curl_now(), pp->response); /* spent time */
+ Curl_timediff(Curl_now(), pp->response); /* spent time */
if(data->set.timeout && !disconnecting) {
/* if timeout is requested, find out how much remaining time we have */
- time_t timeout2_ms = data->set.timeout - /* timeout time */
- (time_t)Curl_timediff(Curl_now(), conn->now); /* spent time */
+ timediff_t timeout2_ms = data->set.timeout - /* timeout time */
+ Curl_timediff(Curl_now(), conn->now); /* spent time */
/* pick the lowest number */
timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
@@ -83,8 +83,8 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
struct connectdata *conn = pp->conn;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc;
- time_t interval_ms;
- time_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
+ timediff_t interval_ms;
+ timediff_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
diff --git a/libs/libcurl/src/pingpong.h b/libs/libcurl/src/pingpong.h
index 849a7c0ff7..e874799d44 100644
--- a/libs/libcurl/src/pingpong.h
+++ b/libs/libcurl/src/pingpong.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -60,9 +60,8 @@ struct pingpong {
size_t sendsize; /* total size of the sendthis buffer */
struct curltime response; /* set to Curl_now() when a command has been sent
off, used to time-out response reading */
- long response_time; /* When no timeout is given, this is the amount of
- milliseconds we await for a server response. */
-
+ timediff_t response_time; /* When no timeout is given, this is the amount of
+ milliseconds we await for a server response. */
struct connectdata *conn; /* points to the connectdata struct that this
belongs to */
@@ -89,7 +88,7 @@ void Curl_pp_init(struct pingpong *pp);
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
-time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
+timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
/***********************************************************************
diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c
index 57c1373aa8..2f490b2f12 100644
--- a/libs/libcurl/src/pop3.c
+++ b/libs/libcurl/src/pop3.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -178,7 +178,7 @@ static void pop3_to_pop3s(struct connectdata *conn)
conn->handler = &Curl_handler_pop3s;
/* Set the connection's upgraded to TLS flag */
- conn->tls_upgraded = TRUE;
+ conn->bits.tls_upgraded = TRUE;
}
#else
#define pop3_to_pop3s(x) Curl_nop_stmt
@@ -412,7 +412,7 @@ static CURLcode pop3_perform_apop(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
size_t i;
- MD5_context *ctxt;
+ struct MD5_context *ctxt;
unsigned char digest[MD5_DIGEST_LEN];
char secret[2 * MD5_DIGEST_LEN + 1];
@@ -1312,7 +1312,7 @@ static CURLcode pop3_setup_connection(struct connectdata *conn)
return result;
/* Clear the TLS upgraded flag */
- conn->tls_upgraded = FALSE;
+ conn->bits.tls_upgraded = FALSE;
return CURLE_OK;
}
diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c
index 60a941ab2d..8951384481 100644
--- a/libs/libcurl/src/progress.c
+++ b/libs/libcurl/src/progress.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -282,9 +282,9 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
* stay below 'limit'.
*/
if(size < CURL_OFF_T_MAX/1000)
- minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
+ minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / limit);
else {
- minimum = (time_t) (size / limit);
+ minimum = (timediff_t) (size / limit);
if(minimum < TIMEDIFF_T_MAX/1000)
minimum *= 1000;
else
diff --git a/libs/libcurl/src/quic.h b/libs/libcurl/src/quic.h
index 1eb23e9766..8e7df90eac 100644
--- a/libs/libcurl/src/quic.h
+++ b/libs/libcurl/src/quic.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -47,11 +47,13 @@ int Curl_quic_ver(char *p, size_t len);
CURLcode Curl_quic_done_sending(struct connectdata *conn);
void Curl_quic_done(struct Curl_easy *data, bool premature);
bool Curl_quic_data_pending(const struct Curl_easy *data);
+void Curl_quic_disconnect(struct connectdata *conn, int tempindex);
#else /* ENABLE_QUIC */
#define Curl_quic_done_sending(x)
#define Curl_quic_done(x,y)
#define Curl_quic_data_pending(x)
+#define Curl_quic_disconnect(x,y)
#endif /* !ENABLE_QUIC */
#endif /* HEADER_CURL_QUIC_H */
diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c
index bba4c16a1e..dbd7dc6a6d 100644
--- a/libs/libcurl/src/rtsp.c
+++ b/libs/libcurl/src/rtsp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -233,7 +233,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
CURLcode result = CURLE_OK;
Curl_RtspReq rtspreq = data->set.rtspreq;
struct RTSP *rtsp = data->req.protop;
- Curl_send_buffer *req_buffer;
+ struct dynbuf req_buffer;
curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
@@ -333,12 +333,12 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
if(rtspreq == RTSPREQ_SETUP && !p_transport) {
/* New Transport: setting? */
if(data->set.str[STRING_RTSP_TRANSPORT]) {
- Curl_safefree(conn->allocptr.rtsp_transport);
+ Curl_safefree(data->state.aptr.rtsp_transport);
- conn->allocptr.rtsp_transport =
+ data->state.aptr.rtsp_transport =
aprintf("Transport: %s\r\n",
data->set.str[STRING_RTSP_TRANSPORT]);
- if(!conn->allocptr.rtsp_transport)
+ if(!data->state.aptr.rtsp_transport)
return CURLE_OUT_OF_MEMORY;
}
else {
@@ -347,7 +347,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- p_transport = conn->allocptr.rtsp_transport;
+ p_transport = data->state.aptr.rtsp_transport;
}
/* Accept Headers for DESCRIBE requests */
@@ -359,14 +359,14 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
/* Accept-Encoding header */
if(!Curl_checkheaders(conn, "Accept-Encoding") &&
data->set.str[STRING_ENCODING]) {
- Curl_safefree(conn->allocptr.accept_encoding);
- conn->allocptr.accept_encoding =
+ Curl_safefree(data->state.aptr.accept_encoding);
+ data->state.aptr.accept_encoding =
aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
- if(!conn->allocptr.accept_encoding)
+ if(!data->state.aptr.accept_encoding)
return CURLE_OUT_OF_MEMORY;
- p_accept_encoding = conn->allocptr.accept_encoding;
+ p_accept_encoding = data->state.aptr.accept_encoding;
}
}
@@ -374,13 +374,13 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
it might have been used in the proxy connect, but if we have got a header
with the user-agent string specified, we erase the previously made string
here. */
- if(Curl_checkheaders(conn, "User-Agent") && conn->allocptr.uagent) {
- Curl_safefree(conn->allocptr.uagent);
- conn->allocptr.uagent = NULL;
+ if(Curl_checkheaders(conn, "User-Agent") && data->state.aptr.uagent) {
+ Curl_safefree(data->state.aptr.uagent);
+ data->state.aptr.uagent = NULL;
}
else if(!Curl_checkheaders(conn, "User-Agent") &&
data->set.str[STRING_USERAGENT]) {
- p_uagent = conn->allocptr.uagent;
+ p_uagent = data->state.aptr.uagent;
}
/* setup the authentication headers */
@@ -388,17 +388,17 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
if(result)
return result;
- p_proxyuserpwd = conn->allocptr.proxyuserpwd;
- p_userpwd = conn->allocptr.userpwd;
+ p_proxyuserpwd = data->state.aptr.proxyuserpwd;
+ p_userpwd = data->state.aptr.userpwd;
/* Referrer */
- Curl_safefree(conn->allocptr.ref);
+ Curl_safefree(data->state.aptr.ref);
if(data->change.referer && !Curl_checkheaders(conn, "Referer"))
- conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+ data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
else
- conn->allocptr.ref = NULL;
+ data->state.aptr.ref = NULL;
- p_referrer = conn->allocptr.ref;
+ p_referrer = data->state.aptr.ref;
/*
* Range Header
@@ -411,9 +411,9 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
/* Check to see if there is a range set in the custom headers */
if(!Curl_checkheaders(conn, "Range") && data->state.range) {
- Curl_safefree(conn->allocptr.rangeline);
- conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
- p_range = conn->allocptr.rangeline;
+ Curl_safefree(data->state.aptr.rangeline);
+ data->state.aptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
+ p_range = data->state.aptr.rangeline;
}
}
@@ -430,16 +430,13 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
}
/* Initialize a dynamic send buffer */
- req_buffer = Curl_add_buffer_init();
-
- if(!req_buffer)
- return CURLE_OUT_OF_MEMORY;
+ Curl_dyn_init(&req_buffer, DYN_RTSP_REQ_HEADER);
result =
- Curl_add_bufferf(&req_buffer,
- "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
- "CSeq: %ld\r\n", /* CSeq */
- p_request, p_stream_uri, rtsp->CSeq_sent);
+ Curl_dyn_addf(&req_buffer,
+ "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
+ "CSeq: %ld\r\n", /* CSeq */
+ p_request, p_stream_uri, rtsp->CSeq_sent);
if(result)
return result;
@@ -448,7 +445,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
* to make comparison easier
*/
if(p_session_id) {
- result = Curl_add_bufferf(&req_buffer, "Session: %s\r\n", p_session_id);
+ result = Curl_dyn_addf(&req_buffer, "Session: %s\r\n", p_session_id);
if(result)
return result;
}
@@ -456,42 +453,42 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
/*
* Shared HTTP-like options
*/
- result = Curl_add_bufferf(&req_buffer,
- "%s" /* transport */
- "%s" /* accept */
- "%s" /* accept-encoding */
- "%s" /* range */
- "%s" /* referrer */
- "%s" /* user-agent */
- "%s" /* proxyuserpwd */
- "%s" /* userpwd */
- ,
- p_transport ? p_transport : "",
- p_accept ? p_accept : "",
- p_accept_encoding ? p_accept_encoding : "",
- p_range ? p_range : "",
- p_referrer ? p_referrer : "",
- p_uagent ? p_uagent : "",
- p_proxyuserpwd ? p_proxyuserpwd : "",
- p_userpwd ? p_userpwd : "");
+ result = Curl_dyn_addf(&req_buffer,
+ "%s" /* transport */
+ "%s" /* accept */
+ "%s" /* accept-encoding */
+ "%s" /* range */
+ "%s" /* referrer */
+ "%s" /* user-agent */
+ "%s" /* proxyuserpwd */
+ "%s" /* userpwd */
+ ,
+ p_transport ? p_transport : "",
+ p_accept ? p_accept : "",
+ p_accept_encoding ? p_accept_encoding : "",
+ p_range ? p_range : "",
+ p_referrer ? p_referrer : "",
+ p_uagent ? p_uagent : "",
+ p_proxyuserpwd ? p_proxyuserpwd : "",
+ p_userpwd ? p_userpwd : "");
/*
* Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
* with basic and digest, it will be freed anyway by the next request
*/
- Curl_safefree(conn->allocptr.userpwd);
- conn->allocptr.userpwd = NULL;
+ Curl_safefree(data->state.aptr.userpwd);
+ data->state.aptr.userpwd = NULL;
if(result)
return result;
if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
- result = Curl_add_timecondition(conn, req_buffer);
+ result = Curl_add_timecondition(conn, &req_buffer);
if(result)
return result;
}
- result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+ result = Curl_add_custom_headers(conn, FALSE, &req_buffer);
if(result)
return result;
@@ -501,14 +498,14 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
if(data->set.upload) {
putsize = data->state.infilesize;
- data->set.httpreq = HTTPREQ_PUT;
+ data->state.httpreq = HTTPREQ_PUT;
}
else {
postsize = (data->state.infilesize != -1)?
data->state.infilesize:
(data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
- data->set.httpreq = HTTPREQ_POST;
+ data->state.httpreq = HTTPREQ_POST;
}
if(putsize > 0 || postsize > 0) {
@@ -516,9 +513,9 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
* actually set a custom Content-Length in the headers */
if(!Curl_checkheaders(conn, "Content-Length")) {
result =
- Curl_add_bufferf(&req_buffer,
- "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
- (data->set.upload ? putsize : postsize));
+ Curl_dyn_addf(&req_buffer,
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
+ (data->set.upload ? putsize : postsize));
if(result)
return result;
}
@@ -526,8 +523,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
if(rtspreq == RTSPREQ_SET_PARAMETER ||
rtspreq == RTSPREQ_GET_PARAMETER) {
if(!Curl_checkheaders(conn, "Content-Type")) {
- result = Curl_add_bufferf(&req_buffer,
- "Content-Type: text/parameters\r\n");
+ result = Curl_dyn_addf(&req_buffer,
+ "Content-Type: text/parameters\r\n");
if(result)
return result;
}
@@ -535,8 +532,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
if(rtspreq == RTSPREQ_ANNOUNCE) {
if(!Curl_checkheaders(conn, "Content-Type")) {
- result = Curl_add_bufferf(&req_buffer,
- "Content-Type: application/sdp\r\n");
+ result = Curl_dyn_addf(&req_buffer,
+ "Content-Type: application/sdp\r\n");
if(result)
return result;
}
@@ -546,7 +543,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
}
else if(rtspreq == RTSPREQ_GET_PARAMETER) {
/* Check for an empty GET_PARAMETER (heartbeat) request */
- data->set.httpreq = HTTPREQ_HEAD;
+ data->state.httpreq = HTTPREQ_HEAD;
data->set.opt_no_body = TRUE;
}
}
@@ -554,20 +551,20 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
/* RTSP never allows chunked transfer */
data->req.forbidchunk = TRUE;
/* Finish the request buffer */
- result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+ result = Curl_dyn_add(&req_buffer, "\r\n");
if(result)
return result;
if(postsize > 0) {
- result = Curl_add_buffer(&req_buffer, data->set.postfields,
- (size_t)postsize);
+ result = Curl_dyn_addn(&req_buffer, data->set.postfields,
+ (size_t)postsize);
if(result)
return result;
}
/* issue the request */
- result = Curl_add_buffer_send(&req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
+ result = Curl_buffer_send(&req_buffer, conn,
+ &data->info.request_size, 0, FIRSTSOCKET);
if(result) {
failf(data, "Failed sending RTSP request");
return result;
diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c
index d91b20a4bc..abb124ae8f 100644
--- a/libs/libcurl/src/select.c
+++ b/libs/libcurl/src/select.c
@@ -22,6 +22,8 @@
#include "curl_setup.h"
+#include <limits.h>
+
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#elif defined(HAVE_UNISTD_H)
@@ -50,11 +52,9 @@
#include "urldata.h"
#include "connect.h"
#include "select.h"
+#include "timeval.h"
#include "warnless.h"
-/* Convenience local macros */
-#define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv)
-
/*
* Internal function used for waiting a specific amount of ms
* in Curl_socket_check() and Curl_poll() when no file descriptor
@@ -71,7 +71,7 @@
* -1 = system call error, invalid timeout value, or interrupted
* 0 = specified timeout has elapsed
*/
-int Curl_wait_ms(int timeout_ms)
+int Curl_wait_ms(timediff_t timeout_ms)
{
int r = 0;
@@ -83,16 +83,44 @@ int Curl_wait_ms(int timeout_ms)
}
#if defined(MSDOS)
delay(timeout_ms);
-#elif defined(USE_WINSOCK)
- Sleep(timeout_ms);
+#elif defined(WIN32)
+ /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */
+#if TIMEDIFF_T_MAX >= ULONG_MAX
+ if(timeout_ms >= ULONG_MAX)
+ timeout_ms = ULONG_MAX-1;
+ /* don't use ULONG_MAX, because that is equal to INFINITE */
+#endif
+ Sleep((ULONG)timeout_ms);
#else
#if defined(HAVE_POLL_FINE)
- r = poll(NULL, 0, timeout_ms);
+ /* prevent overflow, timeout_ms is typecast to int. */
+#if TIMEDIFF_T_MAX > INT_MAX
+ if(timeout_ms > INT_MAX)
+ timeout_ms = INT_MAX;
+#endif
+ r = poll(NULL, 0, (int)timeout_ms);
#else
{
struct timeval pending_tv;
- pending_tv.tv_sec = timeout_ms / 1000;
- pending_tv.tv_usec = (timeout_ms % 1000) * 1000;
+ timediff_t tv_sec = timeout_ms / 1000;
+ timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
+#ifdef HAVE_SUSECONDS_T
+#if TIMEDIFF_T_MAX > TIME_T_MAX
+ /* tv_sec overflow check in case time_t is signed */
+ if(tv_sec > TIME_T_MAX)
+ tv_sec = TIME_T_MAX;
+#endif
+ pending_tv.tv_sec = (time_t)tv_sec;
+ pending_tv.tv_usec = (suseconds_t)tv_usec;
+#else
+#if TIMEDIFF_T_MAX > INT_MAX
+ /* tv_sec overflow check in case time_t is signed */
+ if(tv_sec > INT_MAX)
+ tv_sec = INT_MAX;
+#endif
+ pending_tv.tv_sec = (int)tv_sec;
+ pending_tv.tv_usec = (int)tv_usec;
+#endif
r = select(0, NULL, NULL, NULL, &pending_tv);
}
#endif /* HAVE_POLL_FINE */
@@ -113,44 +141,60 @@ int Curl_wait_ms(int timeout_ms)
* 0 = timeout
* N = number of signalled file descriptors
*/
-int Curl_select(curl_socket_t maxfd,
- fd_set *fds_read,
- fd_set *fds_write,
- fd_set *fds_err,
- time_t timeout_ms) /* milliseconds to wait */
+int Curl_select(curl_socket_t maxfd, /* highest socket number */
+ fd_set *fds_read, /* sockets ready for reading */
+ fd_set *fds_write, /* sockets ready for writing */
+ fd_set *fds_err, /* sockets with errors */
+ timediff_t timeout_ms) /* milliseconds to wait */
{
struct timeval pending_tv;
struct timeval *ptimeout;
- int pending_ms;
int r;
-#if SIZEOF_TIME_T != SIZEOF_INT
- /* wrap-around precaution */
- if(timeout_ms >= INT_MAX)
- timeout_ms = INT_MAX;
-#endif
-
#ifdef USE_WINSOCK
/* WinSock select() can't handle zero events. See the comment below. */
if((!fds_read || fds_read->fd_count == 0) &&
(!fds_write || fds_write->fd_count == 0) &&
(!fds_err || fds_err->fd_count == 0)) {
- r = Curl_wait_ms((int)timeout_ms);
+ r = Curl_wait_ms(timeout_ms);
return r;
}
#endif
ptimeout = &pending_tv;
-
if(timeout_ms < 0) {
ptimeout = NULL;
}
else if(timeout_ms > 0) {
- pending_ms = (int)timeout_ms;
- pending_tv.tv_sec = pending_ms / 1000;
- pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ timediff_t tv_sec = timeout_ms / 1000;
+ timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
+#ifdef HAVE_SUSECONDS_T
+#if TIMEDIFF_T_MAX > TIME_T_MAX
+ /* tv_sec overflow check in case time_t is signed */
+ if(tv_sec > TIME_T_MAX)
+ tv_sec = TIME_T_MAX;
+#endif
+ pending_tv.tv_sec = (time_t)tv_sec;
+ pending_tv.tv_usec = (suseconds_t)tv_usec;
+#elif defined(WIN32) /* maybe also others in the future */
+#if TIMEDIFF_T_MAX > LONG_MAX
+ /* tv_sec overflow check on Windows there we know it is long */
+ if(tv_sec > LONG_MAX)
+ tv_sec = LONG_MAX;
+#endif
+ pending_tv.tv_sec = (long)tv_sec;
+ pending_tv.tv_usec = (long)tv_usec;
+#else
+#if TIMEDIFF_T_MAX > INT_MAX
+ /* tv_sec overflow check in case time_t is signed */
+ if(tv_sec > INT_MAX)
+ tv_sec = INT_MAX;
+#endif
+ pending_tv.tv_sec = (int)tv_sec;
+ pending_tv.tv_usec = (int)tv_usec;
+#endif
}
- else if(!timeout_ms) {
+ else {
pending_tv.tv_sec = 0;
pending_tv.tv_usec = 0;
}
@@ -201,11 +245,10 @@ int Curl_select(curl_socket_t maxfd,
int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
curl_socket_t readfd1,
curl_socket_t writefd, /* socket to write to */
- timediff_t timeout_ms) /* milliseconds to wait */
+ timediff_t timeout_ms) /* milliseconds to wait */
{
#ifdef HAVE_POLL_FINE
struct pollfd pfd[3];
- int pending_ms;
int num;
#else
fd_set fds_read;
@@ -216,16 +259,10 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
int r;
int ret;
-#if SIZEOF_TIME_T != SIZEOF_INT
- /* wrap-around precaution */
- if(timeout_ms >= INT_MAX)
- timeout_ms = INT_MAX;
-#endif
-
if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
(writefd == CURL_SOCKET_BAD)) {
/* no sockets, just wait */
- r = Curl_wait_ms((int)timeout_ms);
+ r = Curl_wait_ms(timeout_ms);
return r;
}
@@ -256,18 +293,9 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
num++;
}
- if(timeout_ms > 0)
- pending_ms = (int)timeout_ms;
- else if(timeout_ms < 0)
- pending_ms = -1;
- else
- pending_ms = 0;
- r = poll(pfd, num, pending_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
+ r = Curl_poll(pfd, num, timeout_ms);
+ if(r <= 0)
+ return r;
ret = 0;
num = 0;
@@ -333,7 +361,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
curl_socket_t is unsigned in such cases and thus -1 is the largest
value).
*/
- r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, (time_t)timeout_ms);
+ r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
if(r < 0)
return -1;
@@ -379,7 +407,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
* 0 = timeout
* N = number of structures with non zero revent fields
*/
-int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
{
#ifdef HAVE_POLL_FINE
int pending_ms;
@@ -402,6 +430,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
}
}
if(fds_none) {
+ /* no sockets, just wait */
r = Curl_wait_ms(timeout_ms);
return r;
}
@@ -413,8 +442,13 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
#ifdef HAVE_POLL_FINE
+ /* prevent overflow, timeout_ms is typecast to int. */
+#if TIMEDIFF_T_MAX > INT_MAX
+ if(timeout_ms > INT_MAX)
+ timeout_ms = INT_MAX;
+#endif
if(timeout_ms > 0)
- pending_ms = timeout_ms;
+ pending_ms = (int)timeout_ms;
else if(timeout_ms < 0)
pending_ms = -1;
else
diff --git a/libs/libcurl/src/select.h b/libs/libcurl/src/select.h
index 0fd8ed5152..95181f467e 100644
--- a/libs/libcurl/src/select.h
+++ b/libs/libcurl/src/select.h
@@ -76,7 +76,7 @@ int Curl_select(curl_socket_t maxfd,
fd_set *fds_read,
fd_set *fds_write,
fd_set *fds_err,
- time_t timeout_ms);
+ timediff_t timeout_ms);
int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
curl_socket_t writefd,
@@ -86,12 +86,12 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
#define SOCKET_WRITABLE(x,z) \
Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
-int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
-int Curl_wait_ms(int timeout_ms);
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms);
+int Curl_wait_ms(timediff_t timeout_ms);
#ifdef TPF
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
- fd_set* excepts, struct timeval* tv);
+ fd_set* excepts, struct timeval *tv);
#endif
/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c
index 6ef47aa801..147ecbfa53 100644
--- a/libs/libcurl/src/sendf.c
+++ b/libs/libcurl/src/sendf.c
@@ -267,7 +267,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
size_t len;
char error[CURL_ERROR_SIZE + 2];
va_start(ap, fmt);
- mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
+ (void)mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
len = strlen(error);
if(data->set.errorbuffer && !data->state.errorbuf) {
@@ -498,7 +498,6 @@ static CURLcode pausewrite(struct Curl_easy *data,
is again enabled */
struct SingleRequest *k = &data->req;
struct UrlState *s = &data->state;
- char *dupl;
unsigned int i;
bool newtype = TRUE;
@@ -518,44 +517,21 @@ static CURLcode pausewrite(struct Curl_easy *data,
else
i = 0;
- if(!newtype) {
- /* append new data to old data */
-
- /* figure out the new size of the data to save */
- size_t newlen = len + s->tempwrite[i].len;
- /* allocate the new memory area */
- char *newptr = realloc(s->tempwrite[i].buf, newlen);
- if(!newptr)
- return CURLE_OUT_OF_MEMORY;
- /* copy the new data to the end of the new area */
- memcpy(newptr + s->tempwrite[i].len, ptr, len);
-
- /* update the pointer and the size */
- s->tempwrite[i].buf = newptr;
- s->tempwrite[i].len = newlen;
-
- len = newlen; /* for the debug output below */
- }
- else {
- dupl = Curl_memdup(ptr, len);
- if(!dupl)
- return CURLE_OUT_OF_MEMORY;
-
+ if(newtype) {
/* store this information in the state struct for later use */
- s->tempwrite[i].buf = dupl;
- s->tempwrite[i].len = len;
+ Curl_dyn_init(&s->tempwrite[i].b, DYN_PAUSE_BUFFER);
s->tempwrite[i].type = type;
if(newtype)
s->tempcount++;
}
+ if(Curl_dyn_addn(&s->tempwrite[i].b, (unsigned char *)ptr, len))
+ return CURLE_OUT_OF_MEMORY;
+
/* mark the connection as RECV paused */
k->keepon |= KEEP_RECV_PAUSE;
- DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n",
- len, type));
-
return CURLE_OK;
}
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index 04785a6820..90edf6aa7a 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -77,6 +77,37 @@ CURLcode Curl_setstropt(char **charp, const char *s)
return CURLE_OK;
}
+CURLcode Curl_setblobopt(struct curl_blob **blobp,
+ const struct curl_blob *blob)
+{
+ /* free the previous storage at `blobp' and replace by a dynamic storage
+ copy of blob. If CURL_BLOB_COPY is set, the data is copied. */
+
+ Curl_safefree(*blobp);
+
+ if(blob) {
+ struct curl_blob *nblob;
+ if(blob->len > CURL_MAX_INPUT_LENGTH)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ nblob = (struct curl_blob *)
+ malloc(sizeof(struct curl_blob) +
+ ((blob->flags & CURL_BLOB_COPY) ? blob->len : 0));
+ if(!nblob)
+ return CURLE_OUT_OF_MEMORY;
+ *nblob = *blob;
+ if(blob->flags & CURL_BLOB_COPY) {
+ /* put the data after the blob struct in memory */
+ nblob->data = (char *)nblob + sizeof(struct curl_blob);
+ memcpy(nblob->data, blob->data, blob->len);
+ }
+
+ *blobp = nblob;
+ return CURLE_OK;
+ }
+
+ return CURLE_OK;
+}
+
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
{
CURLcode result = CURLE_OK;
@@ -240,6 +271,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* Do not include the body part in the output data stream.
*/
data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ if(data->set.opt_no_body)
+ /* in HTTP lingo, no body means using the HEAD request... */
+ data->set.method = HTTPREQ_HEAD;
break;
case CURLOPT_FAILONERROR:
/*
@@ -261,13 +295,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
if(data->set.upload) {
/* If this is HTTP, PUT is what's needed to "upload" */
- data->set.httpreq = HTTPREQ_PUT;
+ data->set.method = HTTPREQ_PUT;
data->set.opt_no_body = FALSE; /* this is implied */
}
else
/* In HTTP, the opposite of upload is GET (unless NOBODY is true as
then this can be changed to HEAD later on) */
- data->set.httpreq = HTTPREQ_GET;
+ data->set.method = HTTPREQ_GET;
break;
case CURLOPT_REQUEST_TARGET:
result = Curl_setstropt(&data->set.str[STRING_TARGET],
@@ -363,7 +397,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
case CURLOPT_SSLVERSION:
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLVERSION:
+#endif
/*
* Set explicit SSL version to try to connect with, as some SSL
* implementations are lame.
@@ -371,9 +407,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
#ifdef USE_SSL
{
long version, version_max;
- struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ?
- &data->set.ssl.primary :
- &data->set.proxy_ssl.primary);
+ struct ssl_primary_config *primary = &data->set.ssl.primary;
+#ifndef CURL_DISABLE_PROXY
+ if(option != CURLOPT_SSLVERSION)
+ primary = &data->set.proxy_ssl.primary;
+#endif
arg = va_arg(param, long);
@@ -481,11 +519,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
CURLOPT_POSTFIELDS isn't used and the POST data is read off the
callback! */
if(va_arg(param, long)) {
- data->set.httpreq = HTTPREQ_POST;
+ data->set.method = HTTPREQ_POST;
data->set.opt_no_body = FALSE; /* this is implied */
}
else
- data->set.httpreq = HTTPREQ_GET;
+ data->set.method = HTTPREQ_GET;
break;
case CURLOPT_COPYPOSTFIELDS:
@@ -532,7 +570,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
}
data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
- data->set.httpreq = HTTPREQ_POST;
+ data->set.method = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDS:
@@ -542,7 +580,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.postfields = va_arg(param, void *);
/* Release old copied data. */
(void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
- data->set.httpreq = HTTPREQ_POST;
+ data->set.method = HTTPREQ_POST;
break;
case CURLOPT_POSTFIELDSIZE:
@@ -588,7 +626,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* Set to make us do HTTP POST
*/
data->set.httppost = va_arg(param, struct curl_httppost *);
- data->set.httpreq = HTTPREQ_POST_FORM;
+ data->set.method = HTTPREQ_POST_FORM;
data->set.opt_no_body = FALSE; /* this is implied */
break;
#endif /* CURL_DISABLE_HTTP */
@@ -600,7 +638,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_mime_set_subparts(&data->set.mimepost,
va_arg(param, curl_mime *), FALSE);
if(!result) {
- data->set.httpreq = HTTPREQ_POST_MIME;
+ data->set.method = HTTPREQ_POST_MIME;
data->set.opt_no_body = FALSE; /* this is implied */
}
break;
@@ -795,7 +833,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* Set to force us do HTTP GET
*/
if(va_arg(param, long)) {
- data->set.httpreq = HTTPREQ_GET;
+ data->set.method = HTTPREQ_GET;
data->set.upload = FALSE; /* switch off upload */
data->set.opt_no_body = FALSE; /* this is implied */
}
@@ -905,7 +943,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
va_arg(param, char *));
/* we don't set
- data->set.httpreq = HTTPREQ_CUSTOM;
+ data->set.method = HTTPREQ_CUSTOM;
here, we continue as if we were using the already set type
and this just changes the actual request keyword */
break;
@@ -1606,6 +1644,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
va_arg(param, char *));
break;
+ case CURLOPT_SSLCERT_BLOB:
+ /*
+ * Blob that holds file name of the SSL certificate to use
+ */
+ result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_ORIG],
+ va_arg(param, struct curl_blob *));
+ break;
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLCERT:
/*
@@ -1614,6 +1659,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY],
va_arg(param, char *));
break;
+ case CURLOPT_PROXY_SSLCERT_BLOB:
+ /*
+ * Blob that holds file name of the SSL certificate to use for proxy
+ */
+ result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY],
+ va_arg(param, struct curl_blob *));
+ break;
#endif
case CURLOPT_SSLCERTTYPE:
/*
@@ -1638,6 +1690,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
va_arg(param, char *));
break;
+ case CURLOPT_SSLKEY_BLOB:
+ /*
+ * Blob that holds file name of the SSL key to use
+ */
+ result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_ORIG],
+ va_arg(param, struct curl_blob *));
+ break;
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLKEY:
/*
@@ -1646,6 +1705,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY],
va_arg(param, char *));
break;
+ case CURLOPT_PROXY_SSLKEY_BLOB:
+ /*
+ * Blob that holds file name of the SSL key to use for proxy
+ */
+ result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY],
+ va_arg(param, struct curl_blob *));
+ break;
#endif
case CURLOPT_SSLKEYTYPE:
/*
@@ -1970,6 +2036,30 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
va_arg(param, char *));
break;
+ case CURLOPT_ISSUERCERT_BLOB:
+ /*
+ * Blob that holds Issuer certificate to check certificates issuer
+ */
+ result = Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG],
+ va_arg(param, struct curl_blob *));
+ break;
+#ifndef CURL_DISABLE_PROXY
+ case CURLOPT_PROXY_ISSUERCERT:
+ /*
+ * Set Issuer certificate file
+ * to check certificates issuer
+ */
+ result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_PROXY],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_PROXY_ISSUERCERT_BLOB:
+ /*
+ * Blob that holds Issuer certificate to check certificates issuer
+ */
+ result = Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY],
+ va_arg(param, struct curl_blob *));
+ break;
+#endif
#ifndef CURL_DISABLE_TELNET
case CURLOPT_TELNETOPTIONS:
/*
@@ -1993,7 +2083,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
arg = READBUFFER_MIN;
/* Resize if new size */
- if(arg != data->set.buffer_size) {
+ if((arg != data->set.buffer_size) && data->state.buffer) {
char *newbuff = realloc(data->state.buffer, arg + 1);
if(!newbuff) {
DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
@@ -2135,6 +2225,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
+ data->set.ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
break;
#ifndef CURL_DISABLE_PROXY
@@ -2144,6 +2235,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
(bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
+ data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
data->set.proxy_ssl.revoke_best_effort =
!!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
break;
@@ -2248,7 +2340,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_SSL_SESSIONID_CACHE:
data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
TRUE : FALSE;
+#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
+#endif
break;
#ifdef USE_SSH
@@ -2550,9 +2644,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_PROXY_TLSAUTH_USERNAME:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
va_arg(param, char *));
+#ifndef CURL_DISABLE_PROXY
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
!data->set.proxy_ssl.authtype)
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+#endif
break;
case CURLOPT_TLSAUTH_PASSWORD:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
@@ -2563,9 +2659,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_PROXY_TLSAUTH_PASSWORD:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
va_arg(param, char *));
+#ifndef CURL_DISABLE_PROXY
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
!data->set.proxy_ssl.authtype)
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+#endif
break;
case CURLOPT_TLSAUTH_TYPE:
argptr = va_arg(param, char *);
@@ -2575,6 +2673,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
else
data->set.ssl.authtype = CURL_TLSAUTH_NONE;
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_TLSAUTH_TYPE:
argptr = va_arg(param, char *);
if(!argptr ||
@@ -2584,6 +2683,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
break;
#endif
+#endif
#ifdef USE_ARES
case CURLOPT_DNS_SERVERS:
result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS],
diff --git a/libs/libcurl/src/setopt.h b/libs/libcurl/src/setopt.h
index 5e347dd66b..5fc4368dc9 100644
--- a/libs/libcurl/src/setopt.h
+++ b/libs/libcurl/src/setopt.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -23,6 +23,8 @@
***************************************************************************/
CURLcode Curl_setstropt(char **charp, const char *s);
+CURLcode Curl_setblobopt(struct curl_blob **blobp,
+ const struct curl_blob *blob);
CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list arg);
#endif /* HEADER_CURL_SETOPT_H */
diff --git a/libs/libcurl/src/setup-os400.h b/libs/libcurl/src/setup-os400.h
index 629fd94c46..b693cb3b37 100644
--- a/libs/libcurl/src/setup-os400.h
+++ b/libs/libcurl/src/setup-os400.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -200,10 +200,10 @@ extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
/* Some socket functions must be wrapped to process textual addresses
like AF_UNIX. */
-extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
-extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
+extern int Curl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen);
+extern int Curl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen);
extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
- struct sockaddr * dstaddr, int addrlen);
+ struct sockaddr *dstaddr, int addrlen);
extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
struct sockaddr *fromaddr, int *addrlen);
extern int Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen);
diff --git a/libs/libcurl/src/setup-vms.h b/libs/libcurl/src/setup-vms.h
index 6c454aee68..0e39c9f6b6 100644
--- a/libs/libcurl/src/setup-vms.h
+++ b/libs/libcurl/src/setup-vms.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -73,7 +73,7 @@ char *decc$getenv(const char *__name);
# endif
#endif
- struct passwd * decc_getpwuid(uid_t uid);
+ struct passwd *decc_getpwuid(uid_t uid);
#ifdef __DECC
# if __INITIAL_POINTER_SIZE == 32
@@ -138,9 +138,9 @@ static char *vms_getenv(const char *envvar)
static struct passwd vms_passwd_cache;
-static struct passwd * vms_getpwuid(uid_t uid)
+static struct passwd *vms_getpwuid(uid_t uid)
{
- struct passwd * my_passwd;
+ struct passwd *my_passwd;
/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
#ifdef __DECC
diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c
index 00d98ce469..ee5d273c43 100644
--- a/libs/libcurl/src/sha256.c
+++ b/libs/libcurl/src/sha256.c
@@ -196,10 +196,11 @@ static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
#include <wincrypt.h>
-typedef struct {
+struct sha256_ctx {
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
-} SHA256_CTX;
+};
+typedef struct sha256_ctx SHA256_CTX;
#if !defined(CALG_SHA_256)
#define CALG_SHA_256 0x0000800c
@@ -222,7 +223,7 @@ static void SHA256_Update(SHA256_CTX *ctx,
static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
{
- unsigned long length;
+ unsigned long length = 0;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
if(length == SHA256_DIGEST_LENGTH)
@@ -280,7 +281,7 @@ do { \
} while(0)
#endif
-typedef struct sha256_state {
+struct sha256_state {
#ifdef HAVE_LONGLONG
unsigned long long length;
#else
@@ -288,7 +289,8 @@ typedef struct sha256_state {
#endif
unsigned long state[8], curlen;
unsigned char buf[64];
-} SHA256_CTX;
+};
+typedef struct sha256_state SHA256_CTX;
/* The K array */
static const unsigned long K[64] = {
diff --git a/libs/libcurl/src/share.c b/libs/libcurl/src/share.c
index 3d5108610f..a2d896042a 100644
--- a/libs/libcurl/src/share.c
+++ b/libs/libcurl/src/share.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -70,7 +70,7 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
case CURLSHOPT_SHARE:
/* this is a type this share will share */
type = va_arg(param, int);
- share->specifier |= (1<<type);
+
switch(type) {
case CURL_LOCK_DATA_DNS:
break;
@@ -102,7 +102,7 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
#endif
break;
- case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */
+ case CURL_LOCK_DATA_CONNECT:
if(Curl_conncache_init(&share->conn_cache, 103))
res = CURLSHE_NOMEM;
break;
@@ -116,6 +116,8 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
default:
res = CURLSHE_BAD_OPTION;
}
+ if(!res)
+ share->specifier |= (1<<type);
break;
case CURLSHOPT_UNSHARE:
diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c
index bf65f246f0..ec936480e8 100644
--- a/libs/libcurl/src/smtp.c
+++ b/libs/libcurl/src/smtp.c
@@ -183,7 +183,7 @@ static void smtp_to_smtps(struct connectdata *conn)
conn->handler = &Curl_handler_smtps;
/* Set the connection's upgraded to TLS flag */
- conn->tls_upgraded = TRUE;
+ conn->bits.tls_upgraded = TRUE;
}
#else
#define smtp_to_smtps(x) Curl_nop_stmt
@@ -1617,7 +1617,7 @@ static CURLcode smtp_setup_connection(struct connectdata *conn)
CURLcode result;
/* Clear the TLS upgraded flag */
- conn->tls_upgraded = FALSE;
+ conn->bits.tls_upgraded = FALSE;
/* Initialise the SMTP layer */
result = smtp_init(conn);
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c
index 18affbc964..b2215fef30 100644
--- a/libs/libcurl/src/socks.c
+++ b/libs/libcurl/src/socks.c
@@ -69,7 +69,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
break;
}
if(!timeout_ms)
- timeout_ms = TIME_T_MAX;
+ timeout_ms = TIMEDIFF_T_MAX;
if(SOCKET_READABLE(sockfd, timeout_ms) <= 0) {
result = ~CURLE_OK;
break;
@@ -271,7 +271,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
/* FALLTHROUGH */
CONNECT_RESOLVED:
case CONNECT_RESOLVED: {
- Curl_addrinfo *hp = NULL;
+ struct Curl_addrinfo *hp = NULL;
char buf[64];
/*
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
@@ -382,6 +382,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
curl_easy_strerror(result));
return CURLE_COULDNT_CONNECT;
}
+ else if(!result && !actualread) {
+ /* connection closed */
+ failf(data, "connection to proxy closed");
+ return CURLE_COULDNT_CONNECT;
+ }
else if(actualread != sx->outstanding) {
/* remain in reading state */
sx->outstanding -= actualread;
@@ -592,6 +597,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
failf(data, "Unable to receive initial SOCKS5 response.");
return CURLE_COULDNT_CONNECT;
}
+ else if(!result && !actualread) {
+ /* connection closed */
+ failf(data, "Connection to proxy closed");
+ return CURLE_COULDNT_CONNECT;
+ }
else if(actualread != sx->outstanding) {
/* remain in reading state */
sx->outstanding -= actualread;
@@ -633,11 +643,10 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
failf(data, "No authentication method was acceptable.");
return CURLE_COULDNT_CONNECT;
}
- failf(data,
- "Undocumented SOCKS5 mode attempted to be used by server.");
- return CURLE_COULDNT_CONNECT;
}
- break;
+ failf(data,
+ "Undocumented SOCKS5 mode attempted to be used by server.");
+ return CURLE_COULDNT_CONNECT;
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
case CONNECT_GSSAPI_INIT:
/* GSSAPI stuff done non-blocking */
@@ -718,15 +727,19 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
return CURLE_COULDNT_CONNECT;
}
- if(actualread != sx->outstanding) {
+ else if(!result && !actualread) {
+ /* connection closed */
+ failf(data, "connection to proxy closed");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(actualread != sx->outstanding) {
/* remain in state */
sx->outstanding -= actualread;
sx->outp += actualread;
return CURLE_OK;
}
-
/* ignore the first (VER) byte */
- if(socksreq[1] != 0) { /* status */
+ else if(socksreq[1] != 0) { /* status */
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
socksreq[0], socksreq[1]);
return CURLE_COULDNT_CONNECT;
@@ -773,7 +786,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
/* FALLTHROUGH */
CONNECT_RESOLVED:
case CONNECT_RESOLVED: {
- Curl_addrinfo *hp = NULL;
+ struct Curl_addrinfo *hp = NULL;
+ size_t destlen;
if(dns)
hp = dns->addr;
if(!hp) {
@@ -782,13 +796,9 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
return CURLE_COULDNT_RESOLVE_HOST;
}
- if(Curl_printable_address(hp, dest, sizeof(dest))) {
- size_t destlen = strlen(dest);
- msnprintf(dest + destlen, sizeof(dest) - destlen, ":%d", remote_port);
- }
- else {
- strcpy(dest, "unknown");
- }
+ Curl_printable_address(hp, dest, sizeof(dest));
+ destlen = strlen(dest);
+ msnprintf(dest + destlen, sizeof(dest) - destlen, ":%d", remote_port);
len = 0;
socksreq[len++] = 5; /* version (SOCKS5) */
@@ -894,6 +904,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
failf(data, "Failed to receive SOCKS5 connect request ack.");
return CURLE_COULDNT_CONNECT;
}
+ else if(!result && !actualread) {
+ /* connection closed */
+ failf(data, "connection to proxy closed");
+ return CURLE_COULDNT_CONNECT;
+ }
else if(actualread != sx->outstanding) {
/* remain in state */
sx->outstanding -= actualread;
@@ -938,6 +953,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
/* IPv6 */
len = 4 + 16 + 2;
}
+ else if(socksreq[3] == 1) {
+ len = 4 + 4 + 2;
+ }
+ else {
+ failf(data, "SOCKS5 reply has wrong address type.");
+ return CURLE_COULDNT_CONNECT;
+ }
/* At this point we already read first 10 bytes */
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
@@ -964,7 +986,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
failf(data, "Failed to receive SOCKS5 connect request ack.");
return CURLE_COULDNT_CONNECT;
}
- if(actualread != sx->outstanding) {
+ else if(!result && !actualread) {
+ /* connection closed */
+ failf(data, "connection to proxy closed");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(actualread != sx->outstanding) {
/* remain in state */
sx->outstanding -= actualread;
sx->outp += actualread;
diff --git a/libs/libcurl/src/socks_gssapi.c b/libs/libcurl/src/socks_gssapi.c
index 7f66675fc6..2e36b9940a 100644
--- a/libs/libcurl/src/socks_gssapi.c
+++ b/libs/libcurl/src/socks_gssapi.c
@@ -115,7 +115,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
gss_buffer_desc gss_send_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc gss_recv_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc gss_w_token = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
+ gss_buffer_desc *gss_token = GSS_C_NO_BUFFER;
gss_name_t server = GSS_C_NO_NAME;
gss_name_t gss_client_name = GSS_C_NO_NAME;
unsigned short us_length;
@@ -328,7 +328,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
user[gss_send_token.length] = '\0';
gss_release_name(&gss_status, &gss_client_name);
gss_release_buffer(&gss_status, &gss_send_token);
- infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user);
+ infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",user);
free(user);
user = NULL;
diff --git a/libs/libcurl/src/socks_sspi.c b/libs/libcurl/src/socks_sspi.c
index d5be64a3c0..2f1fd36fa4 100644
--- a/libs/libcurl/src/socks_sspi.c
+++ b/libs/libcurl/src/socks_sspi.c
@@ -160,7 +160,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
for(;;) {
TCHAR *sname;
- sname = Curl_convert_UTF8_to_tchar(service_name);
+ sname = curlx_convert_UTF8_to_tchar(service_name);
if(!sname)
return CURLE_OUT_OF_MEMORY;
@@ -180,7 +180,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
&sspi_ret_flags,
&expiry);
- Curl_unicodefree(sname);
+ curlx_unicodefree(sname);
if(sspi_recv_token.pvBuffer) {
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
@@ -327,7 +327,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
failf(data, "Failed to determine user name.");
return CURLE_COULDNT_CONNECT;
}
- infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
+ infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",
names.sUserName);
s_pSecFn->FreeContextBuffer(names.sUserName);
diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c
index 4bf4c652c2..c3b58e54c5 100644
--- a/libs/libcurl/src/telnet.c
+++ b/libs/libcurl/src/telnet.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -1315,7 +1315,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
DWORD readfile_read;
int err;
#else
- int interval_ms;
+ timediff_t interval_ms;
struct pollfd pfd[2];
int poll_cnt;
curl_off_t total_dl = 0;
diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c
index 346f293dc5..4f2f973a8e 100644
--- a/libs/libcurl/src/tftp.c
+++ b/libs/libcurl/src/tftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -115,11 +115,11 @@ typedef enum {
TFTP_ERR_NORESPONSE
} tftp_error_t;
-typedef struct tftp_packet {
+struct tftp_packet {
unsigned char *data;
-} tftp_packet_t;
+};
-typedef struct tftp_state_data {
+struct tftp_state_data {
tftp_state_t state;
tftp_mode_t mode;
tftp_error_t error;
@@ -140,21 +140,21 @@ typedef struct tftp_state_data {
int sbytes;
int blksize;
int requested_blksize;
- tftp_packet_t rpacket;
- tftp_packet_t spacket;
-} tftp_state_data_t;
+ struct tftp_packet rpacket;
+ struct tftp_packet spacket;
+};
/* Forward declarations */
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event);
+static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event);
static CURLcode tftp_connect(struct connectdata *conn, bool *done);
static CURLcode tftp_disconnect(struct connectdata *conn,
bool dead_connection);
static CURLcode tftp_do(struct connectdata *conn, bool *done);
static CURLcode tftp_done(struct connectdata *conn,
CURLcode, bool premature);
-static CURLcode tftp_setup_connection(struct connectdata * conn);
+static CURLcode tftp_setup_connection(struct connectdata *conn);
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks);
@@ -196,7 +196,7 @@ const struct Curl_handler Curl_handler_tftp = {
*
*
**********************************************************/
-static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
+static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
{
time_t maxtime, timeout;
timediff_t timeout_ms;
@@ -279,25 +279,25 @@ static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
*
**********************************************************/
-static void setpacketevent(tftp_packet_t *packet, unsigned short num)
+static void setpacketevent(struct tftp_packet *packet, unsigned short num)
{
packet->data[0] = (unsigned char)(num >> 8);
packet->data[1] = (unsigned char)(num & 0xff);
}
-static void setpacketblock(tftp_packet_t *packet, unsigned short num)
+static void setpacketblock(struct tftp_packet *packet, unsigned short num)
{
packet->data[2] = (unsigned char)(num >> 8);
packet->data[3] = (unsigned char)(num & 0xff);
}
-static unsigned short getrpacketevent(const tftp_packet_t *packet)
+static unsigned short getrpacketevent(const struct tftp_packet *packet)
{
return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
}
-static unsigned short getrpacketblock(const tftp_packet_t *packet)
+static unsigned short getrpacketblock(const struct tftp_packet *packet)
{
return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
}
@@ -330,7 +330,7 @@ static const char *tftp_option_get(const char *buf, size_t len,
return &buf[loc];
}
-static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
+static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
const char *ptr, int len)
{
const char *tmp = ptr;
@@ -403,7 +403,7 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
return CURLE_OK;
}
-static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize,
+static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize,
char *buf, const char *option)
{
if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
@@ -413,7 +413,7 @@ static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize,
return CURLE_OK;
}
-static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
+static CURLcode tftp_connect_for_tx(struct tftp_state_data *state,
tftp_event_t event)
{
CURLcode result;
@@ -429,7 +429,7 @@ static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
return tftp_tx(state, event);
}
-static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
+static CURLcode tftp_connect_for_rx(struct tftp_state_data *state,
tftp_event_t event)
{
CURLcode result;
@@ -445,7 +445,8 @@ static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
return tftp_rx(state, event);
}
-static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
+static CURLcode tftp_send_first(struct tftp_state_data *state,
+ tftp_event_t event)
{
size_t sbytes;
ssize_t senddata;
@@ -598,7 +599,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
* Event handler for the RX state
*
**********************************************************/
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
+static CURLcode tftp_rx(struct tftp_state_data *state,
+ tftp_event_t event)
{
ssize_t sbytes;
int rblock;
@@ -720,7 +722,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
* Event handler for the TX state
*
**********************************************************/
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
+static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
{
struct Curl_easy *data = state->conn->data;
ssize_t sbytes;
@@ -920,7 +922,7 @@ static CURLcode tftp_translate_code(tftp_error_t error)
* The tftp state machine event dispatcher
*
**********************************************************/
-static CURLcode tftp_state_machine(tftp_state_data_t *state,
+static CURLcode tftp_state_machine(struct tftp_state_data *state,
tftp_event_t event)
{
CURLcode result = CURLE_OK;
@@ -961,7 +963,7 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state,
**********************************************************/
static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
{
- tftp_state_data_t *state = conn->proto.tftpc;
+ struct tftp_state_data *state = conn->proto.tftpc;
(void) dead_connection;
/* done, free dynamically allocated pkt buffers */
@@ -983,13 +985,13 @@ static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
**********************************************************/
static CURLcode tftp_connect(struct connectdata *conn, bool *done)
{
- tftp_state_data_t *state;
+ struct tftp_state_data *state;
int blksize;
int need_blksize;
blksize = TFTP_BLKSIZE_DEFAULT;
- state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
+ state = conn->proto.tftpc = calloc(1, sizeof(struct tftp_state_data));
if(!state)
return CURLE_OUT_OF_MEMORY;
@@ -1078,7 +1080,7 @@ static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
bool premature)
{
CURLcode result = CURLE_OK;
- tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ struct tftp_state_data *state = conn->proto.tftpc;
(void)status; /* unused */
(void)premature; /* not used */
@@ -1119,7 +1121,7 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
curl_socklen_t fromlen;
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ struct tftp_state_data *state = conn->proto.tftpc;
struct SingleRequest *k = &data->req;
/* Receive the packet */
@@ -1206,8 +1208,8 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
**********************************************************/
static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
{
- time_t current;
- tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ time_t current;
+ struct tftp_state_data *state = conn->proto.tftpc;
if(event)
*event = TFTP_EVENT_NONE;
@@ -1244,7 +1246,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
tftp_event_t event;
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ struct tftp_state_data *state = conn->proto.tftpc;
long timeout_ms = tftp_state_timeout(conn, &event);
*done = FALSE;
@@ -1328,7 +1330,7 @@ static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
{
CURLcode result = CURLE_OK;
- tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ struct tftp_state_data *state = conn->proto.tftpc;
*dophase_done = FALSE;
@@ -1358,7 +1360,7 @@ static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
static CURLcode tftp_do(struct connectdata *conn, bool *done)
{
- tftp_state_data_t *state;
+ struct tftp_state_data *state;
CURLcode result;
*done = FALSE;
@@ -1369,7 +1371,7 @@ static CURLcode tftp_do(struct connectdata *conn, bool *done)
return result;
}
- state = (tftp_state_data_t *)conn->proto.tftpc;
+ state = conn->proto.tftpc;
if(!state)
return CURLE_TFTP_ILLEGAL;
@@ -1384,7 +1386,7 @@ static CURLcode tftp_do(struct connectdata *conn, bool *done)
return result;
}
-static CURLcode tftp_setup_connection(struct connectdata * conn)
+static CURLcode tftp_setup_connection(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
char *type;
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index b9581d7adf..133a4783c6 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.c
@@ -128,12 +128,13 @@ static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems,
void *raw)
{
struct Curl_easy *data = (struct Curl_easy *)raw;
- Curl_send_buffer *trailers_buf = data->state.trailers_buf;
- size_t bytes_left = trailers_buf->size_used-data->state.trailers_bytes_sent;
+ struct dynbuf *trailers_buf = &data->state.trailers_buf;
+ size_t bytes_left = Curl_dyn_len(trailers_buf) -
+ data->state.trailers_bytes_sent;
size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left;
if(to_copy) {
memcpy(buffer,
- &trailers_buf->buffer[data->state.trailers_bytes_sent],
+ Curl_dyn_ptr(trailers_buf) + data->state.trailers_bytes_sent,
to_copy);
data->state.trailers_bytes_sent += to_copy;
}
@@ -143,8 +144,8 @@ static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems,
static size_t Curl_trailers_left(void *raw)
{
struct Curl_easy *data = (struct Curl_easy *)raw;
- Curl_send_buffer *trailers_buf = data->state.trailers_buf;
- return trailers_buf->size_used - data->state.trailers_bytes_sent;
+ struct dynbuf *trailers_buf = &data->state.trailers_buf;
+ return Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent;
}
#endif
@@ -186,11 +187,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
infof(data,
"Moving trailers state machine from initialized to sending.\n");
data->state.trailers_state = TRAILERS_SENDING;
- data->state.trailers_buf = Curl_add_buffer_init();
- if(!data->state.trailers_buf) {
- failf(data, "Unable to allocate trailing headers buffer !");
- return CURLE_OUT_OF_MEMORY;
- }
+ Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS);
+
data->state.trailers_bytes_sent = 0;
Curl_set_in_callback(data, true);
trailers_ret_code = data->set.trailer_callback(&trailers,
@@ -206,7 +204,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
result = CURLE_ABORTED_BY_CALLBACK;
}
if(result) {
- Curl_add_buffer_free(&data->state.trailers_buf);
+ Curl_dyn_free(&data->state.trailers_buf);
curl_slist_free_all(trailers);
return result;
}
@@ -369,7 +367,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
#ifndef CURL_DISABLE_HTTP
if(data->state.trailers_state == TRAILERS_SENDING &&
!Curl_trailers_left(data)) {
- Curl_add_buffer_free(&data->state.trailers_buf);
+ Curl_dyn_free(&data->state.trailers_buf);
data->state.trailers_state = TRAILERS_DONE;
data->set.trailer_data = NULL;
data->set.trailer_callback = NULL;
@@ -435,8 +433,8 @@ CURLcode Curl_readrewind(struct connectdata *conn)
}
if(data->set.postfields)
; /* do nothing */
- else if(data->set.httpreq == HTTPREQ_POST_MIME ||
- data->set.httpreq == HTTPREQ_POST_FORM) {
+ else if(data->state.httpreq == HTTPREQ_POST_MIME ||
+ data->state.httpreq == HTTPREQ_POST_FORM) {
if(Curl_mime_rewind(mimepart)) {
failf(data, "Cannot rewind mime/post data");
return CURLE_SEND_FAIL_REWIND;
@@ -560,6 +558,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;
+ char *buf = data->state.buffer;
+ DEBUGASSERT(buf);
*done = FALSE;
*comeback = FALSE;
@@ -594,7 +594,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(bytestoread) {
/* receive data from the network! */
- result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
+ result = Curl_read(conn, conn->sockfd, buf, bytestoread, &nread);
/* read would've blocked */
if(CURLE_AGAIN == result)
@@ -621,9 +621,8 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* indicates data of zero size, i.e. empty file */
is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
- /* NUL terminate, allowing string ops to be used */
if(0 < nread || is_empty_data) {
- k->buf[nread] = 0;
+ buf[nread] = 0;
}
else {
/* if we receive 0 or less here, either the http2 stream is closed or the
@@ -640,7 +639,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* Default buffer to use when we write the buffer, it may be changed
in the flow below before the actual storing is done. */
- k->str = k->buf;
+ k->str = buf;
if(conn->handler->readwrite) {
result = conn->handler->readwrite(data, conn, &nread, &readmore);
@@ -689,7 +688,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* This is not an 'else if' since it may be a rest from the header
parsing, where the beginning of the buffer is headers and the end
is non-headers. */
- if(k->str && !k->header && (nread > 0 || is_empty_data)) {
+ if(!k->header && (nread > 0 || is_empty_data)) {
if(data->set.opt_no_body) {
/* data arrives although we want none, bail out */
@@ -720,7 +719,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
infof(data, "Ignoring the response-body\n");
}
if(data->state.resume_from && !k->content_range &&
- (data->set.httpreq == HTTPREQ_GET) &&
+ (data->state.httpreq == HTTPREQ_GET) &&
!k->ignorebody) {
if(k->size == data->state.resume_from) {
@@ -770,8 +769,9 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* pass data to the debug function before it gets "dechunked" */
if(data->set.verbose) {
if(k->badheader) {
- Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
- (size_t)k->hbuflen);
+ Curl_debug(data, CURLINFO_DATA_IN,
+ Curl_dyn_ptr(&data->state.headerb),
+ Curl_dyn_len(&data->state.headerb));
if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN,
k->str, (size_t)nread);
@@ -822,9 +822,9 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* Account for body content stored in the header buffer */
if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) {
- DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
- k->hbuflen));
- k->bytecount += k->hbuflen;
+ size_t headlen = Curl_dyn_len(&data->state.headerb);
+ DEBUGF(infof(data, "Increasing bytecount by %zu\n", headlen));
+ k->bytecount += headlen;
}
if((-1 != k->maxdownload) &&
@@ -839,6 +839,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
", maxdownload = %" CURL_FORMAT_CURL_OFF_T
", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
excess, k->size, k->maxdownload, k->bytecount);
+ connclose(conn, "excess found in a read");
}
nread = (ssize_t) (k->maxdownload - k->bytecount);
@@ -858,15 +859,16 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(k->badheader && !k->ignorebody) {
/* we parsed a piece of data wrongly assuming it was a header
and now we output it as body instead */
+ size_t headlen = Curl_dyn_len(&data->state.headerb);
/* Don't let excess data pollute body writes */
- if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
+ if(k->maxdownload == -1 || (curl_off_t)headlen <= k->maxdownload)
result = Curl_client_write(conn, CLIENTWRITE_BODY,
- data->state.headerbuff,
- k->hbuflen);
+ Curl_dyn_ptr(&data->state.headerb),
+ headlen);
else
result = Curl_client_write(conn, CLIENTWRITE_BODY,
- data->state.headerbuff,
+ Curl_dyn_ptr(&data->state.headerb),
(size_t)k->maxdownload);
if(result)
@@ -904,10 +906,10 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* Parse the excess data */
k->str += nread;
- if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
+ if(&k->str[excess] > &buf[data->set.buffer_size]) {
/* the excess amount was too excessive(!), make sure
it doesn't read out of buffer */
- excess = &k->buf[data->set.buffer_size] - k->str;
+ excess = &buf[data->set.buffer_size] - k->str;
}
nread = (ssize_t)excess;
@@ -1447,6 +1449,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
}
}
+ data->state.httpreq = data->set.method;
data->change.url = data->set.str[STRING_SET_URL];
/* Init the SSL session ID cache here. We do it here since we want to do it
@@ -1466,12 +1469,11 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
data->state.authhost.want = data->set.httpauth;
data->state.authproxy.want = data->set.proxyauth;
Curl_safefree(data->info.wouldredirect);
- data->info.wouldredirect = NULL;
- if(data->set.httpreq == HTTPREQ_PUT)
+ if(data->state.httpreq == HTTPREQ_PUT)
data->state.infilesize = data->set.filesize;
- else if((data->set.httpreq != HTTPREQ_GET) &&
- (data->set.httpreq != HTTPREQ_HEAD)) {
+ else if((data->state.httpreq != HTTPREQ_GET) &&
+ (data->state.httpreq != HTTPREQ_HEAD)) {
data->state.infilesize = data->set.postfieldsize;
if(data->set.postfields && (data->state.infilesize == -1))
data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
@@ -1682,12 +1684,12 @@ CURLcode Curl_follow(struct Curl_easy *data,
* This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
* can be overridden with CURLOPT_POSTREDIR.
*/
- if((data->set.httpreq == HTTPREQ_POST
- || data->set.httpreq == HTTPREQ_POST_FORM
- || data->set.httpreq == HTTPREQ_POST_MIME)
+ if((data->state.httpreq == HTTPREQ_POST
+ || data->state.httpreq == HTTPREQ_POST_FORM
+ || data->state.httpreq == HTTPREQ_POST_MIME)
&& !(data->set.keep_post & CURL_REDIR_POST_301)) {
infof(data, "Switch from POST to GET\n");
- data->set.httpreq = HTTPREQ_GET;
+ data->state.httpreq = HTTPREQ_GET;
}
break;
case 302: /* Found */
@@ -1707,12 +1709,12 @@ CURLcode Curl_follow(struct Curl_easy *data,
* This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
* can be overridden with CURLOPT_POSTREDIR.
*/
- if((data->set.httpreq == HTTPREQ_POST
- || data->set.httpreq == HTTPREQ_POST_FORM
- || data->set.httpreq == HTTPREQ_POST_MIME)
+ if((data->state.httpreq == HTTPREQ_POST
+ || data->state.httpreq == HTTPREQ_POST_FORM
+ || data->state.httpreq == HTTPREQ_POST_MIME)
&& !(data->set.keep_post & CURL_REDIR_POST_302)) {
infof(data, "Switch from POST to GET\n");
- data->set.httpreq = HTTPREQ_GET;
+ data->state.httpreq = HTTPREQ_GET;
}
break;
@@ -1722,12 +1724,12 @@ CURLcode Curl_follow(struct Curl_easy *data,
* method is POST and the user specified to keep it as POST.
* https://github.com/curl/curl/issues/5237#issuecomment-614641049
*/
- if(data->set.httpreq != HTTPREQ_GET &&
- ((data->set.httpreq != HTTPREQ_POST &&
- data->set.httpreq != HTTPREQ_POST_FORM &&
- data->set.httpreq != HTTPREQ_POST_MIME) ||
+ if(data->state.httpreq != HTTPREQ_GET &&
+ ((data->state.httpreq != HTTPREQ_POST &&
+ data->state.httpreq != HTTPREQ_POST_FORM &&
+ data->state.httpreq != HTTPREQ_POST_MIME) ||
!(data->set.keep_post & CURL_REDIR_POST_303))) {
- data->set.httpreq = HTTPREQ_GET;
+ data->state.httpreq = HTTPREQ_GET;
data->set.upload = false;
infof(data, "Switch to %s\n",
data->set.opt_no_body?"HEAD":"GET");
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index 03c274438e..8225e617a8 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.c
@@ -122,6 +122,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "strdup.h"
#include "setopt.h"
#include "altsvc.h"
+#include "dynbuf.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -141,19 +142,21 @@ static unsigned int get_protocol_family(unsigned int protocol);
/*
- * Protocol table.
+ * Protocol table. Schemes (roughly) in 2019 popularity order:
+ *
+ * HTTPS, HTTP, FTP, FTPS, SFTP, FILE, SCP, SMTP, LDAP, IMAPS, TELNET, IMAP,
+ * LDAPS, SMTPS, TFTP, SMB, POP3, GOPHER POP3S, RTSP, RTMP, SMBS, DICT
*/
-
static const struct Curl_handler * const protocols[] = {
-#ifndef CURL_DISABLE_HTTP
- &Curl_handler_http,
-#endif
-
#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
&Curl_handler_https,
#endif
+#ifndef CURL_DISABLE_HTTP
+ &Curl_handler_http,
+#endif
+
#ifndef CURL_DISABLE_FTP
&Curl_handler_ftp,
#endif
@@ -162,12 +165,23 @@ static const struct Curl_handler * const protocols[] = {
&Curl_handler_ftps,
#endif
-#ifndef CURL_DISABLE_TELNET
- &Curl_handler_telnet,
+#if defined(USE_SSH)
+ &Curl_handler_sftp,
#endif
-#ifndef CURL_DISABLE_DICT
- &Curl_handler_dict,
+#ifndef CURL_DISABLE_FILE
+ &Curl_handler_file,
+#endif
+
+#if defined(USE_SSH) && !defined(USE_WOLFSSH)
+ &Curl_handler_scp,
+#endif
+
+#ifndef CURL_DISABLE_SMTP
+ &Curl_handler_smtp,
+#ifdef USE_SSL
+ &Curl_handler_smtps,
+#endif
#endif
#ifndef CURL_DISABLE_LDAP
@@ -179,22 +193,6 @@ static const struct Curl_handler * const protocols[] = {
#endif
#endif
-#ifndef CURL_DISABLE_FILE
- &Curl_handler_file,
-#endif
-
-#ifndef CURL_DISABLE_TFTP
- &Curl_handler_tftp,
-#endif
-
-#if defined(USE_SSH) && !defined(USE_WOLFSSH)
- &Curl_handler_scp,
-#endif
-
-#if defined(USE_SSH)
- &Curl_handler_sftp,
-#endif
-
#ifndef CURL_DISABLE_IMAP
&Curl_handler_imap,
#ifdef USE_SSL
@@ -202,6 +200,14 @@ static const struct Curl_handler * const protocols[] = {
#endif
#endif
+#ifndef CURL_DISABLE_TELNET
+ &Curl_handler_telnet,
+#endif
+
+#ifndef CURL_DISABLE_TFTP
+ &Curl_handler_tftp,
+#endif
+
#ifndef CURL_DISABLE_POP3
&Curl_handler_pop3,
#ifdef USE_SSL
@@ -218,25 +224,18 @@ static const struct Curl_handler * const protocols[] = {
#endif
#endif
-#ifndef CURL_DISABLE_SMTP
- &Curl_handler_smtp,
-#ifdef USE_SSL
- &Curl_handler_smtps,
-#endif
-#endif
-
#ifndef CURL_DISABLE_RTSP
&Curl_handler_rtsp,
#endif
-#ifndef CURL_DISABLE_GOPHER
- &Curl_handler_gopher,
-#endif
-
#ifdef CURL_ENABLE_MQTT
&Curl_handler_mqtt,
#endif
+#ifndef CURL_DISABLE_GOPHER
+ &Curl_handler_gopher,
+#endif
+
#ifdef USE_LIBRTMP
&Curl_handler_rtmp,
&Curl_handler_rtmpt,
@@ -246,6 +245,10 @@ static const struct Curl_handler * const protocols[] = {
&Curl_handler_rtmpts,
#endif
+#ifndef CURL_DISABLE_DICT
+ &Curl_handler_dict,
+#endif
+
(struct Curl_handler *) NULL
};
@@ -278,10 +281,16 @@ void Curl_freeset(struct Curl_easy *data)
{
/* Free all dynamic strings stored in the data->set substructure. */
enum dupstring i;
+ enum dupblob j;
+
for(i = (enum dupstring)0; i < STRING_LAST; i++) {
Curl_safefree(data->set.str[i]);
}
+ for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
+ Curl_safefree(data->set.blobs[j]);
+ }
+
if(data->change.referer_alloc) {
Curl_safefree(data->change.referer);
data->change.referer_alloc = FALSE;
@@ -380,7 +389,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
up_free(data);
Curl_safefree(data->state.buffer);
- Curl_safefree(data->state.headerbuff);
+ Curl_dyn_free(&data->state.headerb);
Curl_safefree(data->state.ulbuf);
Curl_flush_cookies(data, TRUE);
#ifdef USE_ALTSVC
@@ -407,9 +416,20 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
+ Curl_safefree(data->state.aptr.proxyuserpwd);
+ Curl_safefree(data->state.aptr.uagent);
+ Curl_safefree(data->state.aptr.userpwd);
+ Curl_safefree(data->state.aptr.accept_encoding);
+ Curl_safefree(data->state.aptr.te);
+ Curl_safefree(data->state.aptr.rangeline);
+ Curl_safefree(data->state.aptr.ref);
+ Curl_safefree(data->state.aptr.host);
+ Curl_safefree(data->state.aptr.cookiehost);
+ Curl_safefree(data->state.aptr.rtsp_transport);
+
#ifndef CURL_DISABLE_DOH
- free(data->req.doh.probe[0].serverdoh.memory);
- free(data->req.doh.probe[1].serverdoh.memory);
+ Curl_dyn_free(&data->req.doh.probe[0].serverdoh);
+ Curl_dyn_free(&data->req.doh.probe[1].serverdoh);
curl_slist_free_all(data->req.doh.headers);
#endif
@@ -453,7 +473,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->postfieldsize = -1; /* unknown size */
set->maxredirs = -1; /* allow any amount by default */
- set->httpreq = HTTPREQ_GET; /* Default HTTP request */
+ set->method = HTTPREQ_GET; /* Default HTTP request */
set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
#ifndef CURL_DISABLE_FTP
set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
@@ -492,7 +512,9 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
type */
set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
default */
+#ifndef CURL_DISABLE_PROXY
set->proxy_ssl = set->ssl;
+#endif
set->new_file_perms = 0644; /* Default permissions */
set->new_directory_perms = 0755; /* Default permissions */
@@ -601,38 +623,22 @@ CURLcode Curl_open(struct Curl_easy **curl)
return result;
}
- /* We do some initial setup here, all those fields that can't be just 0 */
-
- data->state.buffer = malloc(READBUFFER_SIZE + 1);
- if(!data->state.buffer) {
- DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
- result = CURLE_OUT_OF_MEMORY;
- }
- else {
- data->state.headerbuff = malloc(HEADERSIZE);
- if(!data->state.headerbuff) {
- DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
- result = CURLE_OUT_OF_MEMORY;
- }
- else {
- result = Curl_init_userdefined(data);
-
- data->state.headersize = HEADERSIZE;
- Curl_convert_init(data);
- Curl_initinfo(data);
+ result = Curl_init_userdefined(data);
+ if(!result) {
+ Curl_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER);
+ Curl_convert_init(data);
+ Curl_initinfo(data);
- /* most recent connection is not yet defined */
- data->state.lastconnect = NULL;
+ /* most recent connection is not yet defined */
+ data->state.lastconnect = NULL;
- data->progress.flags |= PGRS_HIDE;
- data->state.current_speed = -1; /* init to negative == impossible */
- }
+ data->progress.flags |= PGRS_HIDE;
+ data->state.current_speed = -1; /* init to negative == impossible */
}
if(result) {
Curl_resolver_cleanup(data->state.resolver);
- free(data->state.buffer);
- free(data->state.headerbuff);
+ Curl_dyn_free(&data->state.headerb);
Curl_freeset(data);
free(data);
data = NULL;
@@ -684,9 +690,7 @@ static void conn_reset_all_postponed_data(struct connectdata *conn)
static void conn_shutdown(struct connectdata *conn)
{
- if(!conn)
- return;
-
+ DEBUGASSERT(conn);
infof(conn->data, "Closing connection %ld\n", conn->connection_id);
DEBUGASSERT(conn->data);
@@ -707,54 +711,40 @@ static void conn_shutdown(struct connectdata *conn)
Curl_closesocket(conn, conn->tempsock[0]);
if(CURL_SOCKET_BAD != conn->tempsock[1])
Curl_closesocket(conn, conn->tempsock[1]);
-
- /* unlink ourselves. this should be called last since other shutdown
- procedures need a valid conn->data and this may clear it. */
- Curl_conncache_remove_conn(conn->data, conn, TRUE);
}
static void conn_free(struct connectdata *conn)
{
- if(!conn)
- return;
+ DEBUGASSERT(conn);
Curl_free_idnconverted_hostname(&conn->host);
Curl_free_idnconverted_hostname(&conn->conn_to_host);
+#ifndef CURL_DISABLE_PROXY
Curl_free_idnconverted_hostname(&conn->http_proxy.host);
Curl_free_idnconverted_hostname(&conn->socks_proxy.host);
-
- Curl_safefree(conn->user);
- Curl_safefree(conn->passwd);
- Curl_safefree(conn->sasl_authzid);
- Curl_safefree(conn->options);
Curl_safefree(conn->http_proxy.user);
Curl_safefree(conn->socks_proxy.user);
Curl_safefree(conn->http_proxy.passwd);
Curl_safefree(conn->socks_proxy.passwd);
- Curl_safefree(conn->allocptr.proxyuserpwd);
- Curl_safefree(conn->allocptr.uagent);
- Curl_safefree(conn->allocptr.userpwd);
- Curl_safefree(conn->allocptr.accept_encoding);
- Curl_safefree(conn->allocptr.te);
- Curl_safefree(conn->allocptr.rangeline);
- Curl_safefree(conn->allocptr.ref);
- Curl_safefree(conn->allocptr.host);
- Curl_safefree(conn->allocptr.cookiehost);
- Curl_safefree(conn->allocptr.rtsp_transport);
- Curl_safefree(conn->trailer);
+ Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
+ Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
+ Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
+#endif
+ Curl_safefree(conn->user);
+ Curl_safefree(conn->passwd);
+ Curl_safefree(conn->sasl_authzid);
+ Curl_safefree(conn->options);
+ Curl_dyn_free(&conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
Curl_safefree(conn->hostname_resolve);
Curl_safefree(conn->secondaryhostname);
- Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
- Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
Curl_safefree(conn->connect_state);
conn_reset_all_postponed_data(conn);
Curl_llist_destroy(&conn->easyq, NULL);
Curl_safefree(conn->localdev);
Curl_free_primary_ssl_config(&conn->ssl_config);
- Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
#ifdef USE_UNIX_SOCKETS
Curl_safefree(conn->unix_domain_socket);
@@ -783,13 +773,17 @@ static void conn_free(struct connectdata *conn)
CURLcode Curl_disconnect(struct Curl_easy *data,
struct connectdata *conn, bool dead_connection)
{
- if(!conn)
- return CURLE_OK; /* this is closed and fine already */
+ /* there must be a connection to close */
+ DEBUGASSERT(conn);
- if(!data) {
- DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
- return CURLE_OK;
- }
+ /* it must be removed from the connection cache */
+ DEBUGASSERT(!conn->bundle);
+
+ /* there must be an associated transfer */
+ DEBUGASSERT(data);
+
+ /* the transfer must be detached from the connection */
+ DEBUGASSERT(!data->conn);
/*
* If this connection isn't marked to force-close, leave it open if there
@@ -805,16 +799,11 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
conn->dns_entry = NULL;
}
- Curl_hostcache_prune(data); /* kill old DNS cache entries */
-
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
/* Cleanup NTLM connection-related data */
Curl_http_auth_cleanup_ntlm(conn);
-#endif
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
/* Cleanup NEGOTIATE connection-related data */
Curl_http_auth_cleanup_negotiate(conn);
-#endif
/* the protocol specific disconnect handler and conn_shutdown need a transfer
for the connection! */
@@ -876,8 +865,8 @@ static int IsMultiplexingPossible(const struct Curl_easy *handle,
#ifndef CURL_DISABLE_PROXY
static bool
-proxy_info_matches(const struct proxy_info* data,
- const struct proxy_info* needle)
+proxy_info_matches(const struct proxy_info *data,
+ const struct proxy_info *needle)
{
if((data->proxytype == needle->proxytype) &&
(data->port == needle->port) &&
@@ -888,8 +877,8 @@ proxy_info_matches(const struct proxy_info* data,
}
static bool
-socks_proxy_info_matches(const struct proxy_info* data,
- const struct proxy_info* needle)
+socks_proxy_info_matches(const struct proxy_info *data,
+ const struct proxy_info *needle)
{
if(!proxy_info_matches(data, needle))
return FALSE;
@@ -1011,8 +1000,12 @@ static int call_extract_if_dead(struct connectdata *conn, void *param)
static void prune_dead_connections(struct Curl_easy *data)
{
struct curltime now = Curl_now();
- timediff_t elapsed =
+ timediff_t elapsed;
+
+ CONNCACHE_LOCK(data);
+ elapsed =
Curl_timediff(now, data->state.conn_cache->last_cleanup);
+ CONNCACHE_UNLOCK(data);
if(elapsed >= 1000L) {
struct prunedead prune;
@@ -1020,10 +1013,17 @@ static void prune_dead_connections(struct Curl_easy *data)
prune.extracted = NULL;
while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
call_extract_if_dead)) {
+ /* unlocked */
+
+ /* remove connection from cache */
+ Curl_conncache_remove_conn(data, prune.extracted, TRUE);
+
/* disconnect it */
(void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
}
+ CONNCACHE_LOCK(data);
data->state.conn_cache->last_cleanup = now;
+ CONNCACHE_UNLOCK(data);
}
}
@@ -1056,10 +1056,14 @@ ConnectionExists(struct Curl_easy *data,
bool wantNTLMhttp = ((data->state.authhost.want &
(CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
(needle->handler->protocol & PROTO_FAMILY_HTTP));
+#ifndef CURL_DISABLE_PROXY
bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
((data->state.authproxy.want &
(CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
(needle->handler->protocol & PROTO_FAMILY_HTTP)));
+#else
+ bool wantProxyNTLMhttp = FALSE;
+#endif
#endif
*force_reuse = FALSE;
@@ -1083,7 +1087,7 @@ ConnectionExists(struct Curl_easy *data,
if(data->set.pipewait) {
infof(data, "Server doesn't support multiplex yet, wait\n");
*waitpipe = TRUE;
- Curl_conncache_unlock(data);
+ CONNCACHE_UNLOCK(data);
return FALSE; /* no re-use */
}
@@ -1156,7 +1160,8 @@ ConnectionExists(struct Curl_easy *data,
continue;
if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
continue;
- if(needle->abstract_unix_socket != check->abstract_unix_socket)
+ if(needle->bits.abstract_unix_socket !=
+ check->bits.abstract_unix_socket)
continue;
}
else if(check->unix_domain_socket)
@@ -1167,10 +1172,11 @@ ConnectionExists(struct Curl_easy *data,
(check->handler->flags&PROTOPT_SSL))
/* don't do mixed SSL and non-SSL connections */
if(get_protocol_family(check->handler->protocol) !=
- needle->handler->protocol || !check->tls_upgraded)
+ needle->handler->protocol || !check->bits.tls_upgraded)
/* except protocols that have been upgraded via TLS */
continue;
+#ifndef CURL_DISABLE_PROXY
if(needle->bits.httpproxy != check->bits.httpproxy ||
needle->bits.socksproxy != check->bits.socksproxy)
continue;
@@ -1179,7 +1185,7 @@ ConnectionExists(struct Curl_easy *data,
!socks_proxy_info_matches(&needle->socks_proxy,
&check->socks_proxy))
continue;
-
+#endif
if(needle->bits.conn_to_host != check->bits.conn_to_host)
/* don't mix connections that use the "connect to host" feature and
* connections that don't use this feature */
@@ -1190,6 +1196,7 @@ ConnectionExists(struct Curl_easy *data,
* connections that don't use this feature */
continue;
+#ifndef CURL_DISABLE_PROXY
if(needle->bits.httpproxy) {
if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
continue;
@@ -1216,6 +1223,7 @@ ConnectionExists(struct Curl_easy *data,
}
}
}
+#endif
DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data));
@@ -1258,15 +1266,18 @@ ConnectionExists(struct Curl_easy *data,
}
}
- if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
- needle->bits.tunnel_proxy) {
+ if((needle->handler->flags&PROTOPT_SSL)
+#ifndef CURL_DISABLE_PROXY
+ || !needle->bits.httpproxy || needle->bits.tunnel_proxy
+#endif
+ ) {
/* The requested connection does not use a HTTP proxy or it uses SSL or
it is a non-SSL protocol tunneled or it is a non-SSL protocol which
is allowed to be upgraded via TLS */
if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
(get_protocol_family(check->handler->protocol) ==
- needle->handler->protocol && check->tls_upgraded)) &&
+ needle->handler->protocol && check->bits.tls_upgraded)) &&
(!needle->bits.conn_to_host || strcasecompare(
needle->conn_to_host.name, check->conn_to_host.name)) &&
(!needle->bits.conn_to_port ||
@@ -1328,6 +1339,7 @@ ConnectionExists(struct Curl_easy *data,
continue;
}
+#ifndef CURL_DISABLE_PROXY
/* Same for Proxy NTLM authentication */
if(wantProxyNTLMhttp) {
/* Both check->http_proxy.user and check->http_proxy.passwd can be
@@ -1343,7 +1355,7 @@ ConnectionExists(struct Curl_easy *data,
/* Proxy connection is using NTLM auth but we don't want NTLM */
continue;
}
-
+#endif
if(wantNTLMhttp || wantProxyNTLMhttp) {
/* Credentials are already checked, we can use this connection */
chosen = check;
@@ -1407,11 +1419,12 @@ ConnectionExists(struct Curl_easy *data,
if(chosen) {
/* mark it as used before releasing the lock */
chosen->data = data; /* own it! */
- Curl_conncache_unlock(data);
+ Curl_attach_connnection(data, chosen);
+ CONNCACHE_UNLOCK(data);
*usethis = chosen;
return TRUE; /* yes, we found one to use! */
}
- Curl_conncache_unlock(data);
+ CONNCACHE_UNLOCK(data);
if(foundPendingCandidate && data->set.pipewait) {
infof(data,
@@ -1430,8 +1443,10 @@ void Curl_verboseconnect(struct connectdata *conn)
{
if(conn->data->set.verbose)
infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
+#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->ip_addr_str, conn->port, conn->connection_id);
@@ -1578,8 +1593,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->ssl_extra = ssl;
conn->ssl[0].backend = (void *)ssl;
conn->ssl[1].backend = (void *)(ssl + sslsize);
+#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize);
conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize);
+#endif
}
#endif
@@ -1618,10 +1635,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->data = data; /* Setup the association between this connection
and the Curl_easy */
+#ifndef CURL_DISABLE_PROXY
conn->http_proxy.proxytype = data->set.proxytype;
conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
-#if !defined(CURL_DISABLE_PROXY)
/* note that these two proxy bits are now just on what looks to be
requested, they may be altered down the road */
conn->bits.proxy = (data->set.str[STRING_PROXY] &&
@@ -1652,10 +1669,12 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl_config.verifystatus =
data->set.proxy_ssl.primary.verifystatus;
conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
+#endif
conn->ip_version = data->set.ipver;
conn->bits.connect_only = data->set.connect_only;
conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
@@ -2001,7 +2020,7 @@ static CURLcode setup_range(struct Curl_easy *data)
*/
static CURLcode setup_connection_internals(struct connectdata *conn)
{
- const struct Curl_handler * p;
+ const struct Curl_handler *p;
CURLcode result;
/* Perform setup complement if some. */
@@ -2348,24 +2367,14 @@ static CURLcode parse_proxy(struct Curl_easy *data,
static CURLcode parse_proxy_auth(struct Curl_easy *data,
struct connectdata *conn)
{
- char proxyuser[MAX_CURL_USER_LENGTH]="";
- char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
- CURLcode result;
-
- if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
- strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
- MAX_CURL_USER_LENGTH);
- proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
- }
- if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
- strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
- MAX_CURL_PASSWORD_LENGTH);
- proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
- }
+ char *proxyuser = data->set.str[STRING_PROXYUSERNAME];
+ char *proxypasswd = data->set.str[STRING_PROXYPASSWORD];
+ CURLcode result = CURLE_OK;
- result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
- FALSE);
- if(!result)
+ if(proxyuser)
+ result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
+ FALSE);
+ if(!result && proxypasswd)
result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
NULL, FALSE);
return result;
@@ -2585,6 +2594,12 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len,
size_t plen;
size_t olen;
+ /* the input length check is because this is called directcly from setopt
+ and isn't going through the regular string length check */
+ size_t llen = strlen(login);
+ if(llen > CURL_MAX_INPUT_LENGTH)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
/* Attempt to find the password separator */
if(passwdp) {
psep = strchr(login, ':');
@@ -2781,12 +2796,14 @@ static CURLcode override_login(struct Curl_easy *data,
/* for updated strings, we update them in the URL */
if(user_changed) {
- uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, 0);
+ uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp,
+ CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
}
if(passwd_changed) {
- uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, 0);
+ uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp,
+ CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
}
@@ -3159,7 +3176,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
else {
bool longpath = FALSE;
hostaddr->addr = Curl_unix2addr(path, &longpath,
- conn->abstract_unix_socket);
+ conn->bits.abstract_unix_socket);
if(hostaddr->addr)
hostaddr->inuse++;
else {
@@ -3177,6 +3194,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
}
else
#endif
+
if(!conn->bits.proxy) {
struct hostname *connhost;
if(conn->bits.conn_to_host)
@@ -3205,10 +3223,11 @@ static CURLcode resolve_server(struct Curl_easy *data,
else if(!hostaddr) {
failf(data, "Couldn't resolve host '%s'", connhost->dispname);
- result = CURLE_COULDNT_RESOLVE_HOST;
+ result = CURLE_COULDNT_RESOLVE_HOST;
/* don't return yet, we need to clean up the timeout first */
}
}
+#ifndef CURL_DISABLE_PROXY
else {
/* This is a proxy that hasn't been resolved yet. */
@@ -3234,6 +3253,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
/* don't return yet, we need to clean up the timeout first */
}
}
+#endif
DEBUGASSERT(conn->dns_entry == NULL);
conn->dns_entry = hostaddr;
}
@@ -3249,16 +3269,17 @@ static CURLcode resolve_server(struct Curl_easy *data,
static void reuse_conn(struct connectdata *old_conn,
struct connectdata *conn)
{
+#ifndef CURL_DISABLE_PROXY
Curl_free_idnconverted_hostname(&old_conn->http_proxy.host);
Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host);
free(old_conn->http_proxy.host.rawalloc);
free(old_conn->socks_proxy.host.rawalloc);
-
+ Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
+#endif
/* free the SSL config struct from this connection struct as this was
allocated in vain and is targeted for destruction */
Curl_free_primary_ssl_config(&old_conn->ssl_config);
- Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
conn->data = old_conn->data;
@@ -3275,6 +3296,7 @@ static void reuse_conn(struct connectdata *old_conn,
old_conn->passwd = NULL;
}
+#ifndef CURL_DISABLE_PROXY
conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
if(conn->bits.proxy_user_passwd) {
/* use the new proxy user name and proxy password though */
@@ -3291,6 +3313,11 @@ static void reuse_conn(struct connectdata *old_conn,
old_conn->http_proxy.passwd = NULL;
old_conn->socks_proxy.passwd = NULL;
}
+ Curl_safefree(old_conn->http_proxy.user);
+ Curl_safefree(old_conn->socks_proxy.user);
+ Curl_safefree(old_conn->http_proxy.passwd);
+ Curl_safefree(old_conn->socks_proxy.passwd);
+#endif
/* host can change, when doing keepalive with a proxy or if the case is
different this time etc */
@@ -3318,10 +3345,6 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->user);
Curl_safefree(old_conn->passwd);
Curl_safefree(old_conn->options);
- Curl_safefree(old_conn->http_proxy.user);
- Curl_safefree(old_conn->socks_proxy.user);
- Curl_safefree(old_conn->http_proxy.passwd);
- Curl_safefree(old_conn->socks_proxy.passwd);
Curl_safefree(old_conn->localdev);
Curl_llist_destroy(&old_conn->easyq, NULL);
@@ -3406,7 +3429,7 @@ static CURLcode create_conn(struct Curl_easy *data,
result = CURLE_OUT_OF_MEMORY;
goto out;
}
- conn->abstract_unix_socket = data->set.abstract_unix_socket;
+ conn->bits.abstract_unix_socket = data->set.abstract_unix_socket;
}
#endif
@@ -3416,7 +3439,6 @@ static CURLcode create_conn(struct Curl_easy *data,
result = create_conn_helper_init_proxy(conn);
if(result)
goto out;
-#endif
/*************************************************************
* If the protocol is using SSL and HTTP proxy is used, we set
@@ -3424,6 +3446,7 @@ static CURLcode create_conn(struct Curl_easy *data,
*************************************************************/
if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
conn->bits.tunnel_proxy = TRUE;
+#endif
/*************************************************************
* Figure out the remote port number and fix it in the URL
@@ -3462,6 +3485,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if(result)
goto out;
}
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy) {
result = Curl_idnconvert_hostname(conn, &conn->http_proxy.host);
if(result)
@@ -3472,6 +3496,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if(result)
goto out;
}
+#endif
/*************************************************************
* Check whether the host and the "connect to host" are equal.
@@ -3490,6 +3515,7 @@ static CURLcode create_conn(struct Curl_easy *data,
conn->bits.conn_to_port = FALSE;
}
+#ifndef CURL_DISABLE_PROXY
/*************************************************************
* If the "connect to" feature is used with an HTTP proxy,
* we set the tunnel_proxy bit.
@@ -3497,6 +3523,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
conn->bits.httpproxy)
conn->bits.tunnel_proxy = TRUE;
+#endif
/*************************************************************
* Setup internals depending on protocol. Needs to be done after
@@ -3529,6 +3556,7 @@ static CURLcode create_conn(struct Curl_easy *data,
if(!result) {
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
+ Curl_attach_connnection(data, conn);
result = Curl_conncache_add_conn(data->state.conn_cache, conn);
if(result)
goto out;
@@ -3543,7 +3571,6 @@ static CURLcode create_conn(struct Curl_easy *data,
(void)conn->handler->done(conn, result, FALSE);
goto out;
}
- Curl_attach_connnection(data, conn);
Curl_setup_transfer(data, -1, -1, FALSE, -1);
}
@@ -3564,49 +3591,59 @@ static CURLcode create_conn(struct Curl_easy *data,
copies will be separately allocated.
*/
data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
- data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
- data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
- data->set.proxy_ssl.primary.random_file =
- data->set.str[STRING_SSL_RANDOM_FILE];
data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
- data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
- data->set.proxy_ssl.primary.cipher_list =
- data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
- data->set.proxy_ssl.primary.cipher_list13 =
- data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+
+#ifndef CURL_DISABLE_PROXY
+ data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
+ data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
+ data->set.proxy_ssl.primary.random_file =
+ data->set.str[STRING_SSL_RANDOM_FILE];
+ data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+ data->set.proxy_ssl.primary.cipher_list =
+ data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
+ data->set.proxy_ssl.primary.cipher_list13 =
+ data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.proxy_ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
-
- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
- data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
- data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
- data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
- data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
- data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
- data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
+ data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
+ data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
+#endif
+ data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
+ data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
+ data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
+ data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
+ data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
+ data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
+ data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
+ data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
#ifdef USE_TLS_SRP
data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
- data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
+#ifndef CURL_DISABLE_PROXY
+ data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif
+#endif
+
+ data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
+ data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG];
+ data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG];
if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
&conn->ssl_config)) {
@@ -3614,11 +3651,13 @@ static CURLcode create_conn(struct Curl_easy *data,
goto out;
}
+#ifndef CURL_DISABLE_PROXY
if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
&conn->proxy_ssl_config)) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
+#endif
prune_dead_connections(data);
@@ -3656,12 +3695,17 @@ static CURLcode create_conn(struct Curl_easy *data,
conn = conn_temp;
*in_connect = conn;
+#ifndef CURL_DISABLE_PROXY
infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
conn->connection_id,
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);
+ conn->host.dispname);
+#else
+ infof(data, "Re-using existing connection! (#%ld) with host %s\n",
+ conn->connection_id, conn->host.dispname);
+#endif
}
else {
/* We have decided that we want a new connection. However, we may not
@@ -3693,7 +3737,7 @@ static CURLcode create_conn(struct Curl_easy *data,
/* The bundle is full. Extract the oldest connection. */
conn_candidate = Curl_conncache_extract_bundle(data, bundle);
- Curl_conncache_unlock(data);
+ CONNCACHE_UNLOCK(data);
if(conn_candidate)
(void)Curl_disconnect(data, conn_candidate,
@@ -3705,7 +3749,7 @@ static CURLcode create_conn(struct Curl_easy *data,
}
}
else
- Curl_conncache_unlock(data);
+ CONNCACHE_UNLOCK(data);
}
@@ -3739,6 +3783,8 @@ static CURLcode create_conn(struct Curl_easy *data,
* This is a brand new connection, so let's store it in the connection
* cache of ours!
*/
+ Curl_attach_connnection(data, conn);
+
result = Curl_conncache_add_conn(data->state.conn_cache, conn);
if(result)
goto out;
@@ -3790,10 +3836,12 @@ static CURLcode create_conn(struct Curl_easy *data,
/* Strip trailing dots. resolve_server copied the name. */
strip_trailing_dot(&conn->host);
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy)
strip_trailing_dot(&conn->http_proxy.host);
if(conn->bits.socksproxy)
strip_trailing_dot(&conn->socks_proxy.host);
+#endif
if(conn->bits.conn_to_host)
strip_trailing_dot(&conn->conn_to_host);
@@ -3824,22 +3872,23 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
}
*protocol_done = FALSE; /* default to not done */
+#ifndef CURL_DISABLE_PROXY
/* set proxy_connect_closed to false unconditionally already here since it
is used strictly to provide extra information to a parent function in the
case of proxy CONNECT failures and we must make sure we don't have it
lingering set from a previous invoke */
conn->bits.proxy_connect_closed = FALSE;
-
+#endif
/*
* Set user-agent. Used for HTTP, but since we can attempt to tunnel
* basically anything through a http proxy we can't limit this based on
* protocol.
*/
if(data->set.str[STRING_USERAGENT]) {
- Curl_safefree(conn->allocptr.uagent);
- conn->allocptr.uagent =
+ Curl_safefree(data->state.aptr.uagent);
+ data->state.aptr.uagent =
aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
- if(!conn->allocptr.uagent)
+ if(!data->state.aptr.uagent)
return CURLE_OUT_OF_MEMORY;
}
@@ -3893,7 +3942,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
result = create_conn(data, &conn, asyncp);
if(!result) {
- if(CONN_INUSE(conn))
+ if(CONN_INUSE(conn) > 1)
/* multiplexed */
*protocol_done = TRUE;
else if(!*asyncp) {
@@ -3910,11 +3959,10 @@ CURLcode Curl_connect(struct Curl_easy *data,
else if(result && conn) {
/* We're not allowed to return failure with memory left allocated in the
connectdata struct, free those here */
+ Curl_detach_connnection(data);
+ Curl_conncache_remove_conn(data, conn, TRUE);
Curl_disconnect(data, conn, TRUE);
}
- else if(!result && !data->conn)
- /* FILE: transfers already have the connection attached */
- Curl_attach_connnection(data, conn);
return result;
}
@@ -3933,6 +3981,11 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
{
struct SingleRequest *k = &data->req;
+ /* if this is a pushed stream, we need this: */
+ CURLcode result = Curl_preconnect(data);
+ if(result)
+ return result;
+
if(conn) {
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
use */
@@ -3945,30 +3998,17 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
data->state.done = FALSE; /* *_done() is not called yet */
data->state.expect100header = FALSE;
-
if(data->set.opt_no_body)
/* in HTTP lingo, no body means using the HEAD request... */
- data->set.httpreq = HTTPREQ_HEAD;
- else if(HTTPREQ_HEAD == data->set.httpreq)
- /* ... but if unset there really is no perfect method that is the
- "opposite" of HEAD but in reality most people probably think GET
- then. The important thing is that we can't let it remain HEAD if the
- opt_no_body is set FALSE since then we'll behave wrong when getting
- HTTP. */
- data->set.httpreq = HTTPREQ_GET;
+ data->state.httpreq = HTTPREQ_HEAD;
k->start = Curl_now(); /* start time */
k->now = k->start; /* current time is now */
k->header = TRUE; /* assume header */
-
k->bytecount = 0;
-
- k->buf = data->state.buffer;
- k->hbufp = data->state.headerbuff;
k->ignorebody = FALSE;
Curl_speedinit(data);
-
Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0);
diff --git a/libs/libcurl/src/url.h b/libs/libcurl/src/url.h
index 5000c512a8..1941dc6a4f 100644
--- a/libs/libcurl/src/url.h
+++ b/libs/libcurl/src/url.h
@@ -47,7 +47,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn);
CURLcode Curl_open(struct Curl_easy **curl);
CURLcode Curl_init_userdefined(struct Curl_easy *data);
-void Curl_freeset(struct Curl_easy * data);
+void Curl_freeset(struct Curl_easy *data);
CURLcode Curl_uc_to_curlcode(CURLUcode uc);
CURLcode Curl_close(struct Curl_easy **datap); /* opposite of curl_open() */
CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect);
@@ -77,6 +77,10 @@ void Curl_free_idnconverted_hostname(struct hostname *host);
void Curl_verboseconnect(struct connectdata *conn);
#endif
+#ifdef CURL_DISABLE_PROXY
+#define CONNECT_PROXY_SSL() FALSE
+#else
+
#define CONNECT_PROXY_SSL()\
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
!conn->bits.proxy_ssl_connected[sockindex])
@@ -88,5 +92,6 @@ void Curl_verboseconnect(struct connectdata *conn);
#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
!conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
+#endif /* !CURL_DISABLE_PROXY */
#endif /* HEADER_CURL_URL_H */
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c
index 506e244dc4..37937fbca7 100644
--- a/libs/libcurl/src/urlapi.c
+++ b/libs/libcurl/src/urlapi.c
@@ -606,7 +606,7 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
char dest[16]; /* fits a binary IPv6 address */
#endif
const char *l = "0123456789abcdefABCDEF:.";
- if(hlen < 5) /* '[::1]' is the shortest possible valid string */
+ if(hlen < 4) /* '[::]' is the shortest possible valid string */
return CURLUE_MALFORMED_INPUT;
hostname++;
hlen -= 2;
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index 50d8b84a62..74b43abaa8 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.h
@@ -81,7 +81,7 @@
*/
#define RESP_TIMEOUT (120*1000)
-/* Max string intput length is a precaution against abuse and to detect junk
+/* Max string input length is a precaution against abuse and to detect junk
input easier and better. */
#define CURL_MAX_INPUT_LENGTH 8000000
@@ -104,6 +104,7 @@
#include "hostip.h"
#include "hash.h"
#include "splay.h"
+#include "dynbuf.h"
/* return the count of bytes sent, or -1 on error */
typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
@@ -152,10 +153,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#include <libssh2_sftp.h>
#endif /* HAVE_LIBSSH2_H */
-/* Initial size of the buffer to store headers in, it'll be enlarged in case
- of need. */
-#define HEADERSIZE 256
-
#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
#define GOOD_EASY_HANDLE(x) \
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
@@ -243,11 +240,14 @@ struct ssl_config_data {
long certverifyresult; /* result from the certificate verification */
char *CRLfile; /* CRL to check certificate revocation */
char *issuercert;/* optional issuer certificate filename */
+ struct curl_blob *issuercert_blob;
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
void *fsslctxp; /* parameter for call back */
char *cert; /* client certificate file name */
+ struct curl_blob *cert_blob;
char *cert_type; /* format for certificate (default: PEM)*/
char *key; /* private key file name */
+ struct curl_blob *key_blob;
char *key_type; /* format for private key (default: PEM) */
char *key_passwd; /* plain text private key password */
#ifdef USE_TLS_SRP
@@ -262,6 +262,7 @@ struct ssl_config_data {
BIT(no_partialchain); /* don't accept partial certificate chains */
BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
list errors */
+ BIT(native_ca_store); /* use the native ca store of operating system */
};
struct ssl_general_config {
@@ -419,11 +420,23 @@ struct negotiatedata {
* Boolean values that concerns this connection.
*/
struct ConnectBits {
- /* always modify bits.close with the connclose() and connkeep() macros! */
- bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
- is complete */
bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
the first time on the first connect function call */
+#ifndef CURL_DISABLE_PROXY
+ bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
+ is complete */
+ BIT(httpproxy); /* if set, this transfer is done through a http proxy */
+ BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
+ BIT(proxy_user_passwd); /* user+password for the proxy? */
+ BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy.
+ This is implicit when SSL-protocols are used through
+ proxies, but can also be enabled explicitly by
+ apps */
+ BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection
+ in a CONNECT request with auth, so that
+ libcurl should reconnect and continue. */
+#endif
+ /* always modify bits.close with the connclose() and connkeep() macros! */
BIT(close); /* if set, we close the connection after this request */
BIT(reuse); /* if set, this is a re-used connection */
BIT(altused); /* this is an alt-svc "redirect" */
@@ -432,10 +445,7 @@ struct ConnectBits {
BIT(conn_to_port); /* if set, this connection has a "connect to port"
that overrides the port in the URL (remote port) */
BIT(proxy); /* if set, this transfer is done through a proxy - any type */
- BIT(httpproxy); /* if set, this transfer is done through a http proxy */
- BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
BIT(user_passwd); /* do we use user+password for this connection? */
- BIT(proxy_user_passwd); /* user+password for the proxy? */
BIT(ipv6_ip); /* we communicate with a remote site specified with pure IPv6
IP address */
BIT(ipv6); /* we communicate with a site using an IPv6 address */
@@ -445,10 +455,6 @@ struct ConnectBits {
the TCP layer connect */
BIT(retry); /* this connection is about to get closed and then
re-attempted at another connection. */
- BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy.
- This is implicit when SSL-protocols are used through
- proxies, but can also be enabled explicitly by
- apps */
BIT(authneg); /* TRUE when the auth phase has started, which means
that we are creating a request with an auth header,
but it is not the final request in the auth
@@ -467,18 +473,22 @@ struct ConnectBits {
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
#endif
BIT(netrc); /* name+password provided by netrc */
- BIT(userpwd_in_url); /* name+password found in url */
- BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection
- in a CONNECT request with auth, so that
- libcurl should reconnect and continue. */
BIT(bound); /* set true if bind() has already been done on this socket/
connection */
- BIT(type_set); /* type= was used in the URL */
BIT(multiplex); /* connection is multiplexed */
BIT(tcp_fastopen); /* use TCP Fast Open */
BIT(tls_enable_npn); /* TLS NPN extension? */
BIT(tls_enable_alpn); /* TLS ALPN extension? */
BIT(connect_only);
+ BIT(doh);
+#ifdef USE_UNIX_SOCKETS
+ BIT(abstract_unix_socket);
+#endif
+ BIT(tls_upgraded);
+ BIT(sock_accepted); /* TRUE if the SECONDARYSOCKET was created with
+ accept() */
+ BIT(parallel_connect); /* set TRUE when a parallel connect attempt has
+ started (happy eyeballs) */
};
struct hostname {
@@ -556,18 +566,13 @@ enum doh_slots {
DOH_PROBE_SLOTS
};
-struct dohresponse {
- unsigned char *memory;
- size_t size;
-};
-
/* one of these for each DoH request */
struct dnsprobe {
CURL *easy;
int dnstype;
unsigned char dohbuffer[512];
size_t dohlen;
- struct dohresponse serverdoh;
+ struct dynbuf serverdoh;
};
struct dohdata {
@@ -611,12 +616,7 @@ struct SingleRequest {
written as body */
int headerline; /* counts header lines to better track the
first one */
- char *hbufp; /* points at *end* of header line */
- size_t hbuflen;
char *str; /* within buf */
- char *str_start; /* within buf */
- char *end_ptr; /* within buf */
- char *p; /* within headerbuff */
curl_off_t offset; /* possible resume offset read from the
Content-Range: header */
int httpcode; /* error code from the 'HTTP/1.? XXX' or
@@ -625,11 +625,10 @@ struct SingleRequest {
enum expect100 exp100; /* expect 100 continue state */
enum upgrade101 upgr101; /* 101 upgrade state */
- struct contenc_writer_s *writer_stack; /* Content unencoding stack. */
- /* See sec 3.5, RFC2616. */
+ /* Content unencoding stack. See sec 3.5, RFC2616. */
+ struct contenc_writer *writer_stack;
time_t timeofdoc;
long bodywrites;
- char *buf;
int keepon;
char *location; /* This points to an allocated version of the Location:
header data */
@@ -797,15 +796,10 @@ struct proxy_info {
char *passwd; /* proxy password string, allocated */
};
-#define CONNECT_BUFFER_SIZE 16384
-
/* struct for HTTP CONNECT state data */
struct http_connect_state {
- char connect_buffer[CONNECT_BUFFER_SIZE];
- int perline; /* count bytes per line */
+ struct dynbuf rcvbuf;
int keepon;
- char *line_start;
- char *ptr; /* where to store more data */
curl_off_t cl; /* size of content to read and ignore */
enum {
TUNNEL_INIT, /* init/default/no tunnel state */
@@ -885,15 +879,15 @@ struct connectdata {
/* '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
- Curl_done(). This entry will be NULL if the connection is re-used as then
+ multi_done(). This entry will be NULL if the connection is re-used as then
there is no name resolve done. */
struct Curl_dns_entry *dns_entry;
/* 'ip_addr' is the particular IP we connected to. It points to a struct
within the DNS cache, so this pointer is only valid as long as the DNS
- cache entry remains locked. It gets unlocked in Curl_done() */
- Curl_addrinfo *ip_addr;
- Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
+ cache entry remains locked. It gets unlocked in multi_done() */
+ struct Curl_addrinfo *ip_addr;
+ struct Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
/* 'ip_addr_str' is the ip_addr data as a human readable string.
It remains available as long as the connection does, which is longer than
@@ -918,10 +912,10 @@ struct connectdata {
char *secondaryhostname; /* secondary socket host name (ftp) */
struct hostname conn_to_host; /* the host to connect to. valid only if
bits.conn_to_host is set */
-
+#ifndef CURL_DISABLE_PROXY
struct proxy_info socks_proxy;
struct proxy_info http_proxy;
-
+#endif
long port; /* which port to use locally */
int remote_port; /* the remote port, not the proxy port! */
int conn_to_port; /* the remote port to connect to. valid only if
@@ -969,12 +963,16 @@ struct connectdata {
struct postponed_data postponed[2]; /* two buffers for two sockets */
#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
+#ifndef CURL_DISABLE_PROXY
struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
+#endif
#ifdef USE_SSL
void *ssl_extra; /* separately allocated backend-specific data */
#endif
struct ssl_primary_config ssl_config;
+#ifndef CURL_DISABLE_PROXY
struct ssl_primary_config proxy_ssl_config;
+#endif
struct ConnectBits bits; /* various state-flags for this connection */
/* connecttime: when connect() is called on the current IP address. Used to
@@ -983,8 +981,10 @@ struct connectdata {
struct curltime connecttime;
/* The two fields below get set in Curl_connecthost */
int num_addr; /* number of addresses to try to connect to */
- timediff_t timeoutms_per_addr; /* how long time in milliseconds to spend on
- trying to connect to each IP address */
+
+ /* how long time in milliseconds to spend on trying to connect to each IP
+ address, per family */
+ timediff_t timeoutms_per_addr[2];
const struct Curl_handler *handler; /* Connection's protocol handler */
const struct Curl_handler *given; /* The protocol first given */
@@ -1005,21 +1005,6 @@ struct connectdata {
well be the same we read from.
CURL_SOCKET_BAD disables */
- /** Dynamically allocated strings, MUST be freed before this **/
- /** struct is killed. **/
- struct dynamically_allocated_data {
- char *proxyuserpwd;
- char *uagent;
- char *accept_encoding;
- char *userpwd;
- char *rangeline;
- char *ref;
- char *host;
- char *cookiehost;
- char *rtsp_transport;
- char *te; /* TE: request header */
- } allocptr;
-
#ifdef HAVE_GSSAPI
BIT(sec_complete); /* if Kerberos is enabled for this connection */
enum protection_level command_prot;
@@ -1066,10 +1051,8 @@ struct connectdata {
/* data used for the asynch name resolve callback */
struct Curl_async async;
- /* These three are used for chunked-encoding trailer support */
- char *trailer; /* allocated buffer to store trailer in */
- int trlMax; /* allocated buffer size */
- int trlPos; /* index of where to store data */
+ /* for chunked-encoded trailer */
+ struct dynbuf trailer;
union {
struct ftp_conn ftpc;
@@ -1107,20 +1090,7 @@ struct connectdata {
int retrycount; /* number of retries on a new connection */
#ifdef USE_UNIX_SOCKETS
char *unix_domain_socket;
- BIT(abstract_unix_socket);
#endif
- BIT(tls_upgraded);
- /* the two following *_inuse fields are only flags, not counters in any way.
- If TRUE it means the channel is in use, and if FALSE it means the channel
- is up for grabs by one. */
- BIT(readchannel_inuse); /* whether the read channel is in use by an easy
- handle */
- BIT(writechannel_inuse); /* whether the write channel is in use by an easy
- handle */
- BIT(sock_accepted); /* TRUE if the SECONDARYSOCKET was created with
- accept() */
- BIT(parallel_connect); /* set TRUE when a parallel connect attempt has
- started (happy eyeballs) */
};
/* The end of connectdata. */
@@ -1242,17 +1212,6 @@ typedef enum {
RTSPREQ_LAST /* last in list */
} Curl_RtspReq;
-/*
- * Values that are generated, temporary or calculated internally for a
- * "session handle" must be defined within the 'struct UrlState'. This struct
- * will be used within the Curl_easy struct. When the 'Curl_easy'
- * struct is cloned, this data MUST NOT be copied.
- *
- * Remember that any "state" information goes globally for the curl handle.
- * Session-data MUST be put in the connectdata struct and here. */
-#define MAX_CURL_USER_LENGTH 256
-#define MAX_CURL_PASSWORD_LENGTH 256
-
struct auth {
unsigned long want; /* Bitmask set to the authentication methods wanted by
app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
@@ -1278,9 +1237,7 @@ struct Curl_http2_dep {
* BODY).
*/
struct tempbuf {
- char *buf; /* allocated buffer to keep data in when a write callback
- returns to make the connection paused */
- size_t len; /* size of the 'tempwrite' allocated buffer */
+ struct dynbuf b;
int type; /* type of the 'tempwrite' buffer as a bitmask that is used with
Curl_client_write() */
};
@@ -1290,7 +1247,8 @@ typedef enum {
EXPIRE_100_TIMEOUT,
EXPIRE_ASYNC_NAME,
EXPIRE_CONNECTTIMEOUT,
- EXPIRE_DNS_PER_NAME,
+ EXPIRE_DNS_PER_NAME, /* family1 */
+ EXPIRE_DNS_PER_NAME2, /* family2 */
EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */
EXPIRE_HAPPY_EYEBALLS,
EXPIRE_MULTI_PENDING,
@@ -1340,9 +1298,7 @@ struct UrlState {
struct curltime keeps_speed; /* for the progress meter really */
struct connectdata *lastconnect; /* The last connection, NULL if undefined */
-
- char *headerbuff; /* allocated buffer to store headers in */
- size_t headersize; /* size of the allocation */
+ struct dynbuf headerb; /* buffer to store headers in */
char *buffer; /* download buffer */
char *ulbuf; /* allocated upload buffer or NULL */
@@ -1420,13 +1376,30 @@ struct UrlState {
int stream_weight;
CURLU *uh; /* URL handle for the current parsed URL */
struct urlpieces up;
+ Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
#ifndef CURL_DISABLE_HTTP
size_t trailers_bytes_sent;
- Curl_send_buffer *trailers_buf; /* a buffer containing the compiled trailing
- headers */
+ struct dynbuf trailers_buf; /* a buffer containing the compiled trailing
+ headers */
#endif
trailers_state trailers_state; /* whether we are sending trailers
and what stage are we at */
+
+ /* Dynamically allocated strings, MUST be freed before this struct is
+ killed. */
+ struct dynamically_allocated_data {
+ char *proxyuserpwd;
+ char *uagent;
+ char *accept_encoding;
+ char *userpwd;
+ char *rangeline;
+ char *ref;
+ char *host;
+ char *cookiehost;
+ char *rtsp_transport;
+ char *te; /* TE: request header */
+ } aptr;
+
#ifdef CURLDEBUG
BIT(conncache_lock);
#endif
@@ -1601,6 +1574,16 @@ enum dupstring {
STRING_LAST /* not used, just an end-of-list marker */
};
+enum dupblob {
+ BLOB_CERT_ORIG,
+ BLOB_CERT_PROXY,
+ BLOB_KEY_ORIG,
+ BLOB_KEY_PROXY,
+ BLOB_SSL_ISSUERCERT_ORIG,
+ BLOB_SSL_ISSUERCERT_PROXY,
+ BLOB_LAST
+};
+
/* callback that gets called when this easy handle is completed within a multi
handle. Only used for internally created transfers, like for example
DoH. */
@@ -1698,11 +1681,13 @@ struct UserDefined {
the hostname and port to connect to */
curl_TimeCond timecondition; /* kind of time/date comparison */
time_t timevalue; /* what time to compare with */
- Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
+ Curl_HttpReq method; /* what kind of HTTP request (if any) is this */
long httpversion; /* when non-zero, a specific HTTP version requested to
be used in the library's request(s) */
struct ssl_config_data ssl; /* user defined SSL stuff */
+#ifndef CURL_DISABLE_PROXY
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
+#endif
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
curl_proxytype proxytype; /* what kind of proxy that is in use */
long dns_cache_timeout; /* DNS cache timeout */
@@ -1732,6 +1717,7 @@ struct UserDefined {
long new_directory_perms; /* Permissions to use when creating remote dirs */
long ssh_auth_types; /* allowed SSH auth types */
char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
+ struct curl_blob *blobs[BLOB_LAST];
unsigned int scope_id; /* Scope id for IPv6 */
long allowed_protocols;
long redir_protocols;
diff --git a/libs/libcurl/src/vauth/cleartext.c b/libs/libcurl/src/vauth/cleartext.c
index 6f452c1694..3a5c9430f4 100644
--- a/libs/libcurl/src/vauth/cleartext.c
+++ b/libs/libcurl/src/vauth/cleartext.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -81,7 +81,8 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
plen = strlen(passwd);
/* Compute binary message length. Check for overflows. */
- if(((zlen + clen) > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2)))
+ if((zlen > SIZE_T_MAX/4) || (clen > SIZE_T_MAX/4) ||
+ (plen > (SIZE_T_MAX/2 - 2)))
return CURLE_OUT_OF_MEMORY;
plainlen = zlen + clen + plen + 2;
diff --git a/libs/libcurl/src/vauth/cram.c b/libs/libcurl/src/vauth/cram.c
index 04438fa740..717d7f093d 100644
--- a/libs/libcurl/src/vauth/cram.c
+++ b/libs/libcurl/src/vauth/cram.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -96,7 +96,7 @@ CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
{
CURLcode result = CURLE_OK;
size_t chlglen = 0;
- HMAC_context *ctxt;
+ struct HMAC_context *ctxt;
unsigned char digest[MD5_DIGEST_LEN];
char *response;
diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c
index a8835705f3..b9210a8fec 100644
--- a/libs/libcurl/src/vauth/digest.c
+++ b/libs/libcurl/src/vauth/digest.c
@@ -358,7 +358,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
char **outptr, size_t *outlen)
{
size_t i;
- MD5_context *ctxt;
+ struct MD5_context *ctxt;
char *response = NULL;
unsigned char digest[MD5_DIGEST_LEN];
char HA1_hex[2 * MD5_DIGEST_LEN + 1];
diff --git a/libs/libcurl/src/vauth/digest_sspi.c b/libs/libcurl/src/vauth/digest_sspi.c
index a1090568b2..4998306ce8 100644
--- a/libs/libcurl/src/vauth/digest_sspi.c
+++ b/libs/libcurl/src/vauth/digest_sspi.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, 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
@@ -134,7 +134,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
if(status != SEC_E_OK) {
free(input_token);
- return CURLE_NOT_BUILT_IN;
+ failf(data, "SSPI: couldn't get auth info\n");
+ return CURLE_AUTH_ERROR;
}
token_max = SecurityPackage->cbMaxToken;
@@ -288,13 +289,13 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
if(strcasecompare(value, "realm")) {
/* Setup identity's domain and length */
- domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *) content);
+ domain.tchar_ptr = curlx_convert_UTF8_to_tchar((char *) content);
if(!domain.tchar_ptr)
return CURLE_OUT_OF_MEMORY;
dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
if(!dup_domain.tchar_ptr) {
- Curl_unicodefree(domain.tchar_ptr);
+ curlx_unicodefree(domain.tchar_ptr);
return CURLE_OUT_OF_MEMORY;
}
@@ -303,7 +304,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
dup_domain.tchar_ptr = NULL;
- Curl_unicodefree(domain.tchar_ptr);
+ curlx_unicodefree(domain.tchar_ptr);
}
else {
/* Unknown specifier, ignore it! */
@@ -431,8 +432,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
/* Query the security package for DigestSSP */
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
&SecurityPackage);
- if(status != SEC_E_OK)
- return CURLE_NOT_BUILT_IN;
+ if(status != SEC_E_OK) {
+ failf(data, "SSPI: couldn't get auth info\n");
+ return CURLE_AUTH_ERROR;
+ }
token_max = SecurityPackage->cbMaxToken;
@@ -580,7 +583,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
resp_buf.pvBuffer = output_token;
resp_buf.cbBuffer = curlx_uztoul(token_max);
- spn = Curl_convert_UTF8_to_tchar((char *) uripath);
+ spn = curlx_convert_UTF8_to_tchar((char *) uripath);
if(!spn) {
s_pSecFn->FreeCredentialsHandle(&credentials);
@@ -602,7 +605,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
&chlg_desc, 0,
digest->http_context,
&resp_desc, &attrs, &expiry);
- Curl_unicodefree(spn);
+ curlx_unicodefree(spn);
if(status == SEC_I_COMPLETE_NEEDED ||
status == SEC_I_COMPLETE_AND_CONTINUE)
diff --git a/libs/libcurl/src/vauth/krb5_sspi.c b/libs/libcurl/src/vauth/krb5_sspi.c
index 98041d9156..1fb6257ea9 100644
--- a/libs/libcurl/src/vauth/krb5_sspi.c
+++ b/libs/libcurl/src/vauth/krb5_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -125,7 +125,8 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
TEXT(SP_NAME_KERBEROS),
&SecurityPackage);
if(status != SEC_E_OK) {
- return CURLE_NOT_BUILT_IN;
+ failf(data, "SSPI: couldn't get auth info\n");
+ return CURLE_AUTH_ERROR;
}
krb5->token_max = SecurityPackage->cbMaxToken;
@@ -395,7 +396,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
/* Convert the user name to UTF8 when operating with Unicode */
- user_name = Curl_convert_tchar_to_UTF8(names.sUserName);
+ user_name = curlx_convert_tchar_to_UTF8(names.sUserName);
if(!user_name) {
free(trailer);
@@ -407,7 +408,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
message = malloc(messagelen);
if(!message) {
free(trailer);
- Curl_unicodefree(user_name);
+ curlx_unicodefree(user_name);
return CURLE_OUT_OF_MEMORY;
}
@@ -420,7 +421,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
outdata = htonl(max_size) | sec_layer;
memcpy(message, &outdata, sizeof(outdata));
strcpy((char *) message + sizeof(outdata), user_name);
- Curl_unicodefree(user_name);
+ curlx_unicodefree(user_name);
/* Allocate the padding */
padding = malloc(sizes.cbBlockSize);
diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c
index 8f91038064..3b46e1a468 100644
--- a/libs/libcurl/src/vauth/ntlm.c
+++ b/libs/libcurl/src/vauth/ntlm.c
@@ -600,11 +600,14 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
#endif
#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
+
+#define CURL_MD5_DIGEST_LENGTH 16 /* fixed size */
+
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) {
unsigned char ntbuffer[0x18];
unsigned char tmp[0x18];
- unsigned char md5sum[MD5_DIGEST_LENGTH];
+ unsigned char md5sum[CURL_MD5_DIGEST_LENGTH];
unsigned char entropy[8];
/* Need to create 8 bytes random data */
diff --git a/libs/libcurl/src/vauth/ntlm_sspi.c b/libs/libcurl/src/vauth/ntlm_sspi.c
index cd6cb79c14..84ea51dadb 100644
--- a/libs/libcurl/src/vauth/ntlm_sspi.c
+++ b/libs/libcurl/src/vauth/ntlm_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -105,8 +105,10 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
/* Query the security package for NTLM */
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
&SecurityPackage);
- if(status != SEC_E_OK)
- return CURLE_NOT_BUILT_IN;
+ if(status != SEC_E_OK) {
+ failf(data, "SSPI: couldn't get auth info\n");
+ return CURLE_AUTH_ERROR;
+ }
ntlm->token_max = SecurityPackage->cbMaxToken;
diff --git a/libs/libcurl/src/vauth/spnego_sspi.c b/libs/libcurl/src/vauth/spnego_sspi.c
index b9c2cf7d62..194f250f87 100644
--- a/libs/libcurl/src/vauth/spnego_sspi.c
+++ b/libs/libcurl/src/vauth/spnego_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -129,8 +129,10 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
nego->status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
TEXT(SP_NAME_NEGOTIATE),
&SecurityPackage);
- if(nego->status != SEC_E_OK)
- return CURLE_NOT_BUILT_IN;
+ if(nego->status != SEC_E_OK) {
+ failf(data, "SSPI: couldn't get auth info\n");
+ return CURLE_AUTH_ERROR;
+ }
nego->token_max = SecurityPackage->cbMaxToken;
diff --git a/libs/libcurl/src/vauth/vauth.c b/libs/libcurl/src/vauth/vauth.c
index a9c5c9c4f7..d98e66c68a 100644
--- a/libs/libcurl/src/vauth/vauth.c
+++ b/libs/libcurl/src/vauth/vauth.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -89,7 +89,7 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
}
/* Allocate our TCHAR based SPN */
- tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
+ tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn);
if(!tchar_spn) {
free(utf8_spn);
@@ -97,7 +97,7 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
}
/* Release the UTF8 variant when operating with Unicode */
- Curl_unicodefree(utf8_spn);
+ curlx_unicodefree(utf8_spn);
/* Return our newly allocated SPN */
return tchar_spn;
diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c
index 5f7b6e2e0a..e5528231c8 100644
--- a/libs/libcurl/src/vquic/ngtcp2.c
+++ b/libs/libcurl/src/vquic/ngtcp2.c
@@ -38,6 +38,9 @@
#include "strcase.h"
#include "connect.h"
#include "strerror.h"
+#include "dynbuf.h"
+#include "vquic.h"
+#include "vtls/keylog.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -147,21 +150,24 @@ quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
}
#endif
-static int setup_initial_crypto_context(struct quicsocket *qs)
+static void qlog_callback(void *user_data, const void *data, size_t datalen)
{
- const ngtcp2_cid *dcid = ngtcp2_conn_get_dcid(qs->qconn);
-
- if(ngtcp2_crypto_derive_and_install_initial_key(
- qs->qconn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- dcid) != 0)
- return -1;
+ struct quicsocket *qs = (struct quicsocket *)user_data;
+ if(qs->qlogfd != -1) {
+ ssize_t rc = write(qs->qlogfd, data, datalen);
+ if(rc == -1) {
+ /* on write error, stop further write attempts */
+ close(qs->qlogfd);
+ qs->qlogfd = -1;
+ }
+ }
- return 0;
}
-static void quic_settings(ngtcp2_settings *s,
+static void quic_settings(struct quicsocket *qs,
uint64_t stream_buffer_size)
{
+ ngtcp2_settings *s = &qs->settings;
ngtcp2_settings_default(s);
#ifdef DEBUG_NGTCP2
s->log_printf = quic_printf;
@@ -176,16 +182,16 @@ static void quic_settings(ngtcp2_settings *s,
s->transport_params.initial_max_streams_bidi = 1;
s->transport_params.initial_max_streams_uni = 3;
s->transport_params.max_idle_timeout = QUIC_IDLE_TIMEOUT;
+ if(qs->qlogfd != -1) {
+ s->qlog.write = qlog_callback;
+ }
}
-static FILE *keylog_file; /* not thread-safe */
#ifdef USE_OPENSSL
static void keylog_callback(const SSL *ssl, const char *line)
{
(void)ssl;
- fputs(line, keylog_file);
- fputc('\n', keylog_file);
- fflush(keylog_file);
+ Curl_tls_keylog_write_line(line);
}
#elif defined(USE_GNUTLS)
static int keylog_callback(gnutls_session_t session, const char *label,
@@ -193,36 +199,14 @@ static int keylog_callback(gnutls_session_t session, const char *label,
{
gnutls_datum_t crandom;
gnutls_datum_t srandom;
- gnutls_datum_t crandom_hex = { NULL, 0 };
- gnutls_datum_t secret_hex = { NULL, 0 };
- int rc = 0;
gnutls_session_get_random(session, &crandom, &srandom);
if(crandom.size != 32) {
return -1;
}
- rc = gnutls_hex_encode2(&crandom, &crandom_hex);
- if(rc < 0) {
- fprintf(stderr, "gnutls_hex_encode2 failed: %s\n",
- gnutls_strerror(rc));
- goto out;
- }
-
- rc = gnutls_hex_encode2(secret, &secret_hex);
- if(rc < 0) {
- fprintf(stderr, "gnutls_hex_encode2 failed: %s\n",
- gnutls_strerror(rc));
- goto out;
- }
-
- fprintf(keylog_file, "%s %s %s\n", label, crandom_hex.data, secret_hex.data);
- fflush(keylog_file);
-
- out:
- gnutls_free(crandom_hex.data);
- gnutls_free(secret_hex.data);
- return rc;
+ Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
+ return 0;
}
#endif
@@ -271,13 +255,12 @@ static int quic_set_encryption_secrets(SSL *ssl,
struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
int level = quic_from_ossl_level(ossl_level);
- if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
- ngtcp2_crypto_derive_and_install_rx_key(
- qs->qconn, ssl, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
+ if(ngtcp2_crypto_derive_and_install_rx_key(
+ qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
return 0;
if(ngtcp2_crypto_derive_and_install_tx_key(
- qs->qconn, ssl, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
+ qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
return 0;
if(level == NGTCP2_CRYPTO_LEVEL_APP) {
@@ -320,7 +303,6 @@ static SSL_QUIC_METHOD quic_method = {quic_set_encryption_secrets,
static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
{
SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
- const char *keylog_filename;
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
@@ -341,12 +323,10 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
- keylog_filename = getenv("SSLKEYLOGFILE");
- if(keylog_filename) {
- keylog_file = fopen(keylog_filename, "wb");
- if(keylog_file) {
- SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
- }
+ /* Open the file if a TLS or QUIC backend has not done this before. */
+ Curl_tls_keylog_open();
+ if(Curl_tls_keylog_enabled()) {
+ SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
}
return ssl_ctx;
@@ -361,9 +341,7 @@ static int quic_init_ssl(struct quicsocket *qs)
/* this will need some attention when HTTPS proxy over QUIC get fixed */
const char * const hostname = qs->conn->host.name;
- if(qs->ssl)
- SSL_free(qs->ssl);
-
+ DEBUGASSERT(!qs->ssl);
qs->ssl = SSL_new(qs->sslctx);
SSL_set_app_data(qs->ssl, qs);
@@ -372,8 +350,8 @@ static int quic_init_ssl(struct quicsocket *qs)
switch(qs->version) {
#ifdef NGTCP2_PROTO_VER
case NGTCP2_PROTO_VER:
- alpn = (const uint8_t *)NGTCP2_ALPN_H3;
- alpnlen = sizeof(NGTCP2_ALPN_H3) - 1;
+ alpn = (const uint8_t *)NGHTTP3_ALPN_H3;
+ alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1;
break;
#endif
}
@@ -395,11 +373,11 @@ static int secret_func(gnutls_session_t ssl,
if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
ngtcp2_crypto_derive_and_install_rx_key(
- qs->qconn, ssl, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
+ qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
return 0;
if(ngtcp2_crypto_derive_and_install_tx_key(
- qs->qconn, ssl, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
+ qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
return 0;
if(level == NGTCP2_CRYPTO_LEVEL_APP) {
@@ -449,8 +427,8 @@ static int tp_recv_func(gnutls_session_t ssl, const uint8_t *data,
ngtcp2_transport_params params;
if(ngtcp2_decode_transport_params(
- &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
- data, data_size) != 0)
+ &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
+ data, data_size) != 0)
return -1;
if(ngtcp2_conn_set_remote_transport_params(qs->qconn, &params) != 0)
@@ -472,8 +450,8 @@ static int tp_send_func(gnutls_session_t ssl, gnutls_buffer_t extdata)
paramsbuf, sizeof(paramsbuf), NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
&params);
if(nwrite < 0) {
- fprintf(stderr, "ngtcp2_encode_transport_params: %s\n",
- ngtcp2_strerror((int)nwrite));
+ H3BUGF(fprintf(stderr, "ngtcp2_encode_transport_params: %s\n",
+ ngtcp2_strerror((int)nwrite)));
return -1;
}
@@ -489,19 +467,17 @@ static int quic_init_ssl(struct quicsocket *qs)
gnutls_datum_t alpn = {NULL, 0};
/* this will need some attention when HTTPS proxy over QUIC get fixed */
const char * const hostname = qs->conn->host.name;
- const char *keylog_filename;
int rc;
- if(qs->ssl)
- gnutls_deinit(qs->ssl);
+ DEBUGASSERT(!qs->ssl);
gnutls_init(&qs->ssl, GNUTLS_CLIENT);
gnutls_session_set_ptr(qs->ssl, qs);
rc = gnutls_priority_set_direct(qs->ssl, QUIC_PRIORITY, NULL);
if(rc < 0) {
- fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
- gnutls_strerror(rc));
+ H3BUGF(fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
+ gnutls_strerror(rc)));
return 1;
}
@@ -517,17 +493,15 @@ static int quic_init_ssl(struct quicsocket *qs)
GNUTLS_EXT_FLAG_CLIENT_HELLO |
GNUTLS_EXT_FLAG_EE);
if(rc < 0) {
- fprintf(stderr, "gnutls_session_ext_register failed: %s\n",
- gnutls_strerror(rc));
+ H3BUGF(fprintf(stderr, "gnutls_session_ext_register failed: %s\n",
+ gnutls_strerror(rc)));
return 1;
}
- keylog_filename = getenv("SSLKEYLOGFILE");
- if(keylog_filename) {
- keylog_file = fopen(keylog_filename, "wb");
- if(keylog_file) {
- gnutls_session_set_keylog_function(qs->ssl, keylog_callback);
- }
+ /* Open the file if a TLS or QUIC backend has not done this before. */
+ Curl_tls_keylog_open();
+ if(Curl_tls_keylog_enabled()) {
+ gnutls_session_set_keylog_function(qs->ssl, keylog_callback);
}
if(qs->cred)
@@ -535,31 +509,33 @@ static int quic_init_ssl(struct quicsocket *qs)
rc = gnutls_certificate_allocate_credentials(&qs->cred);
if(rc < 0) {
- fprintf(stderr, "gnutls_certificate_allocate_credentials failed: %s\n",
- gnutls_strerror(rc));
+ H3BUGF(fprintf(stderr,
+ "gnutls_certificate_allocate_credentials failed: %s\n",
+ gnutls_strerror(rc)));
return 1;
}
rc = gnutls_certificate_set_x509_system_trust(qs->cred);
if(rc < 0) {
- fprintf(stderr, "gnutls_certificate_set_x509_system_trust failed: %s\n",
- gnutls_strerror(rc));
+ H3BUGF(fprintf(stderr,
+ "gnutls_certificate_set_x509_system_trust failed: %s\n",
+ gnutls_strerror(rc)));
return 1;
}
rc = gnutls_credentials_set(qs->ssl, GNUTLS_CRD_CERTIFICATE, qs->cred);
if(rc < 0) {
- fprintf(stderr, "gnutls_credentials_set failed: %s\n",
- gnutls_strerror(rc));
+ H3BUGF(fprintf(stderr, "gnutls_credentials_set failed: %s\n",
+ gnutls_strerror(rc)));
return 1;
}
switch(qs->version) {
#ifdef NGTCP2_PROTO_VER
case NGTCP2_PROTO_VER:
- /* strip the first byte from NGTCP2_ALPN_H3 */
- alpn.data = (unsigned char *)NGTCP2_ALPN_H3 + 1;
- alpn.size = sizeof(NGTCP2_ALPN_H3) - 2;
+ /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
+ alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1;
+ alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2;
break;
#endif
}
@@ -572,27 +548,16 @@ static int quic_init_ssl(struct quicsocket *qs)
}
#endif
-static int cb_initial(ngtcp2_conn *quic, void *user_data)
-{
- struct quicsocket *qs = (struct quicsocket *)user_data;
-
- if(ngtcp2_crypto_read_write_crypto_data(
- quic, qs->ssl, NGTCP2_CRYPTO_LEVEL_INITIAL, NULL, 0) != 0)
- return NGTCP2_ERR_CALLBACK_FAILURE;
-
- return 0;
-}
-
static int
cb_recv_crypto_data(ngtcp2_conn *tconn, ngtcp2_crypto_level crypto_level,
uint64_t offset,
const uint8_t *data, size_t datalen,
void *user_data)
{
- struct quicsocket *qs = (struct quicsocket *)user_data;
(void)offset;
+ (void)user_data;
- if(ngtcp2_crypto_read_write_crypto_data(tconn, qs->ssl, crypto_level, data,
+ if(ngtcp2_crypto_read_write_crypto_data(tconn, crypto_level, data,
datalen) != 0)
return NGTCP2_ERR_CRYPTO;
@@ -618,13 +583,14 @@ static void extend_stream_window(ngtcp2_conn *tconn,
}
-static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
- int fin, uint64_t offset,
+static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
+ int64_t stream_id, uint64_t offset,
const uint8_t *buf, size_t buflen,
void *user_data, void *stream_user_data)
{
struct quicsocket *qs = (struct quicsocket *)user_data;
ssize_t nconsumed;
+ int fin = flags & NGTCP2_STREAM_DATA_FLAG_FIN ? 1 : 0;
(void)offset;
(void)stream_user_data;
@@ -710,20 +676,6 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
return 0;
}
-static int cb_recv_retry(ngtcp2_conn *tconn, const ngtcp2_pkt_hd *hd,
- const ngtcp2_pkt_retry *retry, void *user_data)
-{
- /* Re-generate handshake secrets here because connection ID might change. */
- struct quicsocket *qs = (struct quicsocket *)user_data;
- (void)tconn;
- (void)hd;
- (void)retry;
-
- setup_initial_crypto_context(qs);
-
- return 0;
-}
-
static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn,
uint64_t max_streams,
void *user_data)
@@ -776,7 +728,7 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
}
static ngtcp2_conn_callbacks ng_callbacks = {
- cb_initial,
+ ngtcp2_crypto_client_initial_cb,
NULL, /* recv_client_initial */
cb_recv_crypto_data,
cb_handshake_completed,
@@ -790,7 +742,7 @@ static ngtcp2_conn_callbacks ng_callbacks = {
NULL, /* stream_open */
cb_stream_close,
NULL, /* recv_stateless_reset */
- cb_recv_retry,
+ ngtcp2_crypto_recv_retry_cb,
cb_extend_max_local_streams_bidi,
NULL, /* extend_max_local_streams_uni */
NULL, /* rand */
@@ -804,7 +756,8 @@ static ngtcp2_conn_callbacks ng_callbacks = {
NULL, /* extend_max_remote_streams_uni */
cb_extend_max_stream_data,
NULL, /* dcid_status */
- NULL /* handshake_confirmed */
+ NULL, /* handshake_confirmed */
+ NULL /* recv_new_token */
};
/*
@@ -824,12 +777,10 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
struct quicsocket *qs = &conn->hequic[sockindex];
char ipbuf[40];
long port;
-#ifdef USE_OPENSSL
- uint8_t paramsbuf[64];
- ngtcp2_transport_params params;
- ssize_t nwrite;
-#endif
+ int qfd;
+ if(qs->conn)
+ Curl_quic_disconnect(conn, sockindex);
qs->conn = conn;
/* extract the used address as a string */
@@ -863,7 +814,9 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
if(result)
return result;
- quic_settings(&qs->settings, data->set.buffer_size);
+ (void)Curl_qlogdir(data, qs->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
+ qs->qlogfd = qfd; /* -1 if failure above */
+ quic_settings(qs, data->set.buffer_size);
qs->local_addrlen = sizeof(qs->local_addr);
rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
@@ -885,24 +838,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
if(rc)
return CURLE_QUIC_CONNECT_ERROR;
-#ifdef USE_OPENSSL
- ngtcp2_conn_get_local_transport_params(qs->qconn, &params);
- nwrite = ngtcp2_encode_transport_params(
- paramsbuf, sizeof(paramsbuf), NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
- &params);
- if(nwrite < 0) {
- failf(data, "ngtcp2_encode_transport_params: %s\n",
- ngtcp2_strerror((int)nwrite));
- return CURLE_QUIC_CONNECT_ERROR;
- }
-
- if(!SSL_set_quic_transport_params(qs->ssl, paramsbuf, nwrite))
- return CURLE_QUIC_CONNECT_ERROR;
-#endif
-
- rc = setup_initial_crypto_context(qs);
- if(rc)
- return CURLE_QUIC_CONNECT_ERROR;
+ ngtcp2_conn_set_tls_native_handle(qs->qconn, qs->ssl);
return CURLE_OK;
}
@@ -943,29 +879,49 @@ static int ng_perform_getsock(const struct connectdata *conn,
return ng_getsock((struct connectdata *)conn, socks);
}
-static CURLcode ng_disconnect(struct connectdata *conn,
- bool dead_connection)
+static void qs_disconnect(struct quicsocket *qs)
{
int i;
- struct quicsocket *qs = &conn->hequic[0];
- (void)dead_connection;
+ if(!qs->conn) /* already closed */
+ return;
+ qs->conn = NULL;
+ if(qs->qlogfd != -1) {
+ close(qs->qlogfd);
+ qs->qlogfd = -1;
+ }
if(qs->ssl)
#ifdef USE_OPENSSL
SSL_free(qs->ssl);
#elif defined(USE_GNUTLS)
gnutls_deinit(qs->ssl);
#endif
+ qs->ssl = NULL;
#ifdef USE_GNUTLS
if(qs->cred)
gnutls_certificate_free_credentials(qs->cred);
#endif
for(i = 0; i < 3; i++)
- free(qs->crypto_data[i].buf);
+ Curl_safefree(qs->crypto_data[i].buf);
nghttp3_conn_del(qs->h3conn);
ngtcp2_conn_del(qs->qconn);
#ifdef USE_OPENSSL
SSL_CTX_free(qs->sslctx);
#endif
+}
+
+void Curl_quic_disconnect(struct connectdata *conn,
+ int tempindex)
+{
+ if(conn->transport == TRNSPRT_QUIC)
+ qs_disconnect(&conn->hequic[tempindex]);
+}
+
+static CURLcode ng_disconnect(struct connectdata *conn,
+ bool dead_connection)
+{
+ (void)dead_connection;
+ Curl_quic_disconnect(conn, 0);
+ Curl_quic_disconnect(conn, 1);
return CURLE_OK;
}
@@ -1018,57 +974,12 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
return 0;
}
-/* Minimum size of the overflow buffer */
-#define OVERFLOWSIZE 1024
-
-/*
- * allocate_overflow() ensures that there is room for incoming data in the
- * overflow buffer, growing it to accommodate the new data if necessary. We
- * may need to use the overflow buffer because we can't precisely limit the
- * amount of HTTP/3 header data we receive using QUIC flow control mechanisms.
- */
-static CURLcode allocate_overflow(struct Curl_easy *data,
- struct HTTP *stream,
- size_t length)
-{
- size_t maxleft;
- size_t newsize;
- /* length can be arbitrarily large, so take care not to overflow newsize */
- maxleft = CURL_MAX_READ_SIZE - stream->overflow_buflen;
- if(length > maxleft) {
- /* The reason to have a max limit for this is to avoid the risk of a bad
- server feeding libcurl with a highly compressed list of headers that
- will cause our overflow buffer to grow too large */
- failf(data, "Rejected %zu bytes of overflow data (max is %d)!",
- stream->overflow_buflen + length, CURL_MAX_READ_SIZE);
- return CURLE_OUT_OF_MEMORY;
- }
- newsize = stream->overflow_buflen + length;
- if(newsize > stream->overflow_bufsize) {
- /* We enlarge the overflow buffer as it is too small */
- char *newbuff;
- newsize = CURLMAX(newsize * 3 / 2, stream->overflow_bufsize*2);
- newsize = CURLMIN(CURLMAX(OVERFLOWSIZE, newsize), CURL_MAX_READ_SIZE);
- newbuff = realloc(stream->overflow_buf, newsize);
- if(!newbuff) {
- failf(data, "Failed to alloc memory for overflow buffer!");
- return CURLE_OUT_OF_MEMORY;
- }
- stream->overflow_buf = newbuff;
- stream->overflow_bufsize = newsize;
- infof(data, "Grew HTTP/3 overflow buffer to %zu bytes\n", newsize);
- }
- return CURLE_OK;
-}
-
/*
* write_data() copies data to the stream's receive buffer. If not enough
* space is available in the receive buffer, it copies the rest to the
* stream's overflow buffer.
*/
-static CURLcode write_data(struct Curl_easy *data,
- struct HTTP *stream,
- const void *mem, size_t memlen)
+static CURLcode write_data(struct HTTP *stream, const void *mem, size_t memlen)
{
CURLcode result = CURLE_OK;
const char *buf = mem;
@@ -1076,10 +987,6 @@ static CURLcode write_data(struct Curl_easy *data,
/* copy as much as possible to the receive buffer */
if(stream->len) {
size_t len = CURLMIN(ncopy, stream->len);
-#if 0 /* extra debugging of incoming h3 data */
- fprintf(stderr, "!! Copies %zd bytes to %p (total %zd)\n",
- len, stream->mem, stream->memlen);
-#endif
memcpy(stream->mem, buf, len);
stream->len -= len;
stream->memlen += len;
@@ -1088,26 +995,8 @@ static CURLcode write_data(struct Curl_easy *data,
ncopy -= len;
}
/* copy the rest to the overflow buffer */
- if(ncopy) {
- result = allocate_overflow(data, stream, ncopy);
- if(result) {
- return result;
- }
-#if 0 /* extra debugging of incoming h3 data */
- fprintf(stderr, "!! Copies %zd overflow bytes to %p (total %zd)\n",
- ncopy, stream->overflow_buf, stream->overflow_buflen);
-#endif
- memcpy(stream->overflow_buf + stream->overflow_buflen, buf, ncopy);
- stream->overflow_buflen += ncopy;
- }
-#if 0 /* extra debugging of incoming h3 data */
- {
- size_t i;
- for(i = 0; i < memlen; i++) {
- fprintf(stderr, "!! data[%d]: %02x '%c'\n", i, buf[i], buf[i]);
- }
- }
-#endif
+ if(ncopy)
+ result = Curl_dyn_addn(&stream->overflow, buf, ncopy);
return result;
}
@@ -1120,7 +1009,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
CURLcode result = CURLE_OK;
(void)conn;
- result = write_data(data, stream, buf, buflen);
+ result = write_data(stream, buf, buflen);
if(result) {
return -1;
}
@@ -1183,7 +1072,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
/* add a CRLF only if we've received some headers */
if(stream->firstheader) {
- result = write_data(data, stream, "\r\n", 2);
+ result = write_data(stream, "\r\n", 2);
if(result) {
return -1;
}
@@ -1214,26 +1103,26 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
int status = decode_status_code(h3val.base, h3val.len);
DEBUGASSERT(status != -1);
ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status);
- result = write_data(data, stream, line, ncopy);
+ result = write_data(stream, line, ncopy);
if(result) {
return -1;
}
}
else {
/* store as a HTTP1-style header */
- result = write_data(data, stream, h3name.base, h3name.len);
+ result = write_data(stream, h3name.base, h3name.len);
if(result) {
return -1;
}
- result = write_data(data, stream, ": ", 2);
+ result = write_data(stream, ": ", 2);
if(result) {
return -1;
}
- result = write_data(data, stream, h3val.base, h3val.len);
+ result = write_data(stream, h3val.base, h3val.len);
if(result) {
return -1;
}
- result = write_data(data, stream, "\r\n", 2);
+ result = write_data(stream, "\r\n", 2);
if(result) {
return -1;
}
@@ -1341,15 +1230,16 @@ static Curl_send ngh3_stream_send;
static size_t drain_overflow_buffer(struct HTTP *stream)
{
- size_t ncopy = CURLMIN(stream->overflow_buflen, stream->len);
+ size_t overlen = Curl_dyn_len(&stream->overflow);
+ size_t ncopy = CURLMIN(overlen, stream->len);
if(ncopy > 0) {
- memcpy(stream->mem, stream->overflow_buf, ncopy);
+ memcpy(stream->mem, Curl_dyn_ptr(&stream->overflow), ncopy);
stream->len -= ncopy;
stream->mem += ncopy;
stream->memlen += ncopy;
- stream->overflow_buflen -= ncopy;
- memmove(stream->overflow_buf, stream->overflow_buf + ncopy,
- stream->overflow_buflen);
+ if(ncopy != overlen)
+ /* make the buffer only keep the tail */
+ (void)Curl_dyn_tail(&stream->overflow, overlen - ncopy);
}
return ncopy;
}
@@ -1528,6 +1418,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
stream->stream3_id = stream3_id;
stream->h3req = TRUE; /* senf off! */
+ Curl_dyn_init(&stream->overflow, CURL_MAX_READ_SIZE);
/* Calculate number of headers contained in [mem, mem + len). Assumes a
correctly generated HTTP header field block. */
@@ -1684,7 +1575,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
}
}
- switch(data->set.httpreq) {
+ switch(data->state.httpreq) {
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
case HTTPREQ_POST_MIME:
@@ -1806,11 +1697,11 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
result = ng_process_ingress(conn, sockfd, qs);
if(result)
- return result;
+ goto error;
result = ng_flush_egress(conn, sockfd, qs);
if(result)
- return result;
+ goto error;
if(ngtcp2_conn_get_handshake_completed(qs->qconn)) {
*done = TRUE;
@@ -1818,6 +1709,10 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
}
return result;
+ error:
+ (void)qs_disconnect(qs);
+ return result;
+
}
static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
@@ -1914,11 +1809,12 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
return CURLE_SEND_ERROR;
}
else if(veccnt > 0) {
+ uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
+ (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
outlen =
ngtcp2_conn_writev_stream(qs->qconn, &ps.path,
out, pktlen, &ndatalen,
- NGTCP2_WRITE_STREAM_FLAG_MORE,
- stream_id, fin,
+ flags, stream_id,
(const ngtcp2_vec *)vec, veccnt, ts);
if(outlen == 0) {
break;
@@ -1926,6 +1822,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
if(outlen < 0) {
if(outlen == NGTCP2_ERR_STREAM_DATA_BLOCKED ||
outlen == NGTCP2_ERR_STREAM_SHUT_WR) {
+ assert(ndatalen == -1);
rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
if(rv != 0) {
failf(conn->data,
@@ -1948,19 +1845,14 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
continue;
}
else {
+ assert(ndatalen == -1);
failf(conn->data, "ngtcp2_conn_writev_stream returned error: %s\n",
ngtcp2_strerror((int)outlen));
return CURLE_SEND_ERROR;
}
}
- else if(ndatalen >= 0) {
- rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen);
- if(rv != 0) {
- failf(conn->data,
- "nghttp3_conn_add_write_offset returned error: %s\n",
- nghttp3_strerror(rv));
- return CURLE_SEND_ERROR;
- }
+ else {
+ assert(ndatalen == -1);
}
}
}
@@ -2032,7 +1924,7 @@ void Curl_quic_done(struct Curl_easy *data, bool premature)
if(data->conn->handler == &Curl_handler_http3) {
/* only for HTTP/3 transfers */
struct HTTP *stream = data->req.protop;
- Curl_safefree(stream->overflow_buf);
+ Curl_dyn_free(&stream->overflow);
}
}
@@ -2047,7 +1939,7 @@ bool Curl_quic_data_pending(const struct Curl_easy *data)
there's no more data coming on the socket, we need to keep reading
until the overflow buffer is empty. */
const struct HTTP *stream = data->req.protop;
- return stream->overflow_buflen > 0;
+ return Curl_dyn_len(&stream->overflow) > 0;
}
#endif
diff --git a/libs/libcurl/src/vquic/ngtcp2.h b/libs/libcurl/src/vquic/ngtcp2.h
index 06337f6f9f..e2f8b56001 100644
--- a/libs/libcurl/src/vquic/ngtcp2.h
+++ b/libs/libcurl/src/vquic/ngtcp2.h
@@ -63,6 +63,7 @@ struct quicsocket {
nghttp3_conn *h3conn;
nghttp3_conn_settings h3settings;
+ int qlogfd;
};
#include "urldata.h"
diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c
index c40e5e937c..be6f15c199 100644
--- a/libs/libcurl/src/vquic/quiche.c
+++ b/libs/libcurl/src/vquic/quiche.c
@@ -34,6 +34,7 @@
#include "multiif.h"
#include "connect.h"
#include "strerror.h"
+#include "vquic.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -64,7 +65,6 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
static Curl_recv h3_stream_recv;
static Curl_send h3_stream_send;
-
static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks)
{
struct SingleRequest *k = &conn->data->req;
@@ -89,16 +89,30 @@ static int quiche_perform_getsock(const struct connectdata *conn,
return quiche_getsock((struct connectdata *)conn, socks);
}
+static CURLcode qs_disconnect(struct quicsocket *qs)
+{
+ if(qs->h3config)
+ quiche_h3_config_free(qs->h3config);
+ if(qs->h3c)
+ quiche_h3_conn_free(qs->h3c);
+ quiche_config_free(qs->cfg);
+ quiche_conn_free(qs->conn);
+ return CURLE_OK;
+}
+
static CURLcode quiche_disconnect(struct connectdata *conn,
bool dead_connection)
{
struct quicsocket *qs = conn->quic;
(void)dead_connection;
- quiche_h3_config_free(qs->h3config);
- quiche_h3_conn_free(qs->h3c);
- quiche_config_free(qs->cfg);
- quiche_conn_free(qs->conn);
- return CURLE_OK;
+ return qs_disconnect(qs);
+}
+
+void Curl_quic_disconnect(struct connectdata *conn,
+ int tempindex)
+{
+ if(conn->transport == TRNSPRT_QUIC)
+ qs_disconnect(&conn->hequic[tempindex]);
}
static unsigned int quiche_conncheck(struct connectdata *conn,
@@ -152,6 +166,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
CURLcode result;
struct quicsocket *qs = &conn->hequic[sockindex];
struct Curl_easy *data = conn->data;
+ char *keylog_file = NULL;
#ifdef DEBUG_QUICHE
/* initialize debug log callback only once */
@@ -189,7 +204,9 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
if(result)
return result;
- if(getenv("SSLKEYLOGFILE"))
+ keylog_file = getenv("SSLKEYLOGFILE");
+
+ if(keylog_file)
quiche_config_log_keys(qs->cfg);
qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid,
@@ -199,6 +216,20 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
return CURLE_OUT_OF_MEMORY;
}
+ if(keylog_file)
+ quiche_conn_set_keylog_path(qs->conn, keylog_file);
+
+ /* Known to not work on Windows */
+#if !defined(WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD)
+ {
+ int qfd;
+ (void)Curl_qlogdir(data, qs->scid, sizeof(qs->scid), &qfd);
+ if(qfd != -1)
+ quiche_conn_set_qlog_fd(qs->conn, qfd,
+ "qlog title", "curl qlog");
+ }
+#endif
+
result = flush_egress(conn, sockfd, qs);
if(result)
return result;
@@ -217,8 +248,20 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
/* for connection reuse purposes: */
conn->ssl[FIRSTSOCKET].state = ssl_connection_complete;
- infof(data, "Sent QUIC client Initial, ALPN: %s\n",
- QUICHE_H3_APPLICATION_PROTOCOL + 1);
+ {
+ unsigned char alpn_protocols[] = QUICHE_H3_APPLICATION_PROTOCOL;
+ unsigned alpn_len, offset = 0;
+
+ /* Replace each ALPN length prefix by a comma. */
+ while(offset < sizeof(alpn_protocols) - 1) {
+ alpn_len = alpn_protocols[offset];
+ alpn_protocols[offset] = ',';
+ offset += 1 + alpn_len;
+ }
+
+ infof(data, "Sent QUIC client Initial, ALPN: %s\n",
+ alpn_protocols + 1);
+ }
return CURLE_OK;
}
@@ -273,11 +316,11 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex,
result = process_ingress(conn, sockfd, qs);
if(result)
- return result;
+ goto error;
result = flush_egress(conn, sockfd, qs);
if(result)
- return result;
+ goto error;
if(quiche_conn_is_established(qs->conn)) {
*done = TRUE;
@@ -286,6 +329,9 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex,
}
return result;
+ error:
+ qs_disconnect(qs);
+ return result;
}
static CURLcode process_ingress(struct connectdata *conn, int sockfd,
@@ -714,7 +760,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
}
}
- switch(data->set.httpreq) {
+ switch(data->state.httpreq) {
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
case HTTPREQ_POST_MIME:
diff --git a/libs/libcurl/src/vquic/vquic.c b/libs/libcurl/src/vquic/vquic.c
new file mode 100644
index 0000000000..aae8e09514
--- /dev/null
+++ b/libs/libcurl/src/vquic/vquic.c
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, 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.haxx.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.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef ENABLE_QUIC
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include "urldata.h"
+#include "dynbuf.h"
+#include "curl_printf.h"
+#include "vquic.h"
+
+#ifdef O_BINARY
+#define QLOGMODE O_WRONLY|O_CREAT|O_BINARY
+#else
+#define QLOGMODE O_WRONLY|O_CREAT
+#endif
+
+/*
+ * If the QLOGDIR environment variable is set, open and return a file
+ * descriptor to write the log to.
+ *
+ * This function returns error if something failed outside of failing to
+ * create the file. Open file success is deemed by seeing if the returned fd
+ * is != -1.
+ */
+CURLcode Curl_qlogdir(struct Curl_easy *data,
+ unsigned char *scid,
+ size_t scidlen,
+ int *qlogfdp)
+{
+ const char *qlog_dir = getenv("QLOGDIR");
+ *qlogfdp = -1;
+ if(qlog_dir) {
+ struct dynbuf fname;
+ CURLcode result;
+ unsigned int i;
+ Curl_dyn_init(&fname, DYN_QLOG_NAME);
+ result = Curl_dyn_add(&fname, qlog_dir);
+ if(!result)
+ result = Curl_dyn_add(&fname, "/");
+ for(i = 0; (i < scidlen) && !result; i++) {
+ char hex[3];
+ msnprintf(hex, 3, "%02x", scid[i]);
+ result = Curl_dyn_add(&fname, hex);
+ }
+ if(!result)
+ result = Curl_dyn_add(&fname, ".qlog");
+
+ if(!result) {
+ int qlogfd = open(Curl_dyn_ptr(&fname), QLOGMODE,
+ data->set.new_file_perms);
+ if(qlogfd != -1)
+ *qlogfdp = qlogfd;
+ }
+ Curl_dyn_free(&fname);
+ if(result)
+ return result;
+ }
+
+ return CURLE_OK;
+}
+#endif
diff --git a/libs/libcurl/src/vquic/vquic.h b/libs/libcurl/src/vquic/vquic.h
new file mode 100644
index 0000000000..ecff0edf4e
--- /dev/null
+++ b/libs/libcurl/src/vquic/vquic.h
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_VQUIC_QUIC_H
+#define HEADER_CURL_VQUIC_QUIC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, 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.haxx.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.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef ENABLE_QUIC
+CURLcode Curl_qlogdir(struct Curl_easy *data,
+ unsigned char *scid,
+ size_t scidlen,
+ int *qlogfdp);
+#endif
+
+#endif /* HEADER_CURL_VQUIC_QUIC_H */
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
index c487ccabb5..555afc9ef6 100644
--- a/libs/libcurl/src/vssh/libssh2.c
+++ b/libs/libcurl/src/vssh/libssh2.c
@@ -93,15 +93,12 @@
#define HAS_STATVFS_SUPPORT 1
#endif
-#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
-
-#define sftp_libssh2_realpath(s,p,t,m) \
- libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
- (t), (m), LIBSSH2_SFTP_REALPATH)
-
+#define sftp_libssh2_realpath(s,p,t,m) \
+ libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
+ (t), (m), LIBSSH2_SFTP_REALPATH)
/* Local functions: */
-static const char *sftp_libssh2_strerror(int err);
+static const char *sftp_libssh2_strerror(unsigned long err);
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
static LIBSSH2_FREE_FUNC(my_libssh2_free);
@@ -213,7 +210,7 @@ kbd_callback(const char *name, int name_len, const char *instruction,
(void)abstract;
} /* kbd_callback */
-static CURLcode sftp_libssh2_error_to_CURLE(int err)
+static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err)
{
switch(err) {
case LIBSSH2_FX_OK:
@@ -795,10 +792,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
struct SSHPROTO *sftp_scp = data->req.protop;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
- char *new_readdir_line;
int rc = LIBSSH2_ERROR_NONE;
- int err;
+ int ssherr;
+ unsigned long sftperr;
int seekerr = CURL_SEEKFUNC_OK;
+ size_t readdir_len;
*block = 0; /* we're not blocking by default */
do {
@@ -874,12 +872,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_AUTH_DONE);
break;
}
- err = libssh2_session_last_errno(sshc->ssh_session);
- if(err == LIBSSH2_ERROR_EAGAIN)
+ ssherr = libssh2_session_last_errno(sshc->ssh_session);
+ if(ssherr == LIBSSH2_ERROR_EAGAIN)
rc = LIBSSH2_ERROR_EAGAIN;
else {
state(conn, SSH_SESSION_FREE);
- sshc->actualcode = libssh2_session_error_to_CURLE(err);
+ sshc->actualcode = libssh2_session_error_to_CURLE(ssherr);
}
break;
}
@@ -1249,16 +1247,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
else {
/* Return the error type */
- err = sftp_libssh2_last_error(sshc->sftp_session);
- if(err)
- result = sftp_libssh2_error_to_CURLE(err);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+ if(sftperr)
+ result = sftp_libssh2_error_to_CURLE(sftperr);
else
/* in this case, the error wasn't in the SFTP level but for example
a time-out or similar */
result = CURLE_SSH;
sshc->actualcode = result;
DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
- err, (int)result));
+ ssherr, (int)result));
state(conn, SSH_STOP);
break;
}
@@ -1360,7 +1358,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
*/
cp = strchr(cmd, ' ');
if(cp == NULL) {
- failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+ failf(data, "Syntax error command '%s'. Missing parameter!",
+ cmd);
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1376,7 +1375,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(result == CURLE_OUT_OF_MEMORY)
failf(data, "Out of memory");
else
- failf(data, "Syntax error: Bad first parameter");
+ failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = result;
@@ -1401,8 +1400,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(result == CURLE_OUT_OF_MEMORY)
failf(data, "Out of memory");
else
- failf(data, "Syntax error in chgrp/chmod/chown: "
- "Bad second parameter");
+ failf(data, "Syntax error in %s: Bad second parameter", cmd);
Curl_safefree(sshc->quote_path1);
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
@@ -1533,11 +1531,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "Attempt to get SFTP stats failed: %s",
- sftp_libssh2_strerror(err));
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1604,11 +1602,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "Attempt to set SFTP stats failed: %s",
- sftp_libssh2_strerror(err));
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1627,11 +1625,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "symlink command failed: %s",
- sftp_libssh2_strerror(err));
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1648,9 +1646,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
- failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
+ failf(data, "mkdir command failed: %s",
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1672,10 +1671,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
- failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
+ failf(data, "rename command failed: %s",
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1691,9 +1691,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
- failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
+ failf(data, "rmdir command failed: %s",
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1709,9 +1710,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
- failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
+ failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1732,9 +1733,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc != 0 && !sshc->acceptfail) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
- failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
+ failf(data, "statvfs command failed: %s",
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
@@ -1871,21 +1873,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
/* only when there was an SFTP protocol error can we extract
the sftp error! */
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
else
- err = -1; /* not an sftp error at all */
+ sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */
if(sshc->secondCreateDirs) {
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = err>= LIBSSH2_FX_OK?
- sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+ sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
+ sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH;
failf(data, "Creating the dir/file failed: %s",
- sftp_libssh2_strerror(err));
+ sftp_libssh2_strerror(sftperr));
break;
}
- if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
- (err == LIBSSH2_FX_FAILURE) ||
- (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
+ if(((sftperr == LIBSSH2_FX_NO_SUCH_FILE) ||
+ (sftperr == LIBSSH2_FX_FAILURE) ||
+ (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) &&
(data->set.ftp_create_missing_dirs &&
(strlen(sftp_scp->path) > 1))) {
/* try to create the path remotely */
@@ -1895,18 +1897,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = err>= LIBSSH2_FX_OK?
- sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+ sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
+ sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH;
if(!sshc->actualcode) {
- /* Sometimes, for some reason libssh2_sftp_last_error() returns
- zero even though libssh2_sftp_open() failed previously! We need
- to work around that! */
+ /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
+ even though libssh2_sftp_open() failed previously! We need to
+ work around that! */
sshc->actualcode = CURLE_SSH;
- err = -1;
+ sftperr = LIBSSH2_FX_OK;
}
failf(data, "Upload failed: %s (%d/%d)",
- err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
- err, rc);
+ sftperr != LIBSSH2_FX_OK ?
+ sftp_libssh2_strerror(sftperr):"ssh error",
+ sftperr, rc);
break;
}
@@ -2033,11 +2036,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
* permission was denied (creation might succeed further down the
* path) - retry on unspecific FAILURE also
*/
- err = sftp_libssh2_last_error(sshc->sftp_session);
- if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
- (err != LIBSSH2_FX_FAILURE) &&
- (err != LIBSSH2_FX_PERMISSION_DENIED)) {
- result = sftp_libssh2_error_to_CURLE(err);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+ if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
+ (sftperr != LIBSSH2_FX_FAILURE) &&
+ (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) {
+ result = sftp_libssh2_error_to_CURLE(sftperr);
state(conn, SSH_SFTP_CLOSE);
sshc->actualcode = result?result:CURLE_SSH;
break;
@@ -2069,11 +2072,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
rc = LIBSSH2_ERROR_EAGAIN;
break;
}
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
failf(data, "Could not open directory for reading: %s",
- sftp_libssh2_strerror(err));
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
- result = sftp_libssh2_error_to_CURLE(err);
+ result = sftp_libssh2_error_to_CURLE(sftperr);
sshc->actualcode = result?result:CURLE_SSH;
break;
}
@@ -2090,6 +2093,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
}
+ Curl_dyn_init(&sshc->readdir, PATH_MAX * 2);
state(conn, SSH_SFTP_READDIR);
break;
@@ -2104,68 +2108,51 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(rc > 0) {
- sshc->readdir_len = (size_t) rc;
- sshc->readdir_filename[sshc->readdir_len] = '\0';
+ readdir_len = (size_t) rc;
+ sshc->readdir_filename[readdir_len] = '\0';
if(data->set.ftp_list_only) {
- char *tmpLine;
-
- tmpLine = aprintf("%s\n", sshc->readdir_filename);
- if(tmpLine == NULL) {
- state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = CURLE_OUT_OF_MEMORY;
- break;
- }
result = Curl_client_write(conn, CLIENTWRITE_BODY,
- tmpLine, sshc->readdir_len + 1);
- free(tmpLine);
-
+ sshc->readdir_filename,
+ readdir_len);
+ if(!result)
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ (char *)"\n", 1);
if(result) {
state(conn, SSH_STOP);
break;
}
/* since this counts what we send to the client, we include the
newline in this counter */
- data->req.bytecount += sshc->readdir_len + 1;
+ data->req.bytecount += readdir_len + 1;
/* output debug output if that is requested */
if(data->set.verbose) {
- Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
- sshc->readdir_len);
+ Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename,
+ readdir_len);
+ Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
}
}
else {
- sshc->readdir_currLen = strlen(sshc->readdir_longentry);
- sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
- sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
- if(!sshc->readdir_line) {
- Curl_safefree(sshc->readdir_filename);
- Curl_safefree(sshc->readdir_longentry);
- state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = CURLE_OUT_OF_MEMORY;
- break;
- }
-
- memcpy(sshc->readdir_line, sshc->readdir_longentry,
- sshc->readdir_currLen);
- if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
- ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFLNK)) {
- sshc->readdir_linkPath = malloc(PATH_MAX + 1);
- if(sshc->readdir_linkPath == NULL) {
- Curl_safefree(sshc->readdir_filename);
- Curl_safefree(sshc->readdir_longentry);
- state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ result = Curl_dyn_add(&sshc->readdir, sshc->readdir_longentry);
+
+ if(!result) {
+ if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
+ ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
+ LIBSSH2_SFTP_S_IFLNK)) {
+ Curl_dyn_init(&sshc->readdir_link, PATH_MAX);
+ result = Curl_dyn_add(&sshc->readdir_link, sftp_scp->path);
+ state(conn, SSH_SFTP_READDIR_LINK);
+ if(!result)
+ break;
+ }
+ else {
+ state(conn, SSH_SFTP_READDIR_BOTTOM);
break;
}
-
- msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
- sshc->readdir_filename);
- state(conn, SSH_SFTP_READDIR_LINK);
- break;
}
- state(conn, SSH_SFTP_READDIR_BOTTOM);
+ sshc->actualcode = result;
+ state(conn, SSH_SFTP_CLOSE);
break;
}
}
@@ -2176,11 +2163,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
else if(rc < 0) {
- err = sftp_libssh2_last_error(sshc->sftp_session);
- result = sftp_libssh2_error_to_CURLE(err);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+ result = sftp_libssh2_error_to_CURLE(sftperr);
sshc->actualcode = result?result:CURLE_SSH;
failf(data, "Could not open remote file for reading: %s :: %d",
- sftp_libssh2_strerror(err),
+ sftp_libssh2_strerror(sftperr),
libssh2_session_last_errno(sshc->ssh_session));
Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry);
@@ -2192,64 +2179,56 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
case SSH_SFTP_READDIR_LINK:
rc =
libssh2_sftp_symlink_ex(sshc->sftp_session,
- sshc->readdir_linkPath,
- curlx_uztoui(strlen(sshc->readdir_linkPath)),
+ Curl_dyn_ptr(&sshc->readdir_link),
+ (int)Curl_dyn_len(&sshc->readdir_link),
sshc->readdir_filename,
PATH_MAX, LIBSSH2_SFTP_READLINK);
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- sshc->readdir_len = (size_t) rc;
- Curl_safefree(sshc->readdir_linkPath);
+ readdir_len = (size_t) rc;
+ Curl_dyn_free(&sshc->readdir_link);
+
+ /* append filename and extra output */
+ result = Curl_dyn_addf(&sshc->readdir, " -> %s", sshc->readdir_filename);
- /* get room for the filename and extra output */
- sshc->readdir_totalLen += 4 + sshc->readdir_len;
- new_readdir_line = Curl_saferealloc(sshc->readdir_line,
- sshc->readdir_totalLen);
- if(!new_readdir_line) {
+ if(result) {
sshc->readdir_line = NULL;
Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry);
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ sshc->actualcode = result;
break;
}
- sshc->readdir_line = new_readdir_line;
-
- sshc->readdir_currLen += msnprintf(sshc->readdir_line +
- sshc->readdir_currLen,
- sshc->readdir_totalLen -
- sshc->readdir_currLen,
- " -> %s",
- sshc->readdir_filename);
state(conn, SSH_SFTP_READDIR_BOTTOM);
break;
case SSH_SFTP_READDIR_BOTTOM:
- sshc->readdir_currLen += msnprintf(sshc->readdir_line +
- sshc->readdir_currLen,
- sshc->readdir_totalLen -
- sshc->readdir_currLen, "\n");
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
- sshc->readdir_line,
- sshc->readdir_currLen);
+ result = Curl_dyn_addn(&sshc->readdir, "\n", 1);
+ if(!result)
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ Curl_dyn_ptr(&sshc->readdir),
+ Curl_dyn_len(&sshc->readdir));
if(!result) {
/* output debug output if that is requested */
if(data->set.verbose) {
- Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
- sshc->readdir_currLen);
+ Curl_debug(data, CURLINFO_DATA_IN,
+ Curl_dyn_ptr(&sshc->readdir),
+ Curl_dyn_len(&sshc->readdir));
}
- data->req.bytecount += sshc->readdir_currLen;
+ data->req.bytecount += Curl_dyn_len(&sshc->readdir);
}
- Curl_safefree(sshc->readdir_line);
if(result) {
+ Curl_dyn_free(&sshc->readdir);
state(conn, SSH_STOP);
}
- else
+ else {
+ Curl_dyn_reset(&sshc->readdir);
state(conn, SSH_SFTP_READDIR);
+ }
break;
case SSH_SFTP_READDIR_DONE:
@@ -2282,11 +2261,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
rc = LIBSSH2_ERROR_EAGAIN;
break;
}
- err = sftp_libssh2_last_error(sshc->sftp_session);
+ sftperr = libssh2_sftp_last_error(sshc->sftp_session);
failf(data, "Could not open remote file for reading: %s",
- sftp_libssh2_strerror(err));
+ sftp_libssh2_strerror(sftperr));
state(conn, SSH_SFTP_CLOSE);
- result = sftp_libssh2_error_to_CURLE(err);
+ result = sftp_libssh2_error_to_CURLE(sftperr);
sshc->actualcode = result?result:CURLE_SSH;
break;
}
@@ -2551,7 +2530,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
/* upload data */
- Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@@ -2621,7 +2602,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* download data */
bytecount = (curl_off_t)sb.st_size;
- data->req.maxdownload = (curl_off_t)sb.st_size;
+ data->req.maxdownload = (curl_off_t)sb.st_size;
Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
/* not set by Curl_setup_transfer to preserve keepon bits */
@@ -2828,7 +2809,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry);
Curl_safefree(sshc->readdir_line);
- Curl_safefree(sshc->readdir_linkPath);
+ Curl_dyn_free(&sshc->readdir);
/* the code we are about to return */
result = sshc->actualcode;
@@ -2952,7 +2933,7 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
}
static CURLcode ssh_block_statemach(struct connectdata *conn,
- bool disconnect)
+ bool duringconnect)
{
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
@@ -2967,19 +2948,17 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
if(result)
break;
- if(!disconnect) {
- if(Curl_pgrsUpdate(conn))
- return CURLE_ABORTED_BY_CALLBACK;
+ if(Curl_pgrsUpdate(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
- result = Curl_speedcheck(data, now);
- if(result)
- break;
+ result = Curl_speedcheck(data, now);
+ if(result)
+ break;
- left = Curl_timeleft(data, NULL, FALSE);
- if(left < 0) {
- failf(data, "Operation timed out");
- return CURLE_OPERATION_TIMEDOUT;
- }
+ left = Curl_timeleft(data, NULL, duringconnect);
+ if(left < 0) {
+ failf(data, "Operation timed out");
+ return CURLE_OPERATION_TIMEDOUT;
}
#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
@@ -2994,7 +2973,7 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
fd_write = sock;
/* wait for the socket to become ready */
(void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
- left>1000?1000:(time_t)left);
+ left>1000?1000:left);
}
#endif
@@ -3202,7 +3181,7 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
state(conn, SSH_SESSION_DISCONNECT);
- result = ssh_block_statemach(conn, TRUE);
+ result = ssh_block_statemach(conn, FALSE);
}
return result;
@@ -3351,7 +3330,7 @@ static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
if(conn->proto.sshc.ssh_session) {
/* only if there's a session still around to use! */
state(conn, SSH_SFTP_SHUTDOWN);
- result = ssh_block_statemach(conn, TRUE);
+ result = ssh_block_statemach(conn, FALSE);
}
DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
@@ -3426,7 +3405,7 @@ static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
return nread;
}
-static const char *sftp_libssh2_strerror(int err)
+static const char *sftp_libssh2_strerror(unsigned long err)
{
switch(err) {
case LIBSSH2_FX_NO_SUCH_FILE:
diff --git a/libs/libcurl/src/vssh/ssh.h b/libs/libcurl/src/vssh/ssh.h
index 0d4ee521d1..9e49993e96 100644
--- a/libs/libcurl/src/vssh/ssh.h
+++ b/libs/libcurl/src/vssh/ssh.h
@@ -134,9 +134,7 @@ struct ssh_conn {
quote command fails) */
char *homedir; /* when doing SFTP we figure out home dir in the
connect phase */
- size_t readdir_len, readdir_totalLen, readdir_currLen;
char *readdir_line;
- char *readdir_linkPath;
/* end of READDIR stuff */
int secondCreateDirs; /* counter use by the code to see if the
@@ -147,6 +145,8 @@ struct ssh_conn {
int orig_waitfor; /* default READ/WRITE bits wait for */
#if defined(USE_LIBSSH)
+ char *readdir_linkPath;
+ size_t readdir_len, readdir_totalLen, readdir_currLen;
/* our variables */
unsigned kbd_state; /* 0 or 1 */
ssh_key privkey;
@@ -168,6 +168,8 @@ struct ssh_conn {
const char *readdir_longentry;
char *readdir_tmp;
#elif defined(USE_LIBSSH2)
+ struct dynbuf readdir_link;
+ struct dynbuf readdir;
char *readdir_filename;
char *readdir_longentry;
diff --git a/libs/libcurl/src/vssh/wolfssh.c b/libs/libcurl/src/vssh/wolfssh.c
index 363a52c772..dcbbab6c3d 100644
--- a/libs/libcurl/src/vssh/wolfssh.c
+++ b/libs/libcurl/src/vssh/wolfssh.c
@@ -241,8 +241,8 @@ static ssize_t wsftp_send(struct connectdata *conn, int sockindex,
int rc;
(void)sockindex;
- offset[0] = (word32)sshc->offset&0xFFFFFFFF;
- offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
+ offset[0] = (word32)sshc->offset&0xFFFFFFFF;
+ offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
rc = wolfSSH_SFTP_SendWritePacket(sshc->ssh_session, sshc->handle,
sshc->handleSz,
@@ -284,8 +284,8 @@ static ssize_t wsftp_recv(struct connectdata *conn, int sockindex,
word32 offset[2];
(void)sockindex;
- offset[0] = (word32)sshc->offset&0xFFFFFFFF;
- offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
+ offset[0] = (word32)sshc->offset&0xFFFFFFFF;
+ offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
rc = wolfSSH_SFTP_SendReadPacket(sshc->ssh_session, sshc->handle,
sshc->handleSz,
diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c
index 1a6530c81c..628e16a124 100644
--- a/libs/libcurl/src/vtls/bearssl.c
+++ b/libs/libcurl/src/vtls/bearssl.c
@@ -642,7 +642,7 @@ static CURLcode bearssl_connect_common(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
- time_t timeout_ms;
+ timediff_t timeout_ms;
int what;
/* check if the connection has already been established */
diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c
index b0864b5fad..0538e4a463 100644
--- a/libs/libcurl/src/vtls/gskit.c
+++ b/libs/libcurl/src/vtls/gskit.c
@@ -108,13 +108,13 @@ struct ssl_backend_data {
#define BACKEND connssl->backend
/* Supported ciphers. */
-typedef struct {
+struct gskit_cipher {
const char *name; /* Cipher name. */
const char *gsktoken; /* Corresponding token for GSKit String. */
unsigned int versions; /* SSL version flags. */
-} gskit_cipher;
+};
-static const gskit_cipher ciphertable[] = {
+static const struct gskit_cipher ciphertable[] = {
{ "null-md5", "01",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
@@ -307,7 +307,7 @@ static CURLcode set_ciphers(struct connectdata *conn,
struct Curl_easy *data = conn->data;
const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
const char *clp;
- const gskit_cipher *ctp;
+ const struct gskit_cipher *ctp;
int i;
int l;
bool unsupported;
@@ -819,7 +819,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
if(!result) {
/* Compute the handshake timeout. Since GSKit granularity is 1 second,
we round up the required value. */
- long timeout = Curl_timeleft(data, NULL, TRUE);
+ timediff_t timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0)
result = CURLE_OPERATION_TIMEDOUT;
else
@@ -932,7 +932,7 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
/* Poll or wait for end of SSL asynchronous handshake. */
for(;;) {
- long timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+ timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0)
timeout_ms = 0;
stmv.tv_sec = timeout_ms / 1000;
diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c
index 4ed3ea5cfa..9b4c3659ac 100644
--- a/libs/libcurl/src/vtls/gtls.c
+++ b/libs/libcurl/src/vtls/gtls.c
@@ -235,7 +235,7 @@ static CURLcode handshake(struct connectdata *conn,
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
nonblocking?0:
- timeout_ms?(time_t)timeout_ms:1000);
+ timeout_ms?timeout_ms:1000);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -401,6 +401,8 @@ gtls_connect_step1(struct connectdata *conn,
const char *err = NULL;
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+ long * const certverifyresult = SSL_IS_PROXY() ?
+ &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
if(connssl->state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
@@ -410,6 +412,9 @@ gtls_connect_step1(struct connectdata *conn,
if(!gtls_inited)
Curl_gtls_init();
+ /* Initialize certverifyresult to OK */
+ *certverifyresult = 0;
+
if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
failf(data, "GnuTLS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
@@ -458,8 +463,10 @@ gtls_connect_step1(struct connectdata *conn,
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)\n",
SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
- if(SSL_CONN_CONFIG(verifypeer))
+ if(SSL_CONN_CONFIG(verifypeer)) {
+ *certverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
+ }
}
else
infof(data, "found %d certificates in %s\n", rc,
@@ -474,8 +481,10 @@ gtls_connect_step1(struct connectdata *conn,
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)\n",
SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
- if(SSL_CONN_CONFIG(verifypeer))
+ if(SSL_CONN_CONFIG(verifypeer)) {
+ *certverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
+ }
}
else
infof(data, "found %d certificates in %s\n",
@@ -821,6 +830,8 @@ gtls_connect_step3(struct connectdata *conn,
#endif
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+ long * const certverifyresult = SSL_IS_PROXY() ?
+ &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
/* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
@@ -852,6 +863,7 @@ gtls_connect_step3(struct connectdata *conn,
else {
#endif
failf(data, "failed to get server cert");
+ *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
return CURLE_PEER_FAILED_VERIFICATION;
#ifdef USE_TLS_SRP
}
@@ -888,9 +900,12 @@ gtls_connect_step3(struct connectdata *conn,
rc = gnutls_certificate_verify_peers2(session, &verify_status);
if(rc < 0) {
failf(data, "server cert verify failed: %d", rc);
+ *certverifyresult = rc;
return CURLE_SSL_CONNECT_ERROR;
}
+ *certverifyresult = verify_status;
+
/* verify_status is a bitmask of gnutls_certificate_status bits */
if(verify_status & GNUTLS_CERT_INVALID) {
if(SSL_CONN_CONFIG(verifypeer)) {
@@ -1119,6 +1134,7 @@ gtls_connect_step3(struct connectdata *conn,
if(certclock == (time_t)-1) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data, "server cert expiration date verify failed");
+ *certverifyresult = GNUTLS_CERT_EXPIRED;
gnutls_x509_crt_deinit(x509_cert);
return CURLE_SSL_CONNECT_ERROR;
}
@@ -1129,6 +1145,7 @@ gtls_connect_step3(struct connectdata *conn,
if(certclock < time(NULL)) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data, "server certificate expiration date has passed.");
+ *certverifyresult = GNUTLS_CERT_EXPIRED;
gnutls_x509_crt_deinit(x509_cert);
return CURLE_PEER_FAILED_VERIFICATION;
}
@@ -1144,6 +1161,7 @@ gtls_connect_step3(struct connectdata *conn,
if(certclock == (time_t)-1) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data, "server cert activation date verify failed");
+ *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
gnutls_x509_crt_deinit(x509_cert);
return CURLE_SSL_CONNECT_ERROR;
}
@@ -1154,6 +1172,7 @@ gtls_connect_step3(struct connectdata *conn,
if(certclock > time(NULL)) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data, "server certificate not activated yet.");
+ *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
gnutls_x509_crt_deinit(x509_cert);
return CURLE_PEER_FAILED_VERIFICATION;
}
diff --git a/libs/libcurl/src/vtls/keylog.c b/libs/libcurl/src/vtls/keylog.c
new file mode 100644
index 0000000000..70d22ecf0b
--- /dev/null
+++ b/libs/libcurl/src/vtls/keylog.c
@@ -0,0 +1,156 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, 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.haxx.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.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "keylog.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define KEYLOG_LABEL_MAXLEN (sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET") - 1)
+
+#define CLIENT_RANDOM_SIZE 32
+
+/*
+ * The master secret in TLS 1.2 and before is always 48 bytes. In TLS 1.3, the
+ * secret size depends on the cipher suite's hash function which is 32 bytes
+ * for SHA-256 and 48 bytes for SHA-384.
+ */
+#define SECRET_MAXLEN 48
+
+
+/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
+static FILE *keylog_file_fp;
+
+void
+Curl_tls_keylog_open(void)
+{
+ char *keylog_file_name;
+
+ if(!keylog_file_fp) {
+ keylog_file_name = curl_getenv("SSLKEYLOGFILE");
+ if(keylog_file_name) {
+ keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT);
+ if(keylog_file_fp) {
+#ifdef WIN32
+ if(setvbuf(keylog_file_fp, NULL, _IONBF, 0))
+#else
+ if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096))
+#endif
+ {
+ fclose(keylog_file_fp);
+ keylog_file_fp = NULL;
+ }
+ }
+ Curl_safefree(keylog_file_name);
+ }
+ }
+}
+
+void
+Curl_tls_keylog_close(void)
+{
+ if(keylog_file_fp) {
+ fclose(keylog_file_fp);
+ keylog_file_fp = NULL;
+ }
+}
+
+bool
+Curl_tls_keylog_enabled(void)
+{
+ return keylog_file_fp != NULL;
+}
+
+bool
+Curl_tls_keylog_write_line(const char *line)
+{
+ /* The current maximum valid keylog line length LF and NUL is 195. */
+ size_t linelen;
+ char buf[256];
+
+ if(!keylog_file_fp || !line) {
+ return false;
+ }
+
+ linelen = strlen(line);
+ if(linelen == 0 || linelen > sizeof(buf) - 2) {
+ /* Empty line or too big to fit in a LF and NUL. */
+ return false;
+ }
+
+ memcpy(buf, line, linelen);
+ if(line[linelen - 1] != '\n') {
+ buf[linelen++] = '\n';
+ }
+ buf[linelen] = '\0';
+
+ /* Using fputs here instead of fprintf since libcurl's fprintf replacement
+ may not be thread-safe. */
+ fputs(buf, keylog_file_fp);
+ return true;
+}
+
+bool
+Curl_tls_keylog_write(const char *label,
+ const unsigned char client_random[CLIENT_RANDOM_SIZE],
+ const unsigned char *secret, size_t secretlen)
+{
+ const char *hex = "0123456789ABCDEF";
+ size_t pos, i;
+ char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 +
+ 2 * SECRET_MAXLEN + 1 + 1];
+
+ if(!keylog_file_fp) {
+ return false;
+ }
+
+ pos = strlen(label);
+ if(pos > KEYLOG_LABEL_MAXLEN || !secretlen || secretlen > SECRET_MAXLEN) {
+ /* Should never happen - sanity check anyway. */
+ return false;
+ }
+
+ memcpy(line, label, pos);
+ line[pos++] = ' ';
+
+ /* Client Random */
+ for(i = 0; i < CLIENT_RANDOM_SIZE; i++) {
+ line[pos++] = hex[client_random[i] >> 4];
+ line[pos++] = hex[client_random[i] & 0xF];
+ }
+ line[pos++] = ' ';
+
+ /* Secret */
+ for(i = 0; i < secretlen; i++) {
+ line[pos++] = hex[secret[i] >> 4];
+ line[pos++] = hex[secret[i] & 0xF];
+ }
+ line[pos++] = '\n';
+ line[pos] = '\0';
+
+ /* Using fputs here instead of fprintf since libcurl's fprintf replacement
+ may not be thread-safe. */
+ fputs(line, keylog_file_fp);
+ return true;
+}
diff --git a/libs/libcurl/src/vtls/keylog.h b/libs/libcurl/src/vtls/keylog.h
new file mode 100644
index 0000000000..c6b99db938
--- /dev/null
+++ b/libs/libcurl/src/vtls/keylog.h
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_KEYLOG_H
+#define HEADER_CURL_KEYLOG_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, 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.haxx.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.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * Opens the TLS key log file if requested by the user. The SSLKEYLOGFILE
+ * environment variable specifies the output file.
+ */
+void Curl_tls_keylog_open(void);
+
+/*
+ * Closes the TLS key log file if not already.
+ */
+void Curl_tls_keylog_close(void);
+
+/*
+ * Returns true if the user successfully enabled the TLS key log file.
+ */
+bool Curl_tls_keylog_enabled(void);
+
+/*
+ * Appends a key log file entry.
+ * Returns true iff the key log file is open and a valid entry was provided.
+ */
+bool Curl_tls_keylog_write(const char *label,
+ const unsigned char client_random[32],
+ const unsigned char *secret, size_t secretlen);
+
+/*
+ * Appends a line to the key log file, ensure it is terminated by a LF.
+ * Returns true iff the key log file is open and a valid line was provided.
+ */
+bool Curl_tls_keylog_write_line(const char *line);
+
+#endif /* HEADER_CURL_KEYLOG_H */
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index cbf3d3dec9..ba31b8e788 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -239,7 +239,7 @@ mbed_connect_step1(struct connectdata *conn,
int sockindex)
{
struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
@@ -535,7 +535,7 @@ mbed_connect_step2(struct connectdata *conn,
{
int ret;
struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
const mbedtls_x509_crt *peercert;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
@@ -938,7 +938,7 @@ mbed_connect_common(struct connectdata *conn,
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking ? 0 : (time_t)timeout_ms);
+ nonblocking ? 0 : timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c
index cab1e390b4..7132bdfd22 100644
--- a/libs/libcurl/src/vtls/mesalink.c
+++ b/libs/libcurl/src/vtls/mesalink.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -542,9 +542,8 @@ mesalink_connect_common(struct connectdata *conn, int sockindex,
? sockfd
: CURL_SOCKET_BAD;
- what = Curl_socket_check(
- readfd, CURL_SOCKET_BAD, writefd,
- nonblocking ? 0 : (time_t)timeout_ms);
+ what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+ nonblocking ? 0 : timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c
index 16ec409e92..fca2926138 100644
--- a/libs/libcurl/src/vtls/nss.c
+++ b/libs/libcurl/src/vtls/nss.c
@@ -101,10 +101,10 @@ struct ptr_list_wrap {
struct curl_llist_element node;
};
-typedef struct {
+struct cipher_s {
const char *name;
int num;
-} cipher_s;
+};
#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \
CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \
@@ -116,7 +116,7 @@ typedef struct {
#define CERT_NewTempCertificate __CERT_NewTempCertificate
#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
-static const cipher_s cipherlist[] = {
+static const struct cipher_s cipherlist[] = {
/* SSL2 cipher suites */
{"rc4", SSL_EN_RC4_128_WITH_MD5},
{"rc4-md5", SSL_EN_RC4_128_WITH_MD5},
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 176fa522a5..790d35862a 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -41,11 +41,17 @@
#include "slist.h"
#include "select.h"
#include "vtls.h"
+#include "keylog.h"
#include "strcase.h"
#include "hostcheck.h"
#include "multiif.h"
#include "strerror.h"
#include "curl_printf.h"
+
+#if defined(USE_WIN32_CRYPTO)
+#include <wincrypt.h>
+#endif
+
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>
@@ -207,24 +213,14 @@
"ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
#endif
-#define ENABLE_SSLKEYLOGFILE
-
-#ifdef ENABLE_SSLKEYLOGFILE
-typedef struct ssl_tap_state {
- int master_key_length;
- unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
- unsigned char client_random[SSL3_RANDOM_SIZE];
-} ssl_tap_state_t;
-#endif /* ENABLE_SSLKEYLOGFILE */
-
struct ssl_backend_data {
/* these ones requires specific SSL-types */
SSL_CTX* ctx;
SSL* handle;
X509* server_cert;
-#ifdef ENABLE_SSLKEYLOGFILE
- /* tap_state holds the last seen master key if we're logging them */
- ssl_tap_state_t tap_state;
+#ifndef HAVE_KEYLOG_CALLBACK
+ /* Set to true once a valid keylog entry has been created to avoid dupes. */
+ bool keylog_done;
#endif
};
@@ -236,57 +232,27 @@ struct ssl_backend_data {
*/
#define RAND_LOAD_LENGTH 1024
-#ifdef ENABLE_SSLKEYLOGFILE
-/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
-static FILE *keylog_file_fp;
-
#ifdef HAVE_KEYLOG_CALLBACK
static void ossl_keylog_callback(const SSL *ssl, const char *line)
{
(void)ssl;
- /* Using fputs here instead of fprintf since libcurl's fprintf replacement
- may not be thread-safe. */
- if(keylog_file_fp && line && *line) {
- char stackbuf[256];
- char *buf;
- size_t linelen = strlen(line);
-
- if(linelen <= sizeof(stackbuf) - 2)
- buf = stackbuf;
- else {
- buf = malloc(linelen + 2);
- if(!buf)
- return;
- }
- memcpy(buf, line, linelen);
- buf[linelen] = '\n';
- buf[linelen + 1] = '\0';
-
- fputs(buf, keylog_file_fp);
- if(buf != stackbuf)
- free(buf);
- }
+ Curl_tls_keylog_write_line(line);
}
#else
-#define KEYLOG_PREFIX "CLIENT_RANDOM "
-#define KEYLOG_PREFIX_LEN (sizeof(KEYLOG_PREFIX) - 1)
/*
- * tap_ssl_key is called by libcurl to make the CLIENT_RANDOMs if the OpenSSL
- * being used doesn't have native support for doing that.
+ * ossl_log_tls12_secret is called by libcurl to make the CLIENT_RANDOMs if the
+ * OpenSSL being used doesn't have native support for doing that.
*/
-static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
+static void
+ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done)
{
- const char *hex = "0123456789ABCDEF";
- int pos, i;
- char line[KEYLOG_PREFIX_LEN + 2 * SSL3_RANDOM_SIZE + 1 +
- 2 * SSL_MAX_MASTER_KEY_LENGTH + 1 + 1];
const SSL_SESSION *session = SSL_get_session(ssl);
unsigned char client_random[SSL3_RANDOM_SIZE];
unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
int master_key_length = 0;
- if(!session || !keylog_file_fp)
+ if(!session || *keylog_done)
return;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
@@ -305,44 +271,17 @@ static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
}
#endif
+ /* The handshake has not progressed sufficiently yet, or this is a TLS 1.3
+ * session (when curl was built with older OpenSSL headers and running with
+ * newer OpenSSL runtime libraries). */
if(master_key_length <= 0)
return;
- /* Skip writing keys if there is no key or it did not change. */
- if(state->master_key_length == master_key_length &&
- !memcmp(state->master_key, master_key, master_key_length) &&
- !memcmp(state->client_random, client_random, SSL3_RANDOM_SIZE)) {
- return;
- }
-
- state->master_key_length = master_key_length;
- memcpy(state->master_key, master_key, master_key_length);
- memcpy(state->client_random, client_random, SSL3_RANDOM_SIZE);
-
- memcpy(line, KEYLOG_PREFIX, KEYLOG_PREFIX_LEN);
- pos = KEYLOG_PREFIX_LEN;
-
- /* Client Random for SSLv3/TLS */
- for(i = 0; i < SSL3_RANDOM_SIZE; i++) {
- line[pos++] = hex[client_random[i] >> 4];
- line[pos++] = hex[client_random[i] & 0xF];
- }
- line[pos++] = ' ';
-
- /* Master Secret (size is at most SSL_MAX_MASTER_KEY_LENGTH) */
- for(i = 0; i < master_key_length; i++) {
- line[pos++] = hex[master_key[i] >> 4];
- line[pos++] = hex[master_key[i] & 0xF];
- }
- line[pos++] = '\n';
- line[pos] = '\0';
-
- /* Using fputs here instead of fprintf since libcurl's fprintf replacement
- may not be thread-safe. */
- fputs(line, keylog_file_fp);
+ *keylog_done = true;
+ Curl_tls_keylog_write("CLIENT_RANDOM", client_random,
+ master_key, master_key_length);
}
#endif /* !HAVE_KEYLOG_CALLBACK */
-#endif /* ENABLE_SSLKEYLOGFILE */
static const char *SSL_ERROR_to_str(int err)
{
@@ -616,12 +555,136 @@ static bool is_pkcs11_uri(const char *string)
static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
const char *engine);
+static int
+SSL_CTX_use_certificate_bio(SSL_CTX *ctx, BIO *in, int type,
+ const char *key_passwd)
+{
+ int ret = 0;
+ X509 *x = NULL;
+
+ if(type == SSL_FILETYPE_ASN1) {
+ /* j = ERR_R_ASN1_LIB; */
+ x = d2i_X509_bio(in, NULL);
+ }
+ else if(type == SSL_FILETYPE_PEM) {
+ /* ERR_R_PEM_LIB; */
+ x = PEM_read_bio_X509(in, NULL,
+ passwd_callback, (void *)key_passwd);
+ }
+ else {
+ ret = 0;
+ goto end;
+ }
+
+ if(x == NULL) {
+ ret = 0;
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+ end:
+ X509_free(x);
+ return ret;
+}
+
+static int
+SSL_CTX_use_PrivateKey_bio(SSL_CTX *ctx, BIO* in, int type,
+ const char *key_passwd)
+{
+ int ret = 0;
+ EVP_PKEY *pkey = NULL;
+
+ if(type == SSL_FILETYPE_PEM)
+ pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback,
+ (void *)key_passwd);
+ else if(type == SSL_FILETYPE_ASN1)
+ pkey = d2i_PrivateKey_bio(in, NULL);
+ else {
+ ret = 0;
+ goto end;
+ }
+ if(pkey == NULL) {
+ ret = 0;
+ goto end;
+ }
+ ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ EVP_PKEY_free(pkey);
+ end:
+ return ret;
+}
+
+static int
+SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
+ const char *key_passwd)
+{
+/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
+#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */
+ int ret = 0;
+ X509 *x = NULL;
+ void *passwd_callback_userdata = (void *)key_passwd;
+
+ ERR_clear_error();
+
+ x = PEM_read_bio_X509_AUX(in, NULL,
+ passwd_callback, (void *)key_passwd);
+
+ if(x == NULL) {
+ ret = 0;
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+
+ if(ERR_peek_error() != 0)
+ ret = 0;
+
+ if(ret) {
+ X509 *ca;
+ unsigned long err;
+
+ if(!SSL_CTX_clear_chain_certs(ctx)) {
+ ret = 0;
+ goto end;
+ }
+
+ while((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
+ passwd_callback_userdata))
+ != NULL) {
+
+ if(!SSL_CTX_add0_chain_cert(ctx, ca)) {
+ X509_free(ca);
+ ret = 0;
+ goto end;
+ }
+ }
+
+ err = ERR_peek_last_error();
+ if((ERR_GET_LIB(err) == ERR_LIB_PEM) &&
+ (ERR_GET_REASON(err) == PEM_R_NO_START_LINE))
+ ERR_clear_error();
+ else
+ ret = 0;
+ }
+
+ end:
+ X509_free(x);
+ return ret;
+#else
+ (void)ctx; /* unused */
+ (void)in; /* unused */
+ (void)key_passwd; /* unused */
+ return 0;
+#endif
+}
+
static
int cert_stuff(struct connectdata *conn,
SSL_CTX* ctx,
char *cert_file,
+ BIO *cert_bio,
const char *cert_type,
char *key_file,
+ BIO* key_bio,
const char *key_type,
char *key_passwd)
{
@@ -631,10 +694,11 @@ int cert_stuff(struct connectdata *conn,
int file_type = do_file_type(cert_type);
- if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) {
+ if(cert_file || cert_bio || (file_type == SSL_FILETYPE_ENGINE)) {
SSL *ssl;
X509 *x509;
int cert_done = 0;
+ int cert_use_result;
if(key_passwd) {
/* set the password in the callback userdata */
@@ -647,8 +711,10 @@ int cert_stuff(struct connectdata *conn,
switch(file_type) {
case SSL_FILETYPE_PEM:
/* SSL_CTX_use_certificate_chain_file() only works on PEM files */
- if(SSL_CTX_use_certificate_chain_file(ctx,
- cert_file) != 1) {
+ cert_use_result = cert_bio ?
+ SSL_CTX_use_certificate_chain_bio(ctx, cert_bio, key_passwd) :
+ SSL_CTX_use_certificate_chain_file(ctx, cert_file);
+ if(cert_use_result != 1) {
failf(data,
"could not load PEM client certificate, " OSSL_PACKAGE
" error %s, "
@@ -663,9 +729,12 @@ int cert_stuff(struct connectdata *conn,
/* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
we use the case above for PEM so this can only be performed with
ASN1 files. */
- if(SSL_CTX_use_certificate_file(ctx,
- cert_file,
- file_type) != 1) {
+
+ cert_use_result = cert_bio ?
+ SSL_CTX_use_certificate_bio(ctx, cert_bio,
+ file_type, key_passwd) :
+ SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
+ if(cert_use_result != 1) {
failf(data,
"could not load ASN1 client certificate, " OSSL_PACKAGE
" error %s, "
@@ -745,27 +814,31 @@ int cert_stuff(struct connectdata *conn,
PKCS12 *p12 = NULL;
EVP_PKEY *pri;
STACK_OF(X509) *ca = NULL;
+ if(!cert_bio) {
+ fp = BIO_new(BIO_s_file());
+ if(fp == NULL) {
+ failf(data,
+ "BIO_new return NULL, " OSSL_PACKAGE
+ " error %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)) );
+ return 0;
+ }
- fp = BIO_new(BIO_s_file());
- if(fp == NULL) {
- failf(data,
- "BIO_new return NULL, " OSSL_PACKAGE
- " error %s",
- ossl_strerror(ERR_get_error(), error_buffer,
- sizeof(error_buffer)) );
- return 0;
+ if(BIO_read_filename(fp, cert_file) <= 0) {
+ failf(data, "could not open PKCS12 file '%s'", cert_file);
+ BIO_free(fp);
+ return 0;
+ }
}
- if(BIO_read_filename(fp, cert_file) <= 0) {
- failf(data, "could not open PKCS12 file '%s'", cert_file);
+ p12 = d2i_PKCS12_bio(cert_bio ? cert_bio : fp, NULL);
+ if(fp)
BIO_free(fp);
- return 0;
- }
- p12 = d2i_PKCS12_bio(fp, NULL);
- BIO_free(fp);
if(!p12) {
- failf(data, "error reading PKCS12 file '%s'", cert_file);
+ failf(data, "error reading PKCS12 file '%s'",
+ cert_bio ? "(memory blob)" : cert_file);
return 0;
}
@@ -846,8 +919,10 @@ int cert_stuff(struct connectdata *conn,
return 0;
}
- if(!key_file)
+ if((!key_file) && (!key_bio)) {
key_file = cert_file;
+ key_bio = cert_bio;
+ }
else
file_type = do_file_type(key_type);
@@ -857,9 +932,12 @@ int cert_stuff(struct connectdata *conn,
break;
/* FALLTHROUGH */
case SSL_FILETYPE_ASN1:
- if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
+ cert_use_result = key_bio ?
+ SSL_CTX_use_PrivateKey_bio(ctx, key_bio, file_type, key_passwd) :
+ SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type);
+ if(cert_use_result != 1) {
failf(data, "unable to set private key file: '%s' type %s",
- key_file, key_type?key_type:"PEM");
+ key_file?key_file:"(memory blob)", key_type?key_type:"PEM");
return 0;
}
break;
@@ -1019,10 +1097,6 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
*/
static int Curl_ossl_init(void)
{
-#ifdef ENABLE_SSLKEYLOGFILE
- char *keylog_file_name;
-#endif
-
OPENSSL_load_builtin_modules();
#ifdef USE_OPENSSL_ENGINE
@@ -1055,26 +1129,7 @@ static int Curl_ossl_init(void)
OpenSSL_add_all_algorithms();
#endif
-#ifdef ENABLE_SSLKEYLOGFILE
- if(!keylog_file_fp) {
- keylog_file_name = curl_getenv("SSLKEYLOGFILE");
- if(keylog_file_name) {
- keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT);
- if(keylog_file_fp) {
-#ifdef WIN32
- if(setvbuf(keylog_file_fp, NULL, _IONBF, 0))
-#else
- if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096))
-#endif
- {
- fclose(keylog_file_fp);
- keylog_file_fp = NULL;
- }
- }
- Curl_safefree(keylog_file_name);
- }
- }
-#endif
+ Curl_tls_keylog_open();
/* Initialize the extra data indexes */
if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0)
@@ -1117,12 +1172,7 @@ static void Curl_ossl_cleanup(void)
#endif
#endif
-#ifdef ENABLE_SSLKEYLOGFILE
- if(keylog_file_fp) {
- fclose(keylog_file_fp);
- keylog_file_fp = NULL;
- }
-#endif
+ Curl_tls_keylog_close();
}
/*
@@ -1289,7 +1339,9 @@ static void ossl_close(struct ssl_connect_data *connssl)
static void Curl_ossl_close(struct connectdata *conn, int sockindex)
{
ossl_close(&conn->ssl[sockindex]);
+#ifndef CURL_DISABLE_PROXY
ossl_close(&conn->proxy_ssl[sockindex]);
+#endif
}
/*
@@ -1516,10 +1568,16 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
CURLcode result = CURLE_OK;
bool dNSName = FALSE; /* if a dNSName field exists in the cert */
bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
+#ifndef CURL_DISABLE_PROXY
+ const char * const hostname = SSL_IS_PROXY() ?
+ conn->http_proxy.host.name : conn->host.name;
const char * const dispname = SSL_IS_PROXY() ?
conn->http_proxy.host.dispname : conn->host.dispname;
+#else
+ /* disabled proxy support */
+ const char * const hostname = conn->host.name;
+ const char * const dispname = conn->host.dispname;
+#endif
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
@@ -2398,21 +2456,31 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
bool sni;
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+#else
+ const char * const hostname = conn->host.name;
+#endif
+
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
struct in_addr addr;
#endif
#endif
+#ifndef CURL_DISABLE_PROXY
long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+#else
+ long * const certverifyresult = &data->set.ssl.certverifyresult;
+#endif
const long int ssl_version = SSL_CONN_CONFIG(version);
#ifdef USE_TLS_SRP
const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
#endif
char * const ssl_cert = SSL_SET_OPTION(cert);
+ const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
@@ -2420,6 +2488,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
char error_buffer[256];
struct ssl_backend_data *backend = connssl->backend;
+ bool imported_native_ca = false;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
@@ -2634,8 +2703,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
unsigned char protocols[128];
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
- (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+ if(data->set.httpversion >= CURL_HTTP_VERSION_2
+#ifndef CURL_DISABLE_PROXY
+ && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+#endif
+ ) {
protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
@@ -2657,10 +2729,33 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
- if(ssl_cert || ssl_cert_type) {
- if(!cert_stuff(conn, backend->ctx, ssl_cert, ssl_cert_type,
- SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
- SSL_SET_OPTION(key_passwd))) {
+ if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
+ BIO *ssl_cert_bio = NULL;
+ BIO *ssl_key_bio = NULL;
+ int result_cert_stuff;
+ if(ssl_cert_blob) {
+ /* the typecast of blob->len is fine since it is guaranteed to never be
+ larger than CURL_MAX_INPUT_LENGTH */
+ ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data,
+ (int)ssl_cert_blob->len);
+ if(!ssl_cert_bio)
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ if(SSL_SET_OPTION(key_blob)) {
+ ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data,
+ (int)SSL_SET_OPTION(key_blob)->len);
+ if(!ssl_key_bio)
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ result_cert_stuff = cert_stuff(conn, backend->ctx,
+ ssl_cert, ssl_cert_bio, ssl_cert_type,
+ SSL_SET_OPTION(key), ssl_key_bio,
+ SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd));
+ if(ssl_cert_bio)
+ BIO_free(ssl_cert_bio);
+ if(ssl_key_bio)
+ BIO_free(ssl_key_bio);
+ if(!result_cert_stuff) {
/* failf() is already done in cert_stuff() */
return CURLE_SSL_CERTPROBLEM;
}
@@ -2720,38 +2815,186 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
+
+#if defined(USE_WIN32_CRYPTO)
+ /* Import certificates from the Windows root certificate store if requested.
+ https://stackoverflow.com/questions/9507184/
+ https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037
+ https://tools.ietf.org/html/rfc5280 */
+ if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) &&
+ (SSL_SET_OPTION(native_ca_store))) {
+ X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx);
+ HCERTSTORE hStore = CertOpenSystemStoreA((HCRYPTPROV_LEGACY)NULL, "ROOT");
+
+ if(hStore) {
+ PCCERT_CONTEXT pContext = NULL;
+ /* The array of enhanced key usage OIDs will vary per certificate and is
+ declared outside of the loop so that rather than malloc/free each
+ iteration we can grow it with realloc, when necessary. */
+ CERT_ENHKEY_USAGE *enhkey_usage = NULL;
+ DWORD enhkey_usage_size = 0;
+
+ /* This loop makes a best effort to import all valid certificates from
+ the MS root store. If a certificate cannot be imported it is skipped.
+ 'result' is used to store only hard-fail conditions (such as out of
+ memory) that cause an early break. */
+ result = CURLE_OK;
+ for(;;) {
+ X509 *x509;
+ FILETIME now;
+ BYTE key_usage[2];
+ DWORD req_size;
+ const unsigned char *encoded_cert;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ char cert_name[256];
+#endif
+
+ pContext = CertEnumCertificatesInStore(hStore, pContext);
+ if(!pContext)
+ break;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
+ NULL, cert_name, sizeof(cert_name))) {
+ strcpy(cert_name, "Unknown");
+ }
+ infof(data, "SSL: Checking cert \"%s\"\n", cert_name);
+#endif
+
+ encoded_cert = (const unsigned char *)pContext->pbCertEncoded;
+ if(!encoded_cert)
+ continue;
+
+ GetSystemTimeAsFileTime(&now);
+ if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 ||
+ CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0)
+ continue;
+
+ /* If key usage exists check for signing attribute */
+ if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType,
+ pContext->pCertInfo,
+ key_usage, sizeof(key_usage))) {
+ if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE))
+ continue;
+ }
+ else if(GetLastError())
+ continue;
+
+ /* If enhanced key usage exists check for server auth attribute.
+ *
+ * Note "In a Microsoft environment, a certificate might also have EKU
+ * extended properties that specify valid uses for the certificate."
+ * The call below checks both, and behavior varies depending on what is
+ * found. For more details see CertGetEnhancedKeyUsage doc.
+ */
+ if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) {
+ if(req_size && req_size > enhkey_usage_size) {
+ void *tmp = realloc(enhkey_usage, req_size);
+
+ if(!tmp) {
+ failf(data, "SSL: Out of memory allocating for OID list");
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ enhkey_usage = (CERT_ENHKEY_USAGE *)tmp;
+ enhkey_usage_size = req_size;
+ }
+
+ if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) {
+ if(!enhkey_usage->cUsageIdentifier) {
+ /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is
+ good for all uses. If it returns zero, the certificate has no
+ valid uses." */
+ if(GetLastError() != CRYPT_E_NOT_FOUND)
+ continue;
+ }
+ else {
+ DWORD i;
+ bool found = false;
+
+ for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) {
+ if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */,
+ enhkey_usage->rgpszUsageIdentifier[i])) {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found)
+ continue;
+ }
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+
+ x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded);
+ if(!x509)
+ continue;
+
+ /* Try to import the certificate. This may fail for legitimate reasons
+ such as duplicate certificate, which is allowed by MS but not
+ OpenSSL. */
+ if(X509_STORE_add_cert(store, x509) == 1) {
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ infof(data, "SSL: Imported cert \"%s\"\n", cert_name);
+#endif
+ imported_native_ca = true;
+ }
+ X509_free(x509);
+ }
+
+ free(enhkey_usage);
+ CertFreeCertificateContext(pContext);
+ CertCloseStore(hStore, 0);
+
+ if(result)
+ return result;
+ }
+ if(imported_native_ca)
+ infof(data, "successfully imported windows ca store\n");
+ else
+ infof(data, "error importing windows ca store, continuing anyway\n");
+ }
+#endif
+
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
/* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */
- if(ssl_cafile) {
- if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) {
- if(verifypeer) {
- /* Fail if we insist on successfully verifying the server. */
- failf(data, "error setting certificate file: %s", ssl_cafile);
- return CURLE_SSL_CACERT_BADFILE;
+ {
+ if(ssl_cafile) {
+ if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) {
+ if(verifypeer) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate file: %s", ssl_cafile);
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ /* Continue with a warning if no certificate verif is required. */
+ infof(data, "error setting certificate file, continuing anyway\n");
}
- /* Continue with a warning if no certificate verification is required. */
- infof(data, "error setting certificate file, continuing anyway\n");
+ infof(data, " CAfile: %s\n", ssl_cafile);
}
- infof(data, " CAfile: %s\n", ssl_cafile);
- }
- if(ssl_capath) {
- if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) {
- if(verifypeer) {
- /* Fail if we insist on successfully verifying the server. */
- failf(data, "error setting certificate path: %s", ssl_capath);
- return CURLE_SSL_CACERT_BADFILE;
+ if(ssl_capath) {
+ if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) {
+ if(verifypeer) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate path: %s", ssl_capath);
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ /* Continue with a warning if no certificate verif is required. */
+ infof(data, "error setting certificate path, continuing anyway\n");
}
- /* Continue with a warning if no certificate verification is required. */
- infof(data, "error setting certificate path, continuing anyway\n");
+ infof(data, " CApath: %s\n", ssl_capath);
}
- infof(data, " CApath: %s\n", ssl_capath);
}
#else
if(ssl_cafile || ssl_capath) {
/* tell SSL where to find CA certificates that are used to verify
the servers certificate. */
if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) {
- if(verifypeer) {
+ if(verifypeer && !imported_native_ca) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:\n"
" CAfile: %s\n CApath: %s",
@@ -2759,7 +3002,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
ssl_capath ? ssl_capath : "none");
return CURLE_SSL_CACERT_BADFILE;
}
- /* Just continue with a warning if no strict certificate verification
+ /* Just continue with a warning if no strict certificate verification
is required. */
infof(data, "error setting certificate verify locations,"
" continuing anyway:\n");
@@ -2777,7 +3020,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#endif
#ifdef CURL_CA_FALLBACK
- else if(verifypeer) {
+ if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) {
/* verifying the peer without any CA certificates won't
work so use openssl's built in default as fallback */
SSL_CTX_set_default_verify_paths(backend->ctx);
@@ -2805,21 +3048,24 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(verifypeer) {
/* Try building a chain using issuers in the trusted store first to avoid
problems with server-sent legacy intermediates. Newer versions of
- OpenSSL do alternate chain checking by default which gives us the same
- fix without as much of a performance hit (slight), so we prefer that if
- available.
+ OpenSSL do alternate chain checking by default but we do not know how to
+ determine that in a reliable manner.
https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
*/
-#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
+#if defined(X509_V_FLAG_TRUSTED_FIRST)
X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
X509_V_FLAG_TRUSTED_FIRST);
#endif
#ifdef X509_V_FLAG_PARTIAL_CHAIN
- if(!SSL_SET_OPTION(no_partialchain)) {
+ if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) {
/* Have intermediate certificates in the trust store be treated as
trust-anchors, in the same way as self-signed root CA certificates
are. This allows users to verify servers using the intermediate cert
- only, instead of needing the whole chain. */
+ only, instead of needing the whole chain.
+
+ Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we
+ cannot do partial chains with CRL check.
+ */
X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
X509_V_FLAG_PARTIAL_CHAIN);
}
@@ -2834,8 +3080,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
/* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */
-#if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK)
- if(keylog_file_fp) {
+#ifdef HAVE_KEYLOG_CALLBACK
+ if(Curl_tls_keylog_enabled()) {
SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback);
}
#endif
@@ -2922,6 +3168,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
Curl_ssl_sessionid_unlock(conn);
}
+#ifndef CURL_DISABLE_PROXY
if(conn->proxy_ssl[sockindex].use) {
BIO *const bio = BIO_new(BIO_f_ssl());
SSL *handle = conn->proxy_ssl[sockindex].backend->handle;
@@ -2931,7 +3178,9 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
BIO_set_ssl(bio, handle, FALSE);
SSL_set_bio(backend->handle, bio, bio);
}
- else if(!SSL_set_fd(backend->handle, (int)sockfd)) {
+ else
+#endif
+ if(!SSL_set_fd(backend->handle, (int)sockfd)) {
/* pass the raw socket into the SSL layers */
failf(data, "SSL: SSL_set_fd failed: %s",
ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
@@ -2948,8 +3197,12 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
struct Curl_easy *data = conn->data;
int err;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifndef CURL_DISABLE_PROXY
long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+#else
+ long * const certverifyresult = &data->set.ssl.certverifyresult;
+#endif
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -2958,10 +3211,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
ERR_clear_error();
err = SSL_connect(backend->handle);
- /* If keylogging is enabled but the keylog callback is not supported then log
- secrets here, immediately after SSL_connect by using tap_ssl_key. */
-#if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK)
- tap_ssl_key(backend->handle, &backend->tap_state);
+#ifndef HAVE_KEYLOG_CALLBACK
+ if(Curl_tls_keylog_enabled()) {
+ /* If key logging is enabled, wait for the handshake to complete and then
+ * proceed with logging secrets (for TLS 1.2 or older).
+ */
+ ossl_log_tls12_secret(backend->handle, &backend->keylog_done);
+ }
#endif
/* 1 is fine
@@ -3032,9 +3288,14 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
* the SO_ERROR is also lost.
*/
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name : conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+ const char * const hostname = conn->host.name;
+ const long int port = conn->remote_port;
+#endif
char extramsg[80]="";
int sockerr = SOCKERRNO;
if(sockerr && detail == SSL_ERROR_SYSCALL)
@@ -3487,8 +3748,12 @@ static CURLcode servercert(struct connectdata *conn,
char error_buffer[256]="";
char buffer[2048];
const char *ptr;
+#ifndef CURL_DISABLE_PROXY
long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+#else
+ long * const certverifyresult = &data->set.ssl.certverifyresult;
+#endif
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
@@ -3552,27 +3817,32 @@ static CURLcode servercert(struct connectdata *conn,
deallocating the certificate. */
/* e.g. match issuer name with provided issuer certificate */
- if(SSL_SET_OPTION(issuercert)) {
- fp = BIO_new(BIO_s_file());
- if(fp == NULL) {
- failf(data,
- "BIO_new return NULL, " OSSL_PACKAGE
- " error %s",
- ossl_strerror(ERR_get_error(), error_buffer,
- sizeof(error_buffer)) );
- X509_free(backend->server_cert);
- backend->server_cert = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
+ if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) {
+ if(SSL_SET_OPTION(issuercert_blob))
+ fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data,
+ (int)SSL_SET_OPTION(issuercert_blob)->len);
+ else {
+ fp = BIO_new(BIO_s_file());
+ if(fp == NULL) {
+ failf(data,
+ "BIO_new return NULL, " OSSL_PACKAGE
+ " error %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)) );
+ X509_free(backend->server_cert);
+ backend->server_cert = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
- if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
- if(strict)
- failf(data, "SSL: Unable to open issuer cert (%s)",
- SSL_SET_OPTION(issuercert));
- BIO_free(fp);
- X509_free(backend->server_cert);
- backend->server_cert = NULL;
- return CURLE_SSL_ISSUER_ERROR;
+ if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
+ if(strict)
+ failf(data, "SSL: Unable to open issuer cert (%s)",
+ SSL_SET_OPTION(issuercert));
+ BIO_free(fp);
+ X509_free(backend->server_cert);
+ backend->server_cert = NULL;
+ return CURLE_SSL_ISSUER_ERROR;
+ }
}
issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL);
@@ -3690,7 +3960,6 @@ static CURLcode ossl_connect_common(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
- timediff_t timeout_ms;
int what;
/* check if the connection has already been established */
@@ -3701,7 +3970,7 @@ static CURLcode ossl_connect_common(struct connectdata *conn,
if(ssl_connect_1 == connssl->connecting_state) {
/* Find out how much more time we're allowed */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
@@ -3719,7 +3988,7 @@ static CURLcode ossl_connect_common(struct connectdata *conn,
ssl_connect_2_writing == connssl->connecting_state) {
/* check allowed time left */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
@@ -3737,7 +4006,7 @@ static CURLcode ossl_connect_common(struct connectdata *conn,
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking?0:(time_t)timeout_ms);
+ nonblocking?0:timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -3816,14 +4085,15 @@ static bool Curl_ossl_data_pending(const struct connectdata *conn,
int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
- const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
-
if(connssl->backend->handle && SSL_pending(connssl->backend->handle))
return TRUE;
-
- if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
- return TRUE;
-
+#ifndef CURL_DISABLE_PROXY
+ {
+ const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
+ if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
+ return TRUE;
+ }
+#endif
return FALSE;
}
@@ -3884,8 +4154,11 @@ static ssize_t ossl_send(struct connectdata *conn,
sslerror = ERR_get_error();
if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL &&
ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET &&
- conn->ssl[sockindex].state == ssl_connection_complete &&
- conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
+ conn->ssl[sockindex].state == ssl_connection_complete
+#ifndef CURL_DISABLE_PROXY
+ && conn->proxy_ssl[sockindex].state == ssl_connection_complete
+#endif
+ ) {
char ver[120];
Curl_ossl_version(ver, 120);
failf(conn->data, "Error: %s does not support double SSL tunneling.",
@@ -4109,7 +4382,7 @@ static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
unsigned int len = 0;
(void) unused;
- mdctx = EVP_MD_CTX_create();
+ mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
EVP_DigestUpdate(mdctx, tmp, tmplen);
EVP_DigestFinal_ex(mdctx, sha256sum, &len);
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 49659bb7ab..1996526066 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -39,10 +39,11 @@
#include "schannel.h"
#include "vtls.h"
+#include "strcase.h"
#include "sendf.h"
#include "connect.h" /* for the connect timeout */
#include "strerror.h"
-#include "select.h" /* for the socket readyness */
+#include "select.h" /* for the socket readiness */
#include "inet_pton.h" /* for IP addr SNI check */
#include "curl_multibyte.h"
#include "warnless.h"
@@ -51,7 +52,7 @@
#include "multiif.h"
#include "system_win32.h"
- /* The last #include file should be: */
+/* The last #include file should be: */
#include "curl_memory.h"
#include "memdebug.h"
@@ -169,25 +170,25 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
long i = ssl_version;
switch(ssl_version_max) {
- case CURL_SSLVERSION_MAX_NONE:
- case CURL_SSLVERSION_MAX_DEFAULT:
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
- break;
+ case CURL_SSLVERSION_MAX_NONE:
+ case CURL_SSLVERSION_MAX_DEFAULT:
+ ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+ break;
}
for(; i <= (ssl_version_max >> 16); ++i) {
switch(i) {
- case CURL_SSLVERSION_TLSv1_0:
- schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
- break;
- case CURL_SSLVERSION_TLSv1_1:
- schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
- break;
- case CURL_SSLVERSION_TLSv1_2:
- schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
- break;
- case CURL_SSLVERSION_TLSv1_3:
- failf(data, "schannel: TLS 1.3 is not yet supported");
- return CURLE_SSL_CONNECT_ERROR;
+ case CURL_SSLVERSION_TLSv1_0:
+ schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
+ break;
+ case CURL_SSLVERSION_TLSv1_3:
+ failf(data, "schannel: TLS 1.3 is not yet supported");
+ return CURLE_SSL_CONNECT_ERROR;
}
}
return CURLE_OK;
@@ -195,9 +196,9 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
/*longest is 26, buffer is slightly bigger*/
#define LONGEST_ALG_ID 32
-#define CIPHEROPTION(X) \
-if(strcmp(#X, tmp) == 0) \
- return X
+#define CIPHEROPTION(X) \
+ if(strcmp(#X, tmp) == 0) \
+ return X
static int
get_alg_id_by_name(char *name)
@@ -273,11 +274,11 @@ get_alg_id_by_name(char *name)
#ifdef CALG_HMAC
CIPHEROPTION(CALG_HMAC);
#endif
-#if !defined(__W32API_MAJOR_VERSION) || \
- !defined(__W32API_MINOR_VERSION) || \
- defined(__MINGW64_VERSION_MAJOR) || \
- (__W32API_MAJOR_VERSION > 5) || \
- ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0))
+#if !defined(__W32API_MAJOR_VERSION) || \
+ !defined(__W32API_MINOR_VERSION) || \
+ defined(__MINGW64_VERSION_MAJOR) || \
+ (__W32API_MAJOR_VERSION > 5) || \
+ ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0))
/* CALG_TLS1PRF has a syntax error in MinGW's w32api up to version 5.0,
see https://osdn.net/projects/mingw/ticket/38391 */
CIPHEROPTION(CALG_TLS1PRF);
@@ -339,7 +340,7 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers)
if(startCur)
startCur++;
}
- schannel_cred->palgSupportedAlgs = algIds;
+ schannel_cred->palgSupportedAlgs = algIds;
schannel_cred->cSupportedAlgs = algCount;
return CURLE_OK;
}
@@ -424,8 +425,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
#endif
TCHAR *host_name;
CURLcode result;
+#ifndef CURL_DISABLE_PROXY
char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+#else
+ char * const hostname = conn->host.name;
+#endif
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
@@ -433,20 +438,20 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
- /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
- algorithms that may not be supported by all servers. */
- infof(data, "schannel: Windows version is old and may not be able to "
- "connect to some servers due to lack of SNI, algorithms, etc.\n");
+ /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
+ algorithms that may not be supported by all servers. */
+ infof(data, "schannel: Windows version is old and may not be able to "
+ "connect to some servers due to lack of SNI, algorithms, etc.\n");
}
#ifdef HAS_ALPN
/* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
Also it doesn't seem to be supported for Wine, see curl bug #983. */
BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
- !GetProcAddress(GetModuleHandleA("ntdll"),
- "wine_get_version") &&
- Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
- VERSION_GREATER_THAN_EQUAL);
+ !GetProcAddress(GetModuleHandleA("ntdll"),
+ "wine_get_version") &&
+ Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL);
#else
BACKEND->use_alpn = false;
#endif
@@ -555,12 +560,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
- {
- result = set_ssl_version_min_max(&schannel_cred, conn);
- if(result != CURLE_OK)
- return result;
- break;
- }
+ {
+ result = set_ssl_version_min_max(&schannel_cred, conn);
+ if(result != CURLE_OK)
+ return result;
+ break;
+ }
case CURL_SSLVERSION_SSLv3:
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
break;
@@ -583,105 +588,133 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
#ifdef HAS_CLIENT_CERT_PATH
/* client certificate */
- if(data->set.ssl.cert) {
- DWORD cert_store_name;
+ if(data->set.ssl.cert || data->set.ssl.cert_blob) {
+ DWORD cert_store_name = 0;
TCHAR *cert_store_path = NULL;
- TCHAR *cert_thumbprint_str;
+ TCHAR *cert_thumbprint_str = NULL;
CRYPT_HASH_BLOB cert_thumbprint;
BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
- HCERTSTORE cert_store;
+ HCERTSTORE cert_store = NULL;
FILE *fInCert = NULL;
+ void *certdata = NULL;
+ size_t certsize = 0;
+ bool blob = data->set.ssl.cert_blob != NULL;
+ TCHAR *cert_path = NULL;
+ if(blob) {
+ certdata = data->set.ssl.cert_blob->data;
+ certsize = data->set.ssl.cert_blob->len;
+ }
+ else {
+ cert_path = curlx_convert_UTF8_to_tchar(data->set.ssl.cert);
+ if(!cert_path)
+ return CURLE_OUT_OF_MEMORY;
- TCHAR *cert_path = Curl_convert_UTF8_to_tchar(data->set.ssl.cert);
- if(!cert_path)
- return CURLE_OUT_OF_MEMORY;
+ result = get_cert_location(cert_path, &cert_store_name,
+ &cert_store_path, &cert_thumbprint_str);
- result = get_cert_location(cert_path, &cert_store_name,
- &cert_store_path, &cert_thumbprint_str);
- if((result != CURLE_OK) && (data->set.ssl.cert[0]!='\0'))
- fInCert = fopen(data->set.ssl.cert, "rb");
+ if(result && (data->set.ssl.cert[0]!='\0'))
+ fInCert = fopen(data->set.ssl.cert, "rb");
- if((result != CURLE_OK) && (fInCert == NULL)) {
- failf(data, "schannel: Failed to get certificate location"
- " or file for %s",
- data->set.ssl.cert);
- Curl_unicodefree(cert_path);
- return result;
+ if(result && !fInCert) {
+ failf(data, "schannel: Failed to get certificate location"
+ " or file for %s",
+ data->set.ssl.cert);
+ curlx_unicodefree(cert_path);
+ return result;
+ }
}
- if(fInCert) {
+ if((fInCert || blob) && (data->set.ssl.cert_type) &&
+ (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
+ failf(data, "schannel: certificate format compatibility error "
+ " for %s",
+ blob ? "(memory blob)" : data->set.ssl.cert);
+ curlx_unicodefree(cert_path);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+
+ if(fInCert || blob) {
/* Reading a .P12 or .pfx file, like the example at bottom of
- https://social.msdn.microsoft.com/Forums/windowsdesktop/
- en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
+ https://social.msdn.microsoft.com/Forums/windowsdesktop/
+ en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
*/
- void *certdata = NULL;
- long filesize = 0;
CRYPT_DATA_BLOB datablob;
WCHAR* pszPassword;
size_t pwd_len = 0;
int str_w_len = 0;
- int continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
- if(continue_reading)
- filesize = ftell(fInCert);
- if(filesize < 0)
- continue_reading = 0;
- if(continue_reading)
- continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
- if(continue_reading)
- certdata = malloc(((size_t)filesize) + 1);
- if((certdata == NULL) ||
- ((int) fread(certdata, (size_t)filesize, 1, fInCert) != 1))
- continue_reading = 0;
- fclose(fInCert);
- Curl_unicodefree(cert_path);
-
- if(!continue_reading) {
- failf(data, "schannel: Failed to read cert file %s",
+ const char *cert_showfilename_error = blob ?
+ "(memory blob)" : data->set.ssl.cert;
+ curlx_unicodefree(cert_path);
+ if(fInCert) {
+ long cert_tell = 0;
+ bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
+ if(continue_reading)
+ cert_tell = ftell(fInCert);
+ if(cert_tell < 0)
+ continue_reading = FALSE;
+ else
+ certsize = (size_t)cert_tell;
+ if(continue_reading)
+ continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
+ if(continue_reading)
+ certdata = malloc(certsize + 1);
+ if((!certdata) ||
+ ((int) fread(certdata, certsize, 1, fInCert) != 1))
+ continue_reading = FALSE;
+ fclose(fInCert);
+ if(!continue_reading) {
+ failf(data, "schannel: Failed to read cert file %s",
data->set.ssl.cert);
- free(certdata);
- return CURLE_SSL_CERTPROBLEM;
+ free(certdata);
+ return CURLE_SSL_CERTPROBLEM;
+ }
}
/* Convert key-pair data to the in-memory certificate store */
datablob.pbData = (BYTE*)certdata;
- datablob.cbData = (DWORD)filesize;
+ datablob.cbData = (DWORD)certsize;
if(data->set.ssl.key_passwd != NULL)
pwd_len = strlen(data->set.ssl.key_passwd);
pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
- if(pwd_len > 0)
- str_w_len =
- MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- data->set.ssl.key_passwd, (int)pwd_len,
- pszPassword, (int)(pwd_len + 1));
-
- if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
- pszPassword[str_w_len] = 0;
- else
- pszPassword[0] = 0;
-
- cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
- free(pszPassword);
- free(certdata);
+ if(pszPassword) {
+ if(pwd_len > 0)
+ str_w_len = MultiByteToWideChar(CP_UTF8,
+ MB_ERR_INVALID_CHARS,
+ data->set.ssl.key_passwd, (int)pwd_len,
+ pszPassword, (int)(pwd_len + 1));
+
+ if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
+ pszPassword[str_w_len] = 0;
+ else
+ pszPassword[0] = 0;
+
+ cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
+ free(pszPassword);
+ }
+ if(!blob)
+ free(certdata);
if(cert_store == NULL) {
DWORD errorcode = GetLastError();
if(errorcode == ERROR_INVALID_PASSWORD)
failf(data, "schannel: Failed to import cert file %s, "
- "password is bad", data->set.ssl.cert);
+ "password is bad",
+ cert_showfilename_error);
else
failf(data, "schannel: Failed to import cert file %s, "
- "last error is 0x%x", data->set.ssl.cert, errorcode);
+ "last error is 0x%x",
+ cert_showfilename_error, errorcode);
return CURLE_SSL_CERTPROBLEM;
}
client_certs[0] = CertFindCertificateInStore(
- cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
- CERT_FIND_ANY, NULL, NULL);
+ cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+ CERT_FIND_ANY, NULL, NULL);
if(client_certs[0] == NULL) {
failf(data, "schannel: Failed to get certificate from file %s"
", last error is 0x%x",
- data->set.ssl.cert, GetLastError());
+ cert_showfilename_error, GetLastError());
CertCloseStore(cert_store, 0);
return CURLE_SSL_CERTPROBLEM;
}
@@ -700,7 +733,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
"last error is 0x%x",
cert_store_name, cert_store_path, GetLastError());
free(cert_store_path);
- Curl_unicodefree(cert_path);
+ curlx_unicodefree(cert_path);
return CURLE_SSL_CERTPROBLEM;
}
free(cert_store_path);
@@ -714,7 +747,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
cert_thumbprint_data,
&cert_thumbprint.cbData,
NULL, NULL)) {
- Curl_unicodefree(cert_path);
+ curlx_unicodefree(cert_path);
CertCloseStore(cert_store, 0);
return CURLE_SSL_CERTPROBLEM;
}
@@ -723,7 +756,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
CERT_FIND_HASH, &cert_thumbprint, NULL);
- Curl_unicodefree(cert_path);
+ curlx_unicodefree(cert_path);
if(client_certs[0]) {
schannel_cred.cCreds = 1;
@@ -758,7 +791,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
BACKEND->cred->refcount = 1;
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
- */
+ */
sspi_status =
s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
SECPKG_CRED_OUTBOUND, NULL,
@@ -775,15 +808,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
Curl_safefree(BACKEND->cred);
switch(sspi_status) {
- case SEC_E_INSUFFICIENT_MEMORY:
- return CURLE_OUT_OF_MEMORY;
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_SECPKG_NOT_FOUND:
- case SEC_E_NOT_OWNER:
- case SEC_E_UNKNOWN_CREDENTIALS:
- case SEC_E_INTERNAL_ERROR:
- default:
- return CURLE_SSL_CONNECT_ERROR;
+ case SEC_E_INSUFFICIENT_MEMORY:
+ return CURLE_OUT_OF_MEMORY;
+ case SEC_E_NO_CREDENTIALS:
+ case SEC_E_SECPKG_NOT_FOUND:
+ case SEC_E_NOT_OWNER:
+ case SEC_E_UNKNOWN_CREDENTIALS:
+ case SEC_E_INTERNAL_ERROR:
+ default:
+ return CURLE_SSL_CONNECT_ERROR;
}
}
}
@@ -867,7 +900,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_OUT_OF_MEMORY;
}
- host_name = Curl_convert_UTF8_to_tchar(hostname);
+ host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
@@ -884,35 +917,35 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
0, &BACKEND->ctxt->ctxt_handle,
&outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
- Curl_unicodefree(host_name);
+ curlx_unicodefree(host_name);
if(sspi_status != SEC_I_CONTINUE_NEEDED) {
char buffer[STRERROR_LEN];
Curl_safefree(BACKEND->ctxt);
switch(sspi_status) {
- case SEC_E_INSUFFICIENT_MEMORY:
- failf(data, "schannel: initial InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- return CURLE_OUT_OF_MEMORY;
- case SEC_E_WRONG_PRINCIPAL:
- failf(data, "schannel: SNI or certificate check failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- return CURLE_PEER_FAILED_VERIFICATION;
- /*
- case SEC_E_INVALID_HANDLE:
- case SEC_E_INVALID_TOKEN:
- case SEC_E_LOGON_DENIED:
- case SEC_E_TARGET_UNKNOWN:
- case SEC_E_NO_AUTHENTICATING_AUTHORITY:
- case SEC_E_INTERNAL_ERROR:
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_UNSUPPORTED_FUNCTION:
- case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
- */
- default:
- failf(data, "schannel: initial InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- return CURLE_SSL_CONNECT_ERROR;
+ case SEC_E_INSUFFICIENT_MEMORY:
+ failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_OUT_OF_MEMORY;
+ case SEC_E_WRONG_PRINCIPAL:
+ failf(data, "schannel: SNI or certificate check failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_PEER_FAILED_VERIFICATION;
+ /*
+ case SEC_E_INVALID_HANDLE:
+ case SEC_E_INVALID_TOKEN:
+ case SEC_E_LOGON_DENIED:
+ case SEC_E_TARGET_UNKNOWN:
+ case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+ case SEC_E_INTERNAL_ERROR:
+ case SEC_E_NO_CREDENTIALS:
+ case SEC_E_UNSUPPORTED_FUNCTION:
+ case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
+ */
+ default:
+ failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -958,8 +991,12 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
bool doread;
+#ifndef CURL_DISABLE_PROXY
char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+#else
+ char * const hostname = conn->host.name;
+#endif
const char *pubkey_ptr;
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
@@ -1067,18 +1104,18 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
BACKEND->encdata_offset);
- host_name = Curl_convert_UTF8_to_tchar(hostname);
+ host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
- */
+ */
sspi_status = s_pSecFn->InitializeSecurityContext(
&BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
&outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
- Curl_unicodefree(host_name);
+ curlx_unicodefree(host_name);
/* free buffer for received handshake data */
Curl_safefree(inbuf[0].pvBuffer);
@@ -1133,29 +1170,29 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
else {
char buffer[STRERROR_LEN];
switch(sspi_status) {
- case SEC_E_INSUFFICIENT_MEMORY:
- failf(data, "schannel: next InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- return CURLE_OUT_OF_MEMORY;
- case SEC_E_WRONG_PRINCIPAL:
- failf(data, "schannel: SNI or certificate check failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- return CURLE_PEER_FAILED_VERIFICATION;
- /*
- case SEC_E_INVALID_HANDLE:
- case SEC_E_INVALID_TOKEN:
- case SEC_E_LOGON_DENIED:
- case SEC_E_TARGET_UNKNOWN:
- case SEC_E_NO_AUTHENTICATING_AUTHORITY:
- case SEC_E_INTERNAL_ERROR:
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_UNSUPPORTED_FUNCTION:
- case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
- */
- default:
- failf(data, "schannel: next InitializeSecurityContext failed: %s",
- Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- return CURLE_SSL_CONNECT_ERROR;
+ case SEC_E_INSUFFICIENT_MEMORY:
+ failf(data, "schannel: next InitializeSecurityContext failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_OUT_OF_MEMORY;
+ case SEC_E_WRONG_PRINCIPAL:
+ failf(data, "schannel: SNI or certificate check failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_PEER_FAILED_VERIFICATION;
+ /*
+ case SEC_E_INVALID_HANDLE:
+ case SEC_E_INVALID_TOKEN:
+ case SEC_E_LOGON_DENIED:
+ case SEC_E_TARGET_UNKNOWN:
+ case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+ case SEC_E_INTERNAL_ERROR:
+ case SEC_E_NO_CREDENTIALS:
+ case SEC_E_UNSUPPORTED_FUNCTION:
+ case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
+ */
+ default:
+ failf(data, "schannel: next InitializeSecurityContext failed: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -1324,8 +1361,10 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
#ifdef HAS_ALPN
if(BACKEND->use_alpn) {
- sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
- SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
+ sspi_status =
+ s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ SECPKG_ATTR_APPLICATION_PROTOCOL,
+ &alpn_result);
if(sspi_status != SEC_E_OK) {
failf(data, "schannel: failed to retrieve ALPN result");
@@ -1336,21 +1375,21 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
SecApplicationProtocolNegotiationStatus_Success) {
infof(data, "schannel: ALPN, server accepted to use %.*s\n",
- alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
+ alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
#ifdef USE_NGHTTP2
if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN &&
!memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId,
- NGHTTP2_PROTO_VERSION_ID_LEN)) {
+ NGHTTP2_PROTO_VERSION_ID_LEN)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
#endif
- if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH &&
- !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId,
- ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
- }
+ if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH &&
+ !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId,
+ ALPN_HTTP_1_1_LENGTH)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
@@ -1397,8 +1436,10 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
if(data->set.ssl.certinfo) {
int certs_count = 0;
- sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
- SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
+ sspi_status =
+ s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+ &ccert_context);
if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {
failf(data, "schannel: failed to retrieve remote cert context");
@@ -1481,7 +1522,7 @@ schannel_connect_common(struct connectdata *conn, int sockindex,
connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking ? 0 : (time_t)timeout_ms);
+ nonblocking ? 0 : timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
@@ -1630,13 +1671,9 @@ schannel_send(struct connectdata *conn, int sockindex,
/* send entire message or fail */
while(len > (size_t)written) {
- ssize_t this_write;
- timediff_t timeout_ms;
+ ssize_t this_write = 0;
int what;
-
- this_write = 0;
-
- timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
+ timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
if(timeout_ms < 0) {
/* we already got the timeout */
failf(conn->data, "schannel: timed out sending data "
@@ -1645,7 +1682,7 @@ schannel_send(struct connectdata *conn, int sockindex,
written = -1;
break;
}
- if(!timeout_ms)
+ else if(!timeout_ms)
timeout_ms = TIMEDIFF_T_MAX;
what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms);
if(what < 0) {
@@ -1741,8 +1778,8 @@ schannel_recv(struct connectdata *conn, int sockindex,
}
else if(!len) {
/* It's debatable what to return when !len. Regardless we can't return
- immediately because there may be data to decrypt (in the case we want to
- decrypt all encrypted cached data) so handle !len later in cleanup.
+ immediately because there may be data to decrypt (in the case we want to
+ decrypt all encrypted cached data) so handle !len later in cleanup.
*/
; /* do nothing */
}
@@ -1752,7 +1789,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
BACKEND->encdata_length < min_encdata_length) {
reallocated_length = BACKEND->encdata_offset +
- CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ CURL_SCHANNEL_BUFFER_FREE_SIZE;
if(reallocated_length < min_encdata_length) {
reallocated_length = min_encdata_length;
}
@@ -1820,7 +1857,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
InitSecBufferDesc(&inbuf_desc, inbuf, 4);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
- */
+ */
sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
&inbuf_desc, 0, NULL);
@@ -1836,7 +1873,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
/* increase buffer in order to fit the received amount of data */
size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
- inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
BACKEND->decdata_length < len) {
/* increase internal decrypted data buffer */
@@ -1906,7 +1943,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
if(BACKEND->encdata_offset) {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: can't renogotiate, "
- "encrypted data available\n");
+ "encrypted data available\n");
goto cleanup;
}
/* begin renegotiation */
@@ -1961,17 +1998,20 @@ schannel_recv(struct connectdata *conn, int sockindex,
"schannel: decrypted data buffer: offset %zu length %zu\n",
BACKEND->decdata_offset, BACKEND->decdata_length));
-cleanup:
+ cleanup:
/* Warning- there is no guarantee the encdata state is valid at this point */
DEBUGF(infof(data, "schannel: schannel_recv cleanup\n"));
/* Error if the connection has closed without a close_notify.
- Behavior here is a matter of debate. We don't want to be vulnerable to a
- truncation attack however there's some browser precedent for ignoring the
- close_notify for compatibility reasons.
- Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't
- return close_notify. In that case if the connection was closed we assume it
- was graceful (close_notify) since there doesn't seem to be a way to tell.
+
+ The behavior here is a matter of debate. We don't want to be vulnerable
+ to a truncation attack however there's some browser precedent for
+ ignoring the close_notify for compatibility reasons.
+
+ Additionally, Windows 2000 (v5.0) is a special case since it seems it
+ doesn't return close_notify. In that case if the connection was closed we
+ assume it was graceful (close_notify) since there doesn't seem to be a
+ way to tell.
*/
if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
!BACKEND->recv_sspi_close_notify) {
@@ -1988,7 +2028,7 @@ cleanup:
/* Any error other than CURLE_AGAIN is an unrecoverable error. */
if(*err && *err != CURLE_AGAIN)
- BACKEND->recv_unrecoverable_err = *err;
+ BACKEND->recv_unrecoverable_err = *err;
size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
if(size) {
@@ -2005,10 +2045,11 @@ cleanup:
}
if(!*err && !BACKEND->recv_connection_closed)
- *err = CURLE_AGAIN;
+ *err = CURLE_AGAIN;
- /* It's debatable what to return when !len. We could return whatever error we
- got from decryption but instead we override here so the return is consistent.
+ /* It's debatable what to return when !len. We could return whatever error
+ we got from decryption but instead we override here so the return is
+ consistent.
*/
if(!len)
*err = CURLE_OK;
@@ -2074,8 +2115,12 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
*/
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifndef CURL_DISABLE_PROXY
char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+#else
+ char * const hostname = conn->host.name;
+#endif
DEBUGASSERT(data);
@@ -2104,7 +2149,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
}
- host_name = Curl_convert_UTF8_to_tchar(hostname);
+ host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
@@ -2126,7 +2171,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
&BACKEND->ret_flags,
&BACKEND->ctxt->time_stamp);
- Curl_unicodefree(host_name);
+ curlx_unicodefree(host_name);
if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
/* send close message which is in output buffer */
@@ -2235,8 +2280,8 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
SECURITY_STATUS sspi_status;
const char *x509_der;
DWORD x509_der_len;
- curl_X509certificate x509_parsed;
- curl_asn1Element *pubkey;
+ struct Curl_X509certificate x509_parsed;
+ struct Curl_asn1Element *pubkey;
sspi_status =
s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
@@ -2252,7 +2297,7 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
- (pCertContextServer->cbCertEncoded > 0)))
+ (pCertContextServer->cbCertEncoded > 0)))
break;
x509_der = (const char *)pCertContextServer->pbCertEncoded;
@@ -2343,9 +2388,9 @@ static CURLcode Curl_schannel_md5sum(unsigned char *input,
}
static CURLcode Curl_schannel_sha256sum(const unsigned char *input,
- size_t inputlen,
- unsigned char *sha256sum,
- size_t sha256len)
+ size_t inputlen,
+ unsigned char *sha256sum,
+ size_t sha256len)
{
Curl_schannel_checksum(input, inputlen, sha256sum, sha256len,
PROV_RSA_AES, CALG_SHA_256);
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index 3dbc11f056..bdd7199e49 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -57,7 +57,7 @@
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
#define END_CERT "\n-----END CERTIFICATE-----"
-typedef struct {
+struct cert_chain_engine_config_win7 {
DWORD cbSize;
HCERTSTORE hRestrictedRoot;
HCERTSTORE hRestrictedTrust;
@@ -70,7 +70,7 @@ typedef struct {
DWORD CycleDetectionModulus;
HCERTSTORE hExclusiveRoot;
HCERTSTORE hExclusiveTrustedPeople;
-} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7;
+};
static int is_cr_or_lf(char c)
{
@@ -94,7 +94,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
int num_certs = 0;
size_t END_CERT_LEN;
- ca_file_tstr = Curl_convert_UTF8_to_tchar((char *)ca_file);
+ ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file);
if(!ca_file_tstr) {
char buffer[STRERROR_LEN];
failf(data,
@@ -288,7 +288,7 @@ cleanup:
CloseHandle(ca_file_handle);
}
Curl_safefree(ca_file_buffer);
- Curl_unicodefree(ca_file_tstr);
+ curlx_unicodefree(ca_file_tstr);
return result;
}
@@ -361,7 +361,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
return actual_length;
}
- decode_para.cbSize = sizeof(CRYPT_DECODE_PARA);
+ decode_para.cbSize = sizeof(CRYPT_DECODE_PARA);
ret_val =
CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
@@ -476,7 +476,7 @@ static CURLcode verify_host(struct Curl_easy *data,
* is acceptable since both values are assumed to use ASCII
* (or some equivalent) encoding
*/
- cert_hostname = Curl_convert_tchar_to_UTF8(
+ cert_hostname = curlx_convert_tchar_to_UTF8(
&cert_hostname_buff[cert_hostname_buff_index]);
if(!cert_hostname) {
result = CURLE_OUT_OF_MEMORY;
@@ -508,7 +508,7 @@ static CURLcode verify_host(struct Curl_easy *data,
result = CURLE_PEER_FAILED_VERIFICATION;
}
- Curl_unicodefree(cert_hostname);
+ curlx_unicodefree(cert_hostname);
}
}
@@ -522,7 +522,7 @@ static CURLcode verify_host(struct Curl_easy *data,
failf(data, "schannel: server certificate name verification failed");
cleanup:
- Curl_unicodefree(cert_hostname_buff);
+ curlx_unicodefree(cert_hostname_buff);
return result;
}
@@ -537,9 +537,13 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
const CERT_CHAIN_CONTEXT *pChainContext = NULL;
HCERTCHAINENGINE cert_chain_engine = NULL;
HCERTSTORE trust_store = NULL;
+#ifndef CURL_DISABLE_PROXY
const char * const conn_hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name :
conn->host.name;
+#else
+ const char * const conn_hostname = conn->host.name;
+#endif
sspi_status =
s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
@@ -585,7 +589,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
}
if(result == CURLE_OK) {
- CERT_CHAIN_ENGINE_CONFIG_WIN7 engine_config;
+ struct cert_chain_engine_config_win7 engine_config;
BOOL create_engine_result;
memset(&engine_config, 0, sizeof(engine_config));
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index 6b2d436fc0..2627aff16a 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -1126,12 +1126,12 @@ static OSStatus CopyIdentityWithLabel(char *label,
}
static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
+ const struct curl_blob *blob,
const char *cPassword,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
- CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
- (const UInt8 *)cPath, strlen(cPath), false);
+ CFURLRef pkcs_url = NULL;
CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
cPassword, kCFStringEncodingUTF8) : NULL;
CFDataRef pkcs_data = NULL;
@@ -1140,8 +1140,26 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
/* These constants are documented as having first appeared in 10.6 but they
raise linker errors when used on that cat for some reason. */
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
- if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
- NULL, NULL, &status)) {
+ bool resource_imported;
+
+ if(blob) {
+ pkcs_data = CFDataCreate(kCFAllocatorDefault,
+ (const unsigned char *)blob->data, blob->len);
+ status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate;
+ resource_imported = (pkcs_data != NULL);
+ }
+ else {
+ pkcs_url =
+ CFURLCreateFromFileSystemRepresentation(NULL,
+ (const UInt8 *)cPath,
+ strlen(cPath), false);
+ resource_imported =
+ CFURLCreateDataAndPropertiesFromResource(NULL,
+ pkcs_url, &pkcs_data,
+ NULL, NULL, &status);
+ }
+
+ if(resource_imported) {
CFArrayRef items = NULL;
/* On iOS SecPKCS12Import will never add the client certificate to the
@@ -1219,7 +1237,8 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
if(password)
CFRelease(password);
- CFRelease(pkcs_url);
+ if(pkcs_url)
+ CFRelease(pkcs_url);
return status;
}
@@ -1376,8 +1395,10 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+ const struct curl_blob *ssl_cablob = NULL;
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
char * const ssl_cert = SSL_SET_OPTION(cert);
+ const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
@@ -1612,15 +1633,16 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
"Transport. The private key must be in the Keychain.\n");
}
- if(ssl_cert) {
+ if(ssl_cert || ssl_cert_blob) {
+ bool is_cert_data = ssl_cert_blob != NULL;
+ bool is_cert_file = (!is_cert_data) && is_file(ssl_cert);
SecIdentityRef cert_and_key = NULL;
- bool is_cert_file = is_file(ssl_cert);
/* User wants to authenticate with a client cert. Look for it:
If we detect that this is a file on disk, then let's load it.
Otherwise, assume that the user wants to use an identity loaded
from the Keychain. */
- if(is_cert_file) {
+ if(is_cert_file || is_cert_data) {
if(!SSL_SET_OPTION(cert_type))
infof(data, "WARNING: SSL: Certificate type not set, assuming "
"PKCS#12 format.\n");
@@ -1629,7 +1651,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
infof(data, "WARNING: SSL: The Security framework only supports "
"loading identities that are in PKCS#12 format.\n");
- err = CopyIdentityFromPKCS12File(ssl_cert,
+ err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
SSL_SET_OPTION(key_passwd), &cert_and_key);
}
else
@@ -1669,27 +1691,30 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
CFRelease(cert_and_key);
}
else {
+ const char *cert_showfilename_error =
+ is_cert_data ? "(memory blob)" : ssl_cert;
+
switch(err) {
case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
failf(data, "SSL: Incorrect password for the certificate \"%s\" "
- "and its private key.", ssl_cert);
+ "and its private key.", cert_showfilename_error);
break;
case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
failf(data, "SSL: Couldn't make sense of the data in the "
"certificate \"%s\" and its private key.",
- ssl_cert);
+ cert_showfilename_error);
break;
case -25260: /* errSecPassphraseRequired */
failf(data, "SSL The certificate \"%s\" requires a password.",
- ssl_cert);
+ cert_showfilename_error);
break;
case errSecItemNotFound:
failf(data, "SSL: Can't find the certificate \"%s\" and its private "
- "key in the Keychain.", ssl_cert);
+ "key in the Keychain.", cert_showfilename_error);
break;
default:
failf(data, "SSL: Can't load the certificate \"%s\" and its private "
- "key: OSStatus %d", ssl_cert, err);
+ "key: OSStatus %d", cert_showfilename_error, err);
break;
}
return CURLE_SSL_CERTPROBLEM;
@@ -1721,7 +1746,8 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
#else
if(SSLSetSessionOption != NULL) {
#endif /* CURL_BUILD_MAC */
- bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
+ bool break_on_auth = !conn->ssl_config.verifypeer ||
+ ssl_cafile || ssl_cablob;
err = SSLSetSessionOption(backend->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
break_on_auth);
@@ -1749,10 +1775,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
}
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
- if(ssl_cafile && verifypeer) {
- bool is_cert_file = is_file(ssl_cafile);
+ if((ssl_cafile || ssl_cablob) && verifypeer) {
+ bool is_cert_data = ssl_cablob != NULL;
+ bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile);
- if(!is_cert_file) {
+ if(!(is_cert_file || is_cert_data)) {
failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
return CURLE_SSL_CACERT_BADFILE;
}
@@ -2809,7 +2836,6 @@ sectransp_connect_common(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
- timediff_t timeout_ms;
int what;
/* check if the connection has already been established */
@@ -2820,7 +2846,7 @@ sectransp_connect_common(struct connectdata *conn,
if(ssl_connect_1 == connssl->connecting_state) {
/* Find out how much more time we're allowed */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
@@ -2838,7 +2864,7 @@ sectransp_connect_common(struct connectdata *conn,
ssl_connect_2_writing == connssl->connecting_state) {
/* check allowed time left */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
@@ -2856,7 +2882,7 @@ sectransp_connect_common(struct connectdata *conn,
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking?0:(time_t)timeout_ms);
+ nonblocking ? 0 : timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c
index f1b5252273..dfe2601393 100644
--- a/libs/libcurl/src/vtls/vtls.c
+++ b/libs/libcurl/src/vtls/vtls.c
@@ -83,8 +83,8 @@
dest->var = NULL;
bool
-Curl_ssl_config_matches(struct ssl_primary_config* data,
- struct ssl_primary_config* needle)
+Curl_ssl_config_matches(struct ssl_primary_config *data,
+ struct ssl_primary_config *needle)
{
if((data->version == needle->version) &&
(data->version_max == needle->version_max) &&
@@ -127,7 +127,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
return TRUE;
}
-void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
+void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
{
Curl_safefree(sslc->CApath);
Curl_safefree(sslc->CAfile);
@@ -215,6 +215,7 @@ static bool ssl_prefs_check(struct Curl_easy *data)
return TRUE;
}
+#ifndef CURL_DISABLE_PROXY
static CURLcode
ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
{
@@ -238,17 +239,20 @@ ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
}
return CURLE_OK;
}
+#endif
CURLcode
Curl_ssl_connect(struct connectdata *conn, int sockindex)
{
CURLcode result;
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy_ssl_connected[sockindex]) {
result = ssl_connect_init_proxy(conn, sockindex);
if(result)
return result;
}
+#endif
if(!ssl_prefs_check(conn->data))
return CURLE_SSL_CONNECT_ERROR;
@@ -270,12 +274,13 @@ Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
bool *done)
{
CURLcode result;
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.proxy_ssl_connected[sockindex]) {
result = ssl_connect_init_proxy(conn, sockindex);
if(result)
return result;
}
-
+#endif
if(!ssl_prefs_check(conn->data))
return CURLE_SSL_CONNECT_ERROR;
@@ -321,13 +326,21 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
long *general_age;
bool no_match = TRUE;
+#ifndef CURL_DISABLE_PROXY
const bool isProxy = CONNECT_PROXY_SSL();
struct ssl_primary_config * const ssl_config = isProxy ?
&conn->proxy_ssl_config :
&conn->ssl_config;
- const char * const name = isProxy ? conn->http_proxy.host.name :
- conn->host.name;
+ const char * const name = isProxy ?
+ conn->http_proxy.host.name : conn->host.name;
int port = isProxy ? (int)conn->port : conn->remote_port;
+#else
+ /* no proxy support */
+ struct ssl_primary_config * const ssl_config = &conn->ssl_config;
+ const char * const name = conn->host.name;
+ int port = conn->remote_port;
+ (void)sockindex;
+#endif
*ssl_sessionid = NULL;
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
@@ -429,14 +442,23 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
char *clone_conn_to_host;
int conn_to_port;
long *general_age;
+#ifndef CURL_DISABLE_PROXY
const bool isProxy = CONNECT_PROXY_SSL();
struct ssl_primary_config * const ssl_config = isProxy ?
&conn->proxy_ssl_config :
&conn->ssl_config;
-
+ const char *hostname = isProxy ? conn->http_proxy.host.name :
+ conn->host.name;
+#else
+ /* proxy support disabled */
+ const bool isProxy = FALSE;
+ struct ssl_primary_config * const ssl_config = &conn->ssl_config;
+ const char *hostname = conn->host.name;
+ (void)sockindex;
+#endif
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
- clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
+ clone_host = strdup(hostname);
if(!clone_host)
return CURLE_OUT_OF_MEMORY; /* bail out */
@@ -1084,7 +1106,7 @@ bool Curl_none_false_start(void)
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
unsigned char *md5sum, size_t md5len UNUSED_PARAM)
{
- MD5_context *MD5pw;
+ struct MD5_context *MD5pw;
(void)md5len;
diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h
index a81b2f22d1..bcc8444161 100644
--- a/libs/libcurl/src/vtls/vtls.h
+++ b/libs/libcurl/src/vtls/vtls.h
@@ -113,12 +113,6 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
#endif
-#ifndef MD5_DIGEST_LENGTH
-#ifndef LIBWOLFSSL_VERSION_HEX /* because WolfSSL borks this */
-#define MD5_DIGEST_LENGTH 16 /* fixed size */
-#endif
-#endif
-
#ifndef CURL_SHA256_DIGEST_LENGTH
#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
#endif
@@ -129,20 +123,27 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
/* set of helper macros for the backends to access the correct fields. For the
proxy or for the remote host - to properly support HTTPS proxy */
+#ifndef CURL_DISABLE_PROXY
+#define SSL_IS_PROXY() \
+ (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
+ ssl_connection_complete != \
+ conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
+ CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
+#define SSL_SET_OPTION(var) \
+ (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var)
+#define SSL_CONN_CONFIG(var) \
+ (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var)
+#else
+#define SSL_IS_PROXY() FALSE
+#define SSL_SET_OPTION(var) data->set.ssl.var
+#define SSL_CONN_CONFIG(var) conn->ssl_config.var
+#endif
-#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
- ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
- CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
-#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \
- data->set.ssl.var)
-#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ? \
- conn->proxy_ssl_config.var : conn->ssl_config.var)
-
-bool Curl_ssl_config_matches(struct ssl_primary_config* data,
- struct ssl_primary_config* needle);
+bool Curl_ssl_config_matches(struct ssl_primary_config *data,
+ struct ssl_primary_config *needle);
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
struct ssl_primary_config *dest);
-void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc);
+void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc);
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
int Curl_ssl_backend(void);
diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c
index 5040b05929..7b2a124e4f 100644
--- a/libs/libcurl/src/vtls/wolfssl.c
+++ b/libs/libcurl/src/vtls/wolfssl.c
@@ -63,6 +63,7 @@
#include "sendf.h"
#include "inet_pton.h"
#include "vtls.h"
+#include "keylog.h"
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
@@ -99,6 +100,107 @@ struct ssl_backend_data {
static Curl_recv wolfssl_recv;
static Curl_send wolfssl_send;
+#ifdef OPENSSL_EXTRA
+/*
+ * Availability note:
+ * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in
+ * WolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that
+ * option is not set, then TLS 1.3 will not be logged.
+ * For TLS 1.2 and before, we use wolfSSL_get_keys().
+ * SSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA
+ * (--enable-opensslextra or --enable-all).
+ */
+#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
+static int
+wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret,
+ int secretSz, void *ctx)
+{
+ const char *label;
+ unsigned char client_random[SSL3_RANDOM_SIZE];
+ (void)ctx;
+
+ if(!ssl || !Curl_tls_keylog_enabled()) {
+ return 0;
+ }
+
+ switch(id) {
+ case CLIENT_EARLY_TRAFFIC_SECRET:
+ label = "CLIENT_EARLY_TRAFFIC_SECRET";
+ break;
+ case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
+ label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
+ break;
+ case SERVER_HANDSHAKE_TRAFFIC_SECRET:
+ label = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
+ break;
+ case CLIENT_TRAFFIC_SECRET:
+ label = "CLIENT_TRAFFIC_SECRET_0";
+ break;
+ case SERVER_TRAFFIC_SECRET:
+ label = "SERVER_TRAFFIC_SECRET_0";
+ break;
+ case EARLY_EXPORTER_SECRET:
+ label = "EARLY_EXPORTER_SECRET";
+ break;
+ case EXPORTER_SECRET:
+ label = "EXPORTER_SECRET";
+ break;
+ default:
+ return 0;
+ }
+
+ if(SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) {
+ /* Should never happen as wolfSSL_KeepArrays() was called before. */
+ return 0;
+ }
+
+ Curl_tls_keylog_write(label, client_random, secret, secretSz);
+ return 0;
+}
+#endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */
+
+static void
+wolfssl_log_tls12_secret(SSL *ssl)
+{
+ unsigned char *ms, *sr, *cr;
+ unsigned int msLen, srLen, crLen, i, x = 0;
+
+#if LIBWOLFSSL_VERSION_HEX >= 0x0300d000 /* >= 3.13.0 */
+ /* wolfSSL_GetVersion is available since 3.13, we use it instead of
+ * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or
+ * --enable-all). Failing to perform this check could result in an unusable
+ * key log line when TLS 1.3 is actually negotiated. */
+ switch(wolfSSL_GetVersion(ssl)) {
+ case WOLFSSL_SSLV3:
+ case WOLFSSL_TLSV1:
+ case WOLFSSL_TLSV1_1:
+ case WOLFSSL_TLSV1_2:
+ break;
+ default:
+ /* TLS 1.3 does not use this mechanism, the "master secret" returned below
+ * is not directly usable. */
+ return;
+ }
+#endif
+
+ if(SSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) != SSL_SUCCESS) {
+ return;
+ }
+
+ /* Check for a missing master secret and skip logging. That can happen if
+ * curl rejects the server certificate and aborts the handshake.
+ */
+ for(i = 0; i < msLen; i++) {
+ x |= ms[i];
+ }
+ if(x == 0) {
+ return;
+ }
+
+ Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen);
+}
+#endif /* OPENSSL_EXTRA */
+
static int do_file_type(const char *type)
{
if(!type || !type[0])
@@ -120,7 +222,7 @@ wolfssl_connect_step1(struct connectdata *conn,
{
char *ciphers;
struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
SSL_METHOD* req_method = NULL;
curl_socket_t sockfd = conn->sock[sockindex];
@@ -314,8 +416,12 @@ wolfssl_connect_step1(struct connectdata *conn,
#ifdef ENABLE_IPV6
struct in6_addr addr6;
#endif
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+#else
+ const char * const hostname = conn->host.name;
+#endif
size_t hostname_len = strlen(hostname);
if((hostname_len < USHRT_MAX) &&
(0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
@@ -385,6 +491,17 @@ wolfssl_connect_step1(struct connectdata *conn,
}
#endif /* HAVE_ALPN */
+#ifdef OPENSSL_EXTRA
+ if(Curl_tls_keylog_enabled()) {
+ /* Ensure the Client Random is preserved. */
+ wolfSSL_KeepArrays(backend->handle);
+#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
+ wolfSSL_set_tls13_secret_cb(backend->handle,
+ wolfssl_tls13_secret_callback, NULL);
+#endif
+ }
+#endif /* OPENSSL_EXTRA */
+
/* Check if there's a cached ID we can/should use here! */
if(SSL_SET_OPTION(primary.sessionid)) {
void *ssl_sessionid = NULL;
@@ -423,15 +540,22 @@ wolfssl_connect_step2(struct connectdata *conn,
{
int ret = -1;
struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const char * const dispname = SSL_IS_PROXY() ?
conn->http_proxy.host.dispname : conn->host.dispname;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+#else
+ const char * const hostname = conn->host.name;
+ const char * const dispname = conn->host.dispname;
+ const char * const pinnedpubkey =
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+#endif
conn->recv[sockindex] = wolfssl_recv;
conn->send[sockindex] = wolfssl_send;
@@ -444,6 +568,31 @@ wolfssl_connect_step2(struct connectdata *conn,
}
ret = SSL_connect(backend->handle);
+
+#ifdef OPENSSL_EXTRA
+ if(Curl_tls_keylog_enabled()) {
+ /* If key logging is enabled, wait for the handshake to complete and then
+ * proceed with logging secrets (for TLS 1.2 or older).
+ *
+ * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits
+ * for the server response. At that point the master secret is not yet
+ * available, so we must not try to read it.
+ * To log the secret on completion with a handshake failure, detect
+ * completion via the observation that there is nothing to read or write.
+ * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever
+ * changes, the worst case is that no key is logged on error.
+ */
+ if(ret == SSL_SUCCESS ||
+ (!wolfSSL_want_read(backend->handle) &&
+ !wolfSSL_want_write(backend->handle))) {
+ wolfssl_log_tls12_secret(backend->handle);
+ /* Client Random and master secrets are no longer needed, erase these.
+ * Ignored while the handshake is still in progress. */
+ wolfSSL_FreeArrays(backend->handle);
+ }
+ }
+#endif /* OPENSSL_EXTRA */
+
if(ret != 1) {
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int detail = SSL_get_error(backend->handle, ret);
@@ -511,8 +660,8 @@ wolfssl_connect_step2(struct connectdata *conn,
X509 *x509;
const char *x509_der;
int x509_der_len;
- curl_X509certificate x509_parsed;
- curl_asn1Element *pubkey;
+ struct Curl_X509certificate x509_parsed;
+ struct Curl_asn1Element *pubkey;
CURLcode result;
x509 = SSL_get_peer_certificate(backend->handle);
@@ -750,6 +899,9 @@ static size_t Curl_wolfssl_version(char *buffer, size_t size)
static int Curl_wolfssl_init(void)
{
+#ifdef OPENSSL_EXTRA
+ Curl_tls_keylog_open();
+#endif
return (wolfSSL_Init() == SSL_SUCCESS);
}
@@ -757,10 +909,13 @@ static int Curl_wolfssl_init(void)
static void Curl_wolfssl_cleanup(void)
{
wolfSSL_Cleanup();
+#ifdef OPENSSL_EXTRA
+ Curl_tls_keylog_close();
+#endif
}
-static bool Curl_wolfssl_data_pending(const struct connectdata* conn,
+static bool Curl_wolfssl_data_pending(const struct connectdata *conn,
int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
@@ -800,7 +955,6 @@ wolfssl_connect_common(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
- time_t timeout_ms;
int what;
/* check if the connection has already been established */
@@ -811,7 +965,7 @@ wolfssl_connect_common(struct connectdata *conn,
if(ssl_connect_1 == connssl->connecting_state) {
/* Find out how much more time we're allowed */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
@@ -829,7 +983,7 @@ wolfssl_connect_common(struct connectdata *conn,
ssl_connect_2_writing == connssl->connecting_state) {
/* check allowed time left */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
diff --git a/libs/libcurl/src/x509asn1.c b/libs/libcurl/src/x509asn1.c
index ece5364d8a..52747d57df 100644
--- a/libs/libcurl/src/x509asn1.c
+++ b/libs/libcurl/src/x509asn1.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -44,7 +44,7 @@
static const char cnOID[] = "2.5.4.3"; /* Common name. */
static const char sanOID[] = "2.5.29.17"; /* Subject alternative name. */
-static const curl_OID OIDtable[] = {
+static const struct Curl_OID OIDtable[] = {
{ "1.2.840.10040.4.1", "dsa" },
{ "1.2.840.10040.4.3", "dsa-with-sha1" },
{ "1.2.840.10045.2.1", "ecPublicKey" },
@@ -103,16 +103,16 @@ static const curl_OID OIDtable[] = {
* Please note there is no pretention here to rewrite a full SSL library.
*/
-static const char *getASN1Element(curl_asn1Element *elem,
+static const char *getASN1Element(struct Curl_asn1Element *elem,
const char *beg, const char *end)
WARN_UNUSED_RESULT;
-static const char *getASN1Element(curl_asn1Element *elem,
+static const char *getASN1Element(struct Curl_asn1Element *elem,
const char *beg, const char *end)
{
unsigned char b;
unsigned long len;
- curl_asn1Element lelem;
+ struct Curl_asn1Element lelem;
/* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg'
ending at `end'.
@@ -176,9 +176,9 @@ static const char *getASN1Element(curl_asn1Element *elem,
* Search the null terminated OID or OID identifier in local table.
* Return the table entry pointer or NULL if not found.
*/
-static const curl_OID * searchOID(const char *oid)
+static const struct Curl_OID *searchOID(const char *oid)
{
- const curl_OID *op;
+ const struct Curl_OID *op;
for(op = OIDtable; op->numoid; op++)
if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
return op;
@@ -445,7 +445,7 @@ static const char *OID2str(const char *beg, const char *end, bool symbolic)
buf[buflen] = '\0';
if(symbolic) {
- const curl_OID *op = searchOID(buf);
+ const struct Curl_OID *op = searchOID(buf);
if(op) {
free(buf);
buf = strdup(op->textoid);
@@ -565,7 +565,7 @@ static const char *UTime2str(const char *beg, const char *end)
* Convert an ASN.1 element to a printable string.
* Return the dynamically allocated string, or NULL if an error occurs.
*/
-static const char *ASN1tostr(curl_asn1Element *elem, int type)
+static const char *ASN1tostr(struct Curl_asn1Element *elem, int type)
{
if(elem->constructed)
return NULL; /* No conversion of structured elements. */
@@ -609,12 +609,12 @@ static const char *ASN1tostr(curl_asn1Element *elem, int type)
* ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
* `buf'. Return the total string length, even if larger than `buflen'.
*/
-static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn)
+static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn)
{
- curl_asn1Element rdn;
- curl_asn1Element atv;
- curl_asn1Element oid;
- curl_asn1Element value;
+ struct Curl_asn1Element rdn;
+ struct Curl_asn1Element atv;
+ struct Curl_asn1Element oid;
+ struct Curl_asn1Element value;
size_t l = 0;
const char *p1;
const char *p2;
@@ -683,7 +683,7 @@ static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn)
* Convert an ASN.1 distinguished name into a printable string.
* Return the dynamically allocated string, or NULL if an error occurs.
*/
-static const char *DNtostr(curl_asn1Element *dn)
+static const char *DNtostr(struct Curl_asn1Element *dn)
{
char *buf = NULL;
ssize_t buflen = encodeDN(NULL, 0, dn);
@@ -703,11 +703,11 @@ static const char *DNtostr(curl_asn1Element *dn)
* Syntax is assumed to have already been checked by the SSL backend.
* See RFC 5280.
*/
-int Curl_parseX509(curl_X509certificate *cert,
+int Curl_parseX509(struct Curl_X509certificate *cert,
const char *beg, const char *end)
{
- curl_asn1Element elem;
- curl_asn1Element tbsCertificate;
+ struct Curl_asn1Element elem;
+ struct Curl_asn1Element tbsCertificate;
const char *ccp;
static const char defaultVersion = 0; /* v1. */
@@ -835,10 +835,10 @@ static size_t copySubstring(char *to, const char *from)
return i;
}
-static const char *dumpAlgo(curl_asn1Element *param,
+static const char *dumpAlgo(struct Curl_asn1Element *param,
const char *beg, const char *end)
{
- curl_asn1Element oid;
+ struct Curl_asn1Element oid;
/* Get algorithm parameters and return algorithm name. */
@@ -855,7 +855,7 @@ static const char *dumpAlgo(curl_asn1Element *param,
}
static void do_pubkey_field(struct Curl_easy *data, int certnum,
- const char *label, curl_asn1Element *elem)
+ const char *label, struct Curl_asn1Element *elem)
{
const char *output;
@@ -872,11 +872,11 @@ static void do_pubkey_field(struct Curl_easy *data, int certnum,
}
static void do_pubkey(struct Curl_easy *data, int certnum,
- const char *algo, curl_asn1Element *param,
- curl_asn1Element *pubkey)
+ const char *algo, struct Curl_asn1Element *param,
+ struct Curl_asn1Element *pubkey)
{
- curl_asn1Element elem;
- curl_asn1Element pk;
+ struct Curl_asn1Element elem;
+ struct Curl_asn1Element pk;
const char *p;
/* Generate all information records for the public key. */
@@ -950,9 +950,9 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
const char *beg,
const char *end)
{
- curl_X509certificate cert;
+ struct Curl_X509certificate cert;
struct Curl_easy *data = conn->data;
- curl_asn1Element param;
+ struct Curl_asn1Element param;
const char *ccp;
char *cp1;
size_t cl1;
@@ -1111,7 +1111,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
static const char *checkOID(const char *beg, const char *end,
const char *oid)
{
- curl_asn1Element e;
+ struct Curl_asn1Element e;
const char *ccp;
const char *p;
bool matched;
@@ -1136,22 +1136,21 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
const char *beg, const char *end)
{
struct Curl_easy *data = conn->data;
- curl_X509certificate cert;
- curl_asn1Element dn;
- curl_asn1Element elem;
- curl_asn1Element ext;
- curl_asn1Element name;
+ struct Curl_X509certificate cert;
+ struct Curl_asn1Element dn;
+ struct Curl_asn1Element elem;
+ struct Curl_asn1Element ext;
+ struct Curl_asn1Element name;
const char *p;
const char *q;
char *dnsname;
int matched = -1;
size_t addrlen = (size_t) -1;
ssize_t len;
- const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
- conn->host.name;
- const char * const dispname = SSL_IS_PROXY()?
- conn->http_proxy.host.dispname:
- conn->host.dispname;
+ const char *const hostname = SSL_IS_PROXY()?
+ conn->http_proxy.host.name : conn->host.name;
+ const char *const dispname = SSL_IS_PROXY()?
+ conn->http_proxy.host.dispname : conn->host.dispname;
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
diff --git a/libs/libcurl/src/x509asn1.h b/libs/libcurl/src/x509asn1.h
index 205fdc0d71..0b7fb88170 100644
--- a/libs/libcurl/src/x509asn1.h
+++ b/libs/libcurl/src/x509asn1.h
@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, 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
@@ -79,52 +79,51 @@
*/
/* ASN.1 parsed element. */
-typedef struct {
- const char * header; /* Pointer to header byte. */
- const char * beg; /* Pointer to element data. */
- const char * end; /* Pointer to 1st byte after element. */
- unsigned char class; /* ASN.1 element class. */
- unsigned char tag; /* ASN.1 element tag. */
- bool constructed; /* Element is constructed. */
-} curl_asn1Element;
+struct Curl_asn1Element {
+ const char *header; /* Pointer to header byte. */
+ const char *beg; /* Pointer to element data. */
+ const char *end; /* Pointer to 1st byte after element. */
+ unsigned char class; /* ASN.1 element class. */
+ unsigned char tag; /* ASN.1 element tag. */
+ bool constructed; /* Element is constructed. */
+};
/* ASN.1 OID table entry. */
-typedef struct {
- const char * numoid; /* Dotted-numeric OID. */
- const char * textoid; /* OID name. */
-} curl_OID;
+struct Curl_OID {
+ const char *numoid; /* Dotted-numeric OID. */
+ const char *textoid; /* OID name. */
+};
/* X509 certificate: RFC 5280. */
-typedef struct {
- curl_asn1Element certificate;
- curl_asn1Element version;
- curl_asn1Element serialNumber;
- curl_asn1Element signatureAlgorithm;
- curl_asn1Element signature;
- curl_asn1Element issuer;
- curl_asn1Element notBefore;
- curl_asn1Element notAfter;
- curl_asn1Element subject;
- curl_asn1Element subjectPublicKeyInfo;
- curl_asn1Element subjectPublicKeyAlgorithm;
- curl_asn1Element subjectPublicKey;
- curl_asn1Element issuerUniqueID;
- curl_asn1Element subjectUniqueID;
- curl_asn1Element extensions;
-} curl_X509certificate;
-
+struct Curl_X509certificate {
+ struct Curl_asn1Element certificate;
+ struct Curl_asn1Element version;
+ struct Curl_asn1Element serialNumber;
+ struct Curl_asn1Element signatureAlgorithm;
+ struct Curl_asn1Element signature;
+ struct Curl_asn1Element issuer;
+ struct Curl_asn1Element notBefore;
+ struct Curl_asn1Element notAfter;
+ struct Curl_asn1Element subject;
+ struct Curl_asn1Element subjectPublicKeyInfo;
+ struct Curl_asn1Element subjectPublicKeyAlgorithm;
+ struct Curl_asn1Element subjectPublicKey;
+ struct Curl_asn1Element issuerUniqueID;
+ struct Curl_asn1Element subjectUniqueID;
+ struct Curl_asn1Element extensions;
+};
/*
* Prototypes.
*/
-const char *Curl_getASN1Element(curl_asn1Element *elem,
- const char *beg, const char *end);
-const char *Curl_ASN1tostr(curl_asn1Element *elem, int type);
-const char *Curl_DNtostr(curl_asn1Element *dn);
-int Curl_parseX509(curl_X509certificate *cert,
+const char *Curl_getASN1Element(struct Curl_asn1Element *elem,
+ const char *beg, const char *end);
+const char *Curl_ASN1tostr(struct Curl_asn1Element *elem, int type);
+const char *Curl_DNtostr(struct Curl_asn1Element *dn);
+int Curl_parseX509(struct Curl_X509certificate *cert,
const char *beg, const char *end);
CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum,
const char *beg, const char *end);