gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] branch master updated (70745a841 -> 486ada36f)


From: gnunet
Subject: [gnurl] branch master updated (70745a841 -> 486ada36f)
Date: Fri, 20 Dec 2019 14:25:09 +0100

This is an automated email from the git hooks/post-receive script.

ng0 pushed a change to branch master
in repository gnurl.

    from 70745a841 cmake, gnutls.
     new bc1cd39a1 configure: avoid unportable `==' test(1) operator
     new 93738efe1 build: fix for CURL_DISABLE_DOH
     new 93213b242 ntlm: USE_WIN32_CRYPTO check removed to get USE_NTLM2SESSION 
set
     new feea3c27c configure: fix typo in help text
     new 58f7ec163 scripts/contributors: make committers get included too
     new 7ef4e2e90 mailmap: fixup Massimiliano Fantuzzi
     new 8220dab4d curlver: bump to 7.67.1
     new 3820c8d81 RELEASE-NOTES: synced
     new 0bc60d91d copyrights: fix copyright year range
     new 1f73138ce checksrc: repair the copyrightyear check
     new 5d5bd4460 test1560: require IPv6 for IPv6 aware URL parsing
     new 1464abf7e TODO: 1.4 alt-svc sharing
     new d04ee4c82 TODO: Run web-platform-tests url tests
     new cba52e2c2 TODO: curl_multi_unblock
     new 8063c3220 system.h: fix for MCST lcc compiler
     new 07cf042ec strerror: Fix an error looking up some Windows error strings
     new 32747aafa pause: avoid updating socket if done was already called
     new 86e26996c test1558: use double slash after file:
     new 13182b33f remove_handle: clear expire timers after multi_done()
     new cbaaae44f CURL-DISABLE: initial docs for the CURL_DISABLE_* defines
     new 8686aab69 openssl: prevent recursive function calls from ctx callbacks
     new b3eb7d172 quiche: reject headers in the wrong order
     new 674298d19 HISTORY: added cmake, HTTP/3 and parallel downloads with curl
     new 7a46aeb0b curl: fix -T globbing
     new 4e1eee150 multi_poll: avoid busy-loop when called without easy handles 
attached
     new ea19dbe66 examples: add multi-poll.c
     new c6b70de24 config-win32: cpu-machine-OS for Windows on ARM
     new 7627a2dd9 ngtcp2: increase QUIC window size when data is consumed
     new b6a53fff6 doh: improced both encoding and decoding
     new 0a906a45a INSTALL.md: provide Android build instructions
     new 1f6a18685 lib: Move lib/ssh.h -> lib/vssh/ssh.h
     new d1476aa11 multi: Fix curl_multi_poll wait when extra_fds && !extra_nfds
     new a72b6b960 ngtcp2: handle key updates as ngtcp2 master branch tells us
     new 82e4d029c ngtcp2: free used resources on disconnect
     new 425c572a1 altsvc: bump to h3-24
     new e0363a47d ngtcp2: use overflow buffer for extra HTTP/3 data
     new 58bdf056a RELEASE-NOTES: synced
     new 821171dbf projects: Fix Visual Studio wolfSSL configurations
     new 8487734e8 docs: fix typos
     new 215baa74f curl: add --parallel-immediate
     new e1f66ee3b bump: next release will be 7.68.0
     new f70da9c17 include: make CURLE_HTTP3 use a new error code
     new 74f441c6d test1175: verify symbols-in-versions and libcurl-errors.3 in 
sync
     new 1f4e7dc66 openssl: improve error message for SYSCALL during connect
     new 78cef0684 openssl: Revert to less sensitivity for SYSCALL errors
     new 036ebac01 RELEASE-NOTES: synced
     new ee5c68a96 projects: Fix Visual Studio projects SSH builds
     new 8d2dac7de checksrc.bat: Add a check for vquic and vssh directories
     new 0a65febcc schannel: fix --tls-max for when min is --tlsv1 or default
     new f3c35e371 multi: add curl_multi_wakeup()
     new 95e94c64f curl_multi_wakeup.3: add example and AVAILABILITY
     new 9b879160d TLS: add BearSSL vtls implementation
     new 7cf18b05e XFERINFOFUNCTION: support CURL_PROGRESSFUNC_CONTINUE
     new 9a2cbf30b curl: fix --upload-file . hangs if delay in STDIN
     new 793e37767 dist: add error-codes.pl
     new 113db127e travis: export the CC/CXX variables when set
     new d94aa3941 ngtcp2: fix thread-safety bug in error-handling
     new c393b66df travis: build ngtcp2 with --enable-lib-only
     new 8acfad38c doh: use dedicated probe slots
     new 763decc52 mailmap: Niall O'Reilly's name
     new 1ff63fa69 docs: fix typos
     new 18e5cb77e curl: two new command line options for etags
     new a956a8c5b RELEASE-NOTES: synced
     new ba82673da checksrc: fix regexp for ASSIGNWITHINCONDITION
     new bb8cf0516 http_ntlm: Remove duplicate NSS initialisation
     new 66e21520f curl_setup_once: consistently use WHILE_FALSE in macros
     new cc4cf93e5 sha256: bump the copyright year range
     new bc64377ff docs: add more references to curl_multi_poll
     new 0044443a0 parsedate: offer a getdate_capped() alternative
     new bc5d22c3d global_init: undo the "intialized" bump in case of failure
     new 5b22e1a5a strerror: Add Curl_winapi_strerror for Win API specific 
errors
     new 0436d4438 openssl: retrieve reported LibreSSL version at runtime
     new 9c1806ae4 build: Disable Visual Studio warning "conditional expression 
is constant"
     new d9118e8d7 copyright: fix the year ranges for two files
     new d4a186271 docs: add "added: 7.68.0" to the --etag-* docs
     new 6983898b2 Azure Pipelines: initial CI setup
     new 5d576afc5 azure-pipelines: fix the test script
     new 48da3ac67 travis: do not use OVERRIDE_CC or OVERRIDE_CXX if empty
     new 0092b6bf8 OPENSOCKETFUNCTION.3: correct the purpose description
     new 7dffc2b46 curl: show better error message when no homedir is found
     new 94f1f7715 openssl: set X509_V_FLAG_PARTIAL_CHAIN
     new 564d88a8b openssl: CURLSSLOPT_NO_PARTIALCHAIN can disable partial cert 
chains
     new ab712afa8 github action/azure pipeline: run 'make test-nonflaky' for 
tests
     new 67a08dca2 curl_setup: disable IPv6 resolver without `getaddrinfo`
     new 226bf2170 configure: enable IPv6 support without `getaddrinfo`
     new 854343fc4 hostip4.c: bump copyright year range
     new 2ebce6b06 CURLOPT_VERBOSE.3: see also ERRORBUFFER
     new 3b8bbbbd1 azure: add more builds
     new 87b9337c8 CMake: add support for building with the NSS vtls backend
     new 914975fe6 test342: make it return a 304 as the tag matches
     new bf24e0f92 curl_setup: fix `CURLRES_IPV6` condition
     new 9ea769e15 etag: allow both --etag-compare and --etag-save in same 
cmdline
     new 0edf75865 setopt: Fix ALPN / NPN user option when built without HTTP2
     new 689443bf4 lib: fix some loose ends for recently added 
CURLSSLOPT_NO_PARTIALCHAIN
     new 5dc1618fd RELEASE-NOTES: synced
     new 1a46d7c97 docs: fix some typos
     new b62038bfa mailmap: Mohammad Hasbini
     new 147fa0689 curl: make the etag load logic work without fseek
     new 9e891ff54 azure: add a vanilla macos build
     new ee263de7a conncache: fix multi-thread use of shared connection cache
     new 35c7aac3c cirrus: enable clang sanitizers on freebsd 13
     new c7bc689fc conn: always set bits.close with connclose()
     new 476a83209 winbuild: Define CARES_STATICLIB when WITH_CARES=static
     new 0783f2e58 tests: use \r\n for log messages in WSL
     new 213c5aca7 tests: fix permissions of ssh keys in WSL
     new 9819984fb tests: make it possible to set executable extensions
     new c6deecd7e curl: use errorf() better
     new 275e02bde azure: add libssh2 and cmake macos builds
     new 83c0e9605 travis: remove "coverage", make it "torture"
     new de68a7016 RELEASE-NOTES: synced
     new 2c0362ee0 vtls: make BearSSL possible to set with CURL_SSL_BACKEND
     new 1d5c427d7 conncache: CONNECT_ONLY connections assumed always in-use
     new 7c1bd0357 runtests: introduce --shallow to reduce huge torture tests
     new e66d5fa78 travis: make torture use --shallow=40
     new 5a1b0f4c5 mailmap: fix Andrew Ishchuk
     new dc4900eea curl: improved cleanup in upload error path
     new 4940bb856 doh: make it behave when built without proxy support
     new 70a654151 curl: fix memory leak in OOM in etags logic
     new 5dc56eb95 altsvc: make the save function ignore NULL filenames
     new 6a15d1d4e lib1557: fix mem-leak in OOM
     new 197d8aaf6 lib1559: fix mem-leak in OOM
     new f389953da unit1607: fix mem-leak in OOM
     new 5ada90045 unit1609: fix mem-leak in OOM
     new d00aa703f unit1620: fix bad free in OOM
     new 86f9c6762 cirrus: Drop the FreeBSD 10.4 build
     new 68ffe6c17 ntlm_wb: fix double-free in OOM
     new 1fb2a4875 azure: make the default build use --enable-debug 
--enable-werror
     new ec3758b95 azure: add a torture test
     new 9f239811f tests: fix build with `CURL_DISABLE_DOH`
     new 4457e08a7 hostip: suppress compiler warning
     new 38ad9ea1b tests: use DoH feature for DoH tests
     new 29ca9fc59 multi: free sockhash on OOM
     new 69ed88f47 azure: add a torture test on mac
     new 024981cd1 RELEASE-NOTES: synced
     new 571f2c81d runtests: --repeat=[num] to repeat tests
     new 38797e881 lib1591: free memory properly on OOM, in the trailers 
callback
     new 1d2d3feb2 libssh2: add support for ECDSA and ed25519 knownhost keys
     new b0a9e3c28 winbuild: Document CURL_STATICLIB requirement for static 
libcurl
     new 5eda54c0f azure: the macos cmake doesn't need to install cmake
     new 35f908072 cirrus: Switch to the FreeBSD 12.1 point release & enable 
more tests.
     new 4147d58ae docs: TLS SRP doesn't work with TLS 1.3
     new 73ca94675 KNOWN_BUGS: LDAP on Windows doesn't work
     new 8a9d6eeb3 KNOWN_BUGS: Connection information when using TCP Fast Open
     new 3ab45a987 KNOWN_BUGS: TLS session cache doesn't work with TFO
     new 31e637d22 Revert "checksrc: fix regexp for ASSIGNWITHINCONDITION"
     new 728209345 tests: make sure checksrc runs on header files too
     new bdb5b6dd5 lib: remove ASSIGNWITHINCONDITION exceptions, use our code 
style
     new 0caf1423e define: remove HAVE_ENGINE_LOAD_BUILTIN_ENGINES, not used 
anymore
     new aad5bf997 Merge remote-tracking branch 'upstream/master'
     new 2e0d9e8c2 makefile
     new 486ada36f make gnurl

The 151 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .azure-pipelines.yml                            | 166 +++++
 .cirrus.yml                                     |  20 +-
 .mailmap                                        |   4 +
 .travis.yml                                     |  45 +-
 CMake/FindBearSSL.cmake                         |   9 +
 CMake/FindNSS.cmake                             |  15 +
 CMakeLists.txt                                  | 155 ++++-
 Makefile.am                                     |   9 +
 README.md                                       |   1 -
 RELEASE-NOTES                                   | 436 +++++-------
 aux-gnurl/makefile                              |   4 +-
 configure.ac                                    | 126 +++-
 docs/ALTSVC.md                                  |   2 +-
 docs/CURL-DISABLE.md                            | 110 +++
 docs/ESNI.md                                    |   2 +-
 docs/FAQ                                        |   6 +-
 docs/HISTORY.md                                 |   9 +
 docs/HTTP-COOKIES.md                            |   2 +-
 docs/HTTP3.md                                   |   2 +-
 docs/INSTALL.md                                 |  58 +-
 docs/KNOWN_BUGS                                 |  18 +-
 docs/LICENSE-MIXING.md                          |   5 +
 docs/MANUAL.md                                  |   2 +-
 docs/Makefile.am                                |   1 +
 docs/PARALLEL-TRANSFERS.md                      |   2 +-
 docs/TODO                                       |  20 +-
 docs/cmdline-opts/Makefile.inc                  |   5 +-
 docs/cmdline-opts/alt-svc.d                     |   2 +-
 docs/cmdline-opts/etag-compare.d                |  18 +
 docs/cmdline-opts/etag-save.d                   |  16 +
 docs/cmdline-opts/http3.d                       |   2 +-
 docs/cmdline-opts/parallel-immediate.d          |   9 +
 docs/cmdline-opts/tlspassword.d                 |   2 +
 docs/cmdline-opts/tlsuser.d                     |   2 +
 docs/examples/Makefile.inc                      |   2 +-
 docs/examples/anyauthput.c                      |   2 +-
 docs/examples/chkspeed.c                        |   2 +-
 docs/examples/crawler.c                         |   2 +-
 docs/examples/curlgtk.c                         |   2 +-
 docs/examples/curlx.c                           |   2 +-
 docs/examples/fileupload.c                      |   2 +-
 docs/examples/fopen.c                           |   2 +-
 docs/examples/ftpupload.c                       |   2 +-
 docs/examples/href_extractor.c                  |   2 +-
 docs/examples/http-post.c                       |   2 +-
 docs/examples/https.c                           |   2 +-
 docs/examples/imap-list.c                       |   2 +-
 docs/examples/imap-lsub.c                       |   2 +-
 docs/examples/imap-noop.c                       |   2 +-
 docs/examples/imap-store.c                      |   2 +-
 docs/examples/{multi-single.c => multi-poll.c}  |  55 +-
 docs/examples/pop3-dele.c                       |   2 +-
 docs/examples/pop3-list.c                       |   2 +-
 docs/examples/pop3-noop.c                       |   2 +-
 docs/examples/pop3-retr.c                       |   2 +-
 docs/examples/pop3-ssl.c                        |   2 +-
 docs/examples/pop3-stat.c                       |   2 +-
 docs/examples/pop3-uidl.c                       |   2 +-
 docs/examples/rtsp.c                            |   2 +-
 docs/examples/sessioninfo.c                     |   2 +-
 docs/examples/smtp-expn.c                       |   2 +-
 docs/examples/smtp-ssl.c                        |   2 +-
 docs/examples/smtp-tls.c                        |   2 +-
 docs/examples/smtp-vrfy.c                       |   2 +-
 docs/examples/usercertinmem.c                   |   2 +-
 docs/libcurl/Makefile.inc                       | 163 ++---
 docs/libcurl/gnurl_global_sslset.3              |   3 +-
 docs/libcurl/gnurl_multi_poll.3                 |  11 +-
 docs/libcurl/gnurl_multi_wait.3                 |   5 +-
 docs/libcurl/gnurl_multi_wakeup.3               |  86 +++
 docs/libcurl/libgnurl-errors.3                  |  14 +-
 docs/libcurl/libgnurl-multi.3                   |   2 +-
 docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3 |  11 +-
 docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3   |   7 +-
 docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3        |  38 +-
 docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3   |   4 +-
 docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3       |   8 +-
 docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3   |   4 +-
 docs/libcurl/opts/GNURLOPT_VERBOSE.3            |   3 +-
 docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3   |   7 +-
 docs/libcurl/symbols-in-versions                |  17 +-
 include/gnurl/curl.h                            |  13 +-
 include/gnurl/curlver.h                         |   6 +-
 include/gnurl/multi.h                           |  10 +
 include/gnurl/system.h                          |  27 +-
 lib/CMakeLists.txt                              |   1 -
 lib/Makefile.inc                                |  11 +-
 lib/Makefile.m32                                |   4 +-
 lib/altsvc.c                                    |  10 +-
 lib/asyn-thread.c                               |  14 +-
 lib/checksrc.pl                                 |  13 +-
 lib/config-dos.h                                |   2 +-
 lib/config-mac.h                                |   2 +-
 lib/config-plan9.h                              |   1 -
 lib/config-symbian.h                            |   3 -
 lib/config-tpf.h                                |   4 -
 lib/config-vxworks.h                            |   3 -
 lib/config-win32.h                              |   6 +-
 lib/config-win32ce.h                            |   2 +-
 lib/conncache.c                                 |  31 +-
 lib/conncache.h                                 |  24 +-
 lib/cookie.c                                    |   3 +-
 lib/curl_base64.h                               |   2 +-
 lib/curl_config.h.cmake                         |   9 +-
 lib/curl_des.c                                  |   2 +-
 lib/curl_des.h                                  |   2 +-
 lib/curl_fnmatch.h                              |   2 +-
 lib/curl_gethostname.h                          |   2 +-
 lib/curl_ldap.h                                 |   2 +-
 lib/curl_memrchr.h                              |   2 +-
 lib/curl_multibyte.c                            |   2 +-
 lib/curl_multibyte.h                            |  13 +-
 lib/curl_ntlm_core.h                            |   4 +-
 lib/curl_ntlm_wb.c                              |  17 +-
 lib/curl_rtmp.h                                 |   2 +-
 lib/curl_setup.h                                |  25 +-
 lib/curl_setup_once.h                           |  27 +-
 lib/curl_sha256.h                               |   2 +-
 lib/curl_sspi.c                                 |   2 +-
 lib/curl_sspi.h                                 |   2 +-
 lib/curl_threads.c                              |   2 +-
 lib/curl_threads.h                              |   2 +-
 lib/dict.h                                      |   2 +-
 lib/doh.c                                       | 196 +++---
 lib/doh.h                                       |   6 +-
 lib/dotdot.c                                    |   2 +-
 lib/dotdot.h                                    |   2 +-
 lib/easy.c                                      |  23 +-
 lib/easyif.h                                    |   2 +-
 lib/file.h                                      |   2 +-
 lib/ftp.c                                       |   4 +-
 lib/ftplistparser.h                             |   2 +-
 lib/getinfo.h                                   |   2 +-
 lib/gopher.h                                    |   2 +-
 lib/hostcheck.h                                 |   2 +-
 lib/hostip.c                                    |   4 +
 lib/hostip4.c                                   |  12 +-
 lib/hostsyn.c                                   |   2 +-
 lib/http.c                                      |   9 +-
 lib/http.h                                      |   5 +
 lib/http2.c                                     |   7 +-
 lib/http2.h                                     |   2 +-
 lib/http_ntlm.c                                 |   9 +-
 lib/http_proxy.c                                |   5 +-
 lib/imap.h                                      |   2 +-
 lib/inet_ntop.c                                 |   2 +-
 lib/inet_ntop.h                                 |   2 +-
 lib/inet_pton.c                                 |   2 +-
 lib/inet_pton.h                                 |   2 +-
 lib/krb5.c                                      |   2 +-
 lib/ldap.c                                      |   2 +-
 lib/llist.h                                     |   2 +-
 lib/memdebug.h                                  |   2 +-
 lib/mprintf.c                                   |   4 +-
 lib/multi.c                                     | 151 +++-
 lib/multihandle.h                               |  10 +
 lib/nonblock.c                                  |   2 +-
 lib/nonblock.h                                  |   2 +-
 lib/parsedate.c                                 |  24 +
 lib/parsedate.h                                 |   8 +-
 lib/pop3.h                                      |   2 +-
 lib/progress.c                                  |  18 +-
 lib/quic.h                                      |   4 +
 lib/rtsp.h                                      |   2 +-
 lib/select.c                                    |   2 +-
 lib/select.h                                    |   2 +-
 lib/sendf.c                                     |   4 +-
 lib/setopt.c                                    |   4 +-
 lib/sha256.c                                    |   2 +-
 lib/slist.c                                     |   2 +-
 lib/slist.h                                     |   2 +-
 lib/smtp.h                                      |   2 +-
 lib/sockaddr.h                                  |   2 +-
 lib/socks.h                                     |   2 +-
 lib/strdup.c                                    |   2 +-
 lib/strerror.c                                  | 573 +++++++---------
 lib/strerror.h                                  |   3 +
 lib/strtok.c                                    |   2 +-
 lib/strtok.h                                    |   2 +-
 lib/strtoofft.c                                 |   2 +-
 lib/telnet.c                                    |   4 +-
 lib/telnet.h                                    |   2 +-
 lib/tftp.h                                      |   2 +-
 lib/transfer.c                                  |   9 +-
 lib/url.c                                       |  30 +-
 lib/urldata.h                                   |  23 +-
 lib/vauth/cram.c                                |   2 +-
 lib/vauth/digest.h                              |   2 +-
 lib/version.c                                   |   2 +-
 lib/vquic/ngtcp2.c                              | 307 +++++++--
 lib/vquic/ngtcp2.h                              |   5 +-
 lib/vquic/quiche.c                              |  28 +-
 lib/vssh/libssh.c                               |  10 +-
 lib/vssh/libssh2.c                              | 128 ++--
 lib/{ => vssh}/ssh.h                            |   0
 lib/vtls/bearssl.c                              | 874 ++++++++++++++++++++++++
 lib/{curl_range.h => vtls/bearssl.h}            |  14 +-
 lib/vtls/gskit.h                                |   2 +-
 lib/vtls/mbedtls.h                              |   2 +-
 lib/vtls/nss.c                                  |   2 +-
 lib/vtls/openssl.c                              | 143 +++-
 lib/vtls/polarssl.h                             |   2 +-
 lib/vtls/polarssl_threadlock.c                  |   2 +-
 lib/vtls/polarssl_threadlock.h                  |   2 +-
 lib/vtls/schannel.c                             |   4 -
 lib/vtls/schannel_verify.c                      |  23 +-
 lib/vtls/vtls.c                                 |   7 +-
 lib/vtls/vtls.h                                 |   1 +
 packages/OS400/curl.inc.in                      |   8 +-
 packages/vms/config_h.com                       |  22 -
 packages/vms/generate_config_vms_h_curl.com     |   4 +-
 scripts/contributors.sh                         |   4 +-
 src/CMakeLists.txt                              |   2 +-
 src/slist_wc.c                                  |   2 +-
 src/slist_wc.h                                  |   2 +-
 src/tool_binmode.c                              |   2 +-
 src/tool_binmode.h                              |   2 +-
 src/tool_bname.c                                |   2 +-
 src/tool_bname.h                                |   2 +-
 src/tool_cb_dbg.h                               |   2 +-
 src/tool_cb_hdr.c                               |  54 ++
 src/tool_cb_hdr.h                               |   3 +-
 src/tool_cb_prg.c                               |  11 +-
 src/tool_cb_rea.c                               |  28 +-
 src/tool_cb_rea.h                               |  10 +-
 src/tool_cb_see.c                               |   2 +-
 src/tool_cb_see.h                               |   2 +-
 src/tool_cfgable.c                              |   2 +
 src/tool_cfgable.h                              |   3 +
 src/tool_convert.h                              |   2 +-
 src/tool_dirhie.h                               |   2 +-
 src/tool_doswin.c                               |  31 +-
 src/tool_doswin.h                               |   2 +-
 src/tool_easysrc.c                              |   4 +-
 src/tool_getparam.c                             |  16 +-
 src/tool_help.c                                 |   6 +
 src/tool_helpers.h                              |   2 +-
 src/tool_homedir.c                              |   2 +-
 src/tool_homedir.h                              |   2 +-
 src/tool_hugehelp.h                             |   2 +-
 src/tool_libinfo.c                              |   2 +-
 src/tool_libinfo.h                              |   2 +-
 src/tool_main.c                                 |   6 +-
 src/tool_metalink.c                             |   2 +-
 src/tool_msgs.c                                 |  21 +-
 src/tool_msgs.h                                 |   4 +-
 src/tool_operate.c                              | 132 +++-
 src/tool_operate.h                              |   2 +
 src/tool_operhlp.c                              |  11 +-
 src/tool_panykey.c                              |   2 +-
 src/tool_panykey.h                              |   2 +-
 src/tool_paramhlp.c                             |   2 +-
 src/tool_parsecfg.h                             |   2 +-
 src/tool_progress.c                             |   8 +
 src/tool_sdecls.h                               |   2 +-
 src/tool_setopt.c                               |   7 +-
 src/tool_setopt.h                               |   2 +-
 src/tool_setup.h                                |   2 +-
 src/tool_sleep.c                                |   2 +-
 src/tool_sleep.h                                |   2 +-
 src/tool_strdup.h                               |   2 +-
 src/tool_urlglob.h                              |   2 +-
 src/tool_util.c                                 |   2 +-
 src/tool_util.h                                 |   2 +-
 src/tool_version.h                              |   2 +-
 src/tool_vms.c                                  |   2 +-
 src/tool_vms.h                                  |   2 +-
 src/tool_writeout.h                             |   2 +-
 src/tool_xattr.h                                |   2 +-
 tests/Makefile.am                               |   3 +-
 tests/data/DISABLED                             |   2 +
 tests/data/Makefile.inc                         |  11 +-
 tests/data/test1135                             |   1 +
 tests/data/{test1139.skip => test1173}          |   5 +-
 tests/data/{test1119 => test1175}               |   4 +-
 tests/data/test1538                             |   6 +-
 tests/data/test1554                             |   6 +
 tests/data/test1558                             |   6 +-
 tests/data/test1560                             |   1 +
 tests/data/{test1323 => test1564}               |  17 +-
 tests/data/{test1541 => test1565}               |  19 +-
 tests/data/test1650                             |   2 +-
 tests/data/test1655                             |   1 +
 tests/data/test2100                             | Bin 1642 -> 1639 bytes
 tests/data/{test1416 => test339}                |  50 +-
 tests/data/{test1416 => test341}                |  50 +-
 tests/data/{test1298 => test342}                |  20 +-
 tests/data/{test1298 => test343}                |  23 +-
 tests/data/{test199 => test490}                 |  25 +-
 tests/data/{test293 => test491}                 |  26 +-
 tests/data/test492                              |  89 +++
 tests/disable-scan.pl                           |  37 +
 tests/error-codes.pl                            |  80 +++
 tests/ftpserver.pl                              |  10 +-
 tests/httpserver.pl                             |   8 +-
 tests/libtest/CMakeLists.txt                    |   6 +-
 tests/libtest/Makefile.am                       |   2 +-
 tests/libtest/Makefile.inc                      |  10 +-
 tests/libtest/lib1557.c                         |   6 +-
 tests/libtest/lib1559.c                         |  12 +-
 tests/libtest/lib1564.c                         | 142 ++++
 tests/libtest/lib1565.c                         | 204 ++++++
 tests/libtest/lib1591.c                         |  21 +-
 tests/libtest/test.h                            | 108 ++-
 tests/runtests.1                                |  16 +-
 tests/runtests.pl                               |  74 +-
 tests/server/CMakeLists.txt                     |   4 +-
 tests/server/Makefile.am                        |   2 +-
 tests/server/resolve.c                          |   6 +-
 tests/server/util.c                             |   3 +-
 tests/sshhelp.pm                                |  21 +-
 tests/sshserver.pl                              |   3 +
 tests/unit/CMakeLists.txt                       |   2 +-
 tests/unit/Makefile.am                          |   2 +-
 tests/unit/curlcheck.h                          |   4 +-
 tests/unit/unit1607.c                           |  30 +-
 tests/unit/unit1609.c                           |  29 +-
 tests/unit/unit1620.c                           |   2 +
 tests/unit/unit1650.c                           |   4 +-
 tests/unit/unit1655.c                           | 130 +++-
 320 files changed, 4906 insertions(+), 1795 deletions(-)
 create mode 100644 .azure-pipelines.yml
 create mode 100644 CMake/FindBearSSL.cmake
 create mode 100644 CMake/FindNSS.cmake
 create mode 100644 docs/CURL-DISABLE.md
 create mode 100644 docs/cmdline-opts/etag-compare.d
 create mode 100644 docs/cmdline-opts/etag-save.d
 create mode 100644 docs/cmdline-opts/parallel-immediate.d
 copy docs/examples/{multi-single.c => multi-poll.c} (55%)
 create mode 100644 docs/libcurl/gnurl_multi_wakeup.3
 rename lib/{ => vssh}/ssh.h (100%)
 create mode 100644 lib/vtls/bearssl.c
 copy lib/{curl_range.h => vtls/bearssl.h} (79%)
 copy tests/data/{test1139.skip => test1173} (61%)
 copy tests/data/{test1119 => test1175} (66%)
 copy tests/data/{test1323 => test1564} (75%)
 copy tests/data/{test1541 => test1565} (68%)
 copy tests/data/{test1416 => test339} (71%)
 copy tests/data/{test1416 => test341} (68%)
 copy tests/data/{test1298 => test342} (69%)
 copy tests/data/{test1298 => test343} (62%)
 copy tests/data/{test199 => test490} (65%)
 copy tests/data/{test293 => test491} (69%)
 create mode 100644 tests/data/test492
 create mode 100644 tests/error-codes.pl
 create mode 100644 tests/libtest/lib1564.c
 create mode 100644 tests/libtest/lib1565.c

diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
new file mode 100644
index 000000000..93f8cd067
--- /dev/null
+++ b/.azure-pipelines.yml
@@ -0,0 +1,166 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy 
your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+trigger:
+- master
+
+##########################################
+### Linux jobs first
+##########################################
+
+jobs:
+  - job: vanilla_ubuntu
+    displayName: unbuntu default
+    pool:
+      vmImage: 'ubuntu-latest'
+    steps:
+    - script: ./buildconf && ./configure --enable-debug --enable-werror
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: disable_ipv6
+    displayName: ubuntu w/o IPv6
+    pool:
+      vmImage: 'ubuntu-latest'
+    steps:
+    - script: ./buildconf && ./configure --disable-ipv6
+      displayName: 'Run configure --disable-ipv6'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: disable_http_smtp_imap
+    displayName: ubuntu w/o HTTP/SMTP/IMAP
+    pool:
+      vmImage: 'ubuntu-latest'
+    steps:
+    - script: ./buildconf && ./configure --disable-http --disable-smtp 
--disable-imap
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: disable_thredres
+    displayName: ubuntu sync resolver
+    pool:
+      vmImage: 'ubuntu-latest'
+    steps:
+    - script: ./buildconf && ./configure --disable-threaded-resolver
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: http_only
+    displayName: ubuntu HTTP only
+    pool:
+      vmImage: 'ubuntu-latest'
+    steps:
+    - script: ./buildconf && ./configure --disable-dict --disable-file 
--disable-ftp --disable-gopher --disable-imap --disable-ldap --disable-pop3 
--disable-rtmp --disable-rtsp --disable-scp --disable-sftp --disable-smb 
--disable-smtp --disable-telnet --disable-tftp
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: torture
+    displayName: ubuntu torture tests
+    pool:
+      vmImage: 'ubuntu-latest'
+    steps:
+    - script: sudo apt install libnghttp2-dev
+      displayName: 'apt install'
+
+    - script: ./buildconf && ./configure --enable-debug --disable-shared 
--disable-threaded-resolver --enable-alt-svc
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make "TFLAGS=-n -t --shallow=40 '!FTP'" test-nonflaky
+      displayName: 'torture test'
+
+##########################################
+### macOS jobs below
+##########################################
+
+  - job: macos_plain
+    displayName: macos default
+    pool:
+      vmImage: 'macOS-latest'
+    steps:
+    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config
+      displayName: Install packages
+
+    - script: ./buildconf && ./configure --enable-debug --enable-werror
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: macos_libssh2
+    displayName: macos libssh2
+    pool:
+      vmImage: 'macOS-latest'
+    steps:
+    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config libssh2
+      displayName: Install packages
+
+    - script: ./buildconf && ./configure --with-libssh2 --enable-debug
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make test-nonflaky
+      displayName: 'test'
+
+  - job: macos_cmake
+    displayName: macos cmake openssl
+    pool:
+      vmImage: 'macOS-latest'
+    steps:
+    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config openssl
+      displayName: Install packages
+
+    - script: cmake -H. -Bbuild -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl 
-DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON && cmake --build build
+      displayName: 'Run cmake'
+
+  - job: macos_torture
+    displayName: macos torture
+    pool:
+      vmImage: 'macOS-latest'
+    steps:
+    - script: brew update && brew install libtool autoconf automake nghttp2 
pkg-config
+      displayName: Install packages
+
+    - script: ./buildconf && ./configure --enable-debug --disable-shared 
--disable-threaded-resolver --enable-alt-svc
+      displayName: 'Run configure'
+
+    - script: make
+      displayName: 'make'
+
+    - script: make "TFLAGS=-n -t --shallow=25 '!FTP'" test-nonflaky
+      displayName: 'torture test'
+
diff --git a/.cirrus.yml b/.cirrus.yml
index dc7e2299a..17a277145 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -5,12 +5,11 @@ task:
   name: FreeBSD
   freebsd_instance:
     matrix:
-      # There isn't a stable 13.0 image yet (2019-10)
+      # There isn't a stable 13.0 image yet (2019-12)
       image_family: freebsd-13-0-snap
-      image_family: freebsd-12-0
+      image_family: freebsd-12-1
       # The stable 11.3 image causes "Agent is not responding" so use a 
snapshot
       image_family: freebsd-11-3-snap
-      image_family: freebsd-10-4
 
   env:
     CIRRUS_CLONE_DEPTH: 10
@@ -21,6 +20,13 @@ task:
     - pkg delete -y curl
   configure_script:
     - ./buildconf
+    - case `uname -r` in
+        13.0*)
+        export CC=clang;
+        export CFLAGS="-fsanitize=address,undefined,signed-integer-overflow 
-fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security 
-Werror=array-bounds -g"
+        export CXXFLAGS="-fsanitize=address,undefined 
-fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security 
-Werror=array-bounds -g"
+        export LDFLAGS="-fsanitize=address,undefined 
-fno-sanitize-recover=undefined,integer" ;;
+      esac
     - ./configure --prefix="${HOME}"/install --enable-debug --with-libssh2 
--with-brotli --with-gssapi --with-libidn2 --enable-manual --enable-ldap 
--enable-ldaps --with-librtmp --with-libmetalink --with-libpsl --with-nghttp2 
|| { tail -300 config.log; false; }
   compile_script:
     - make V=1
@@ -37,10 +43,10 @@ task:
     - SKIP_TESTS=''
     - uname -r
     - case `uname -r` in
-        13.0*) SKIP_TESTS='!303 !304 !323 !504 !1242 !1243 !2002 !2003';;
-        12.0*) SKIP_TESTS='!303 !304 !323 !504 !1242 !1243 !2002 !2003';;
-        11.3*) SKIP_TESTS='!303 !304 !504 !1242 !1243 !2002 !2003';;
-        10.4*) SKIP_TESTS='!303 !304 !310 !311 !312 !313 !504 !1082 !1242 
!1243 !2002 !2003 !2034 !2035 !2037 !2038 !2041 !2042 !2048 !3000 !3001';;
+        13.0*) SKIP_TESTS='!323 !1242 !1243 !2002 !2003';;
+        12.1*) SKIP_TESTS='!323 !1242 !1243 !2002 !2003';;
+        11.3*) SKIP_TESTS='!504 !1242 !1243 !2002 !2003';;
+        10.4*) SKIP_TESTS='!310 !311 !312 !313 !1082 !1242 !1243 !2002 !2003 
!2034 !2035 !2037 !2038 !2041 !2042 !2048 !3000 !3001';;
       esac
     - sudo -u nobody make V=1 TFLAGS="-n -a -p !flaky ${SKIP_TESTS}" 
test-nonflaky
   install_script:
diff --git a/.mailmap b/.mailmap
index e38055f78..1fbbf1d89 100644
--- a/.mailmap
+++ b/.mailmap
@@ -54,3 +54,7 @@ Anton Malov <address@hidden>
 Marquis de Muesli <address@hidden>
 Kyohei Kadota <address@hidden>
 Lucas Pardue <address@hidden> <address@hidden>
+Massimiliano Fantuzzi <address@hidden>
+Niall O'Reilly <address@hidden>
+Mohammad Hasbini <address@hidden>
+Andrew Ishchuk <address@hidden>
diff --git a/.travis.yml b/.travis.yml
index 3c4fb43e5..8c77a746a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -57,12 +57,6 @@ matrix:
                   packages:
                       - *common_packages
                       - libssh-dev
-        - os: linux
-          compiler: gcc
-          dist: trusty
-          env:
-              - T=normal C="--disable-http --disable-smtp --disable-imap"
-              - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
         - os: linux
           compiler: gcc
           dist: trusty
@@ -228,22 +222,6 @@ matrix:
                       - libgnutls28-dev
                       - libpsl-dev
                       - libbrotli-dev
-        - os: linux
-          compiler: clang
-          dist: xenial
-          env:
-              - T=debug C="--disable-threaded-resolver"
-              - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
-          addons:
-              apt:
-                  sources:
-                      - *common_sources
-                      - llvm-toolchain-xenial-7
-                  packages:
-                      - *common_packages
-                      - clang-7
-                      - libpsl-dev
-                      - libbrotli-dev
         - os: linux
           compiler: clang
           dist: xenial
@@ -267,9 +245,6 @@ matrix:
           env:
               - T=iconv
               - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
-        - os: osx
-          compiler: gcc
-          env: T=debug C=--with-libssh2
         - os: osx
           compiler: gcc
           env: T=debug C="--disable-dict --disable-file --disable-ftp 
--disable-gopher --disable-imap --disable-ldap --disable-pop3 --disable-rtmp 
--disable-rtsp --disable-scp --disable-sftp --disable-smb --disable-smtp 
--disable-telnet --disable-tftp --disable-unix-sockets --disable-shared 
--enable-debug --enable-maintainer-mode --without-brotli --without-gssapi 
--without-libidn2 --without-libmetalink --without-libpsl --without-librtmp 
--without-libssh2 --without-nghttp2 --without-ntlm- [...]
@@ -326,7 +301,7 @@ matrix:
           compiler: gcc
           dist: xenial
           env:
-              - T=coverage
+              - T=torture
               - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
           addons:
               apt:
@@ -439,8 +414,8 @@ matrix:
                       - zlib1g-dev
 
 before_install:
-    - eval "${OVERRIDE_CC}"
-    - eval "${OVERRIDE_CXX}"
+  - export "${OVERRIDE_CC-blank=}"
+  - export "${OVERRIDE_CXX-blank=}"
 
 install:
   - if [ "$T" = "coverage" ]; then pip2 install --user cpp-coveralls; fi
@@ -469,7 +444,7 @@ before_script:
        git clone --depth 1 https://github.com/ngtcp2/ngtcp2 &&
        cd ngtcp2 &&
        autoreconf -i &&
-       ./configure PKG_CONFIG_PATH=$HOME/ngbuild/lib/pkgconfig 
LDFLAGS="-Wl,-rpath,$HOME/ngbuild/lib" --prefix=$HOME/ngbuild &&
+       ./configure PKG_CONFIG_PATH=$HOME/ngbuild/lib/pkgconfig 
LDFLAGS="-Wl,-rpath,$HOME/ngbuild/lib" --prefix=$HOME/ngbuild --enable-lib-only 
&&
        make && make install)
       fi
     - |
@@ -560,6 +535,16 @@ script:
              coveralls --gcov /usr/bin/gcov-8 --gcov-options '\-lp' -i src -e 
lib -e tests -e docs -b $PWD/src
              coveralls --gcov /usr/bin/gcov-8 --gcov-options '\-lp' -e src -i 
lib -e tests -e docs -b $PWD/lib
         fi
+    - |
+        set -eo pipefail
+        if [ "$T" = "torture" ]; then
+             ./configure --enable-debug --disable-shared 
--disable-threaded-resolver --enable-code-coverage --enable-werror 
--enable-alt-svc --with-libssh2
+             make
+             make TFLAGS=-n test-nonflaky
+             make "TFLAGS=-n -e" test-nonflaky
+             tests="1 200 300 500 700 800 900 1000 1100 1200 1302 1400 1502 
3000"
+             make "TFLAGS=-n --shallow=40 -t $tests" test-nonflaky
+        fi
     - |
         set -eo pipefail
         if [ "$T" = "debug" ]; then
@@ -609,6 +594,8 @@ script:
                 make test-nonflaky
              fi
              if [ -n $CHECKSRC ]; then
+                echo "enable COPYRIGHTYEAR" > ./docs/examples/.checksrc
+                echo "enable COPYRIGHTYEAR" > ./include/curl/.checksrc
                 make checksrc
              fi
         fi
diff --git a/CMake/FindBearSSL.cmake b/CMake/FindBearSSL.cmake
new file mode 100644
index 000000000..20d239a4f
--- /dev/null
+++ b/CMake/FindBearSSL.cmake
@@ -0,0 +1,9 @@
+find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
+
+find_library(BEARSSL_LIBRARY bearssl)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(BEARSSL DEFAULT_MSG
+    BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
+
+mark_as_advanced(BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
diff --git a/CMake/FindNSS.cmake b/CMake/FindNSS.cmake
new file mode 100644
index 000000000..277c7dfb2
--- /dev/null
+++ b/CMake/FindNSS.cmake
@@ -0,0 +1,15 @@
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_NSS nss)
+endif()
+if(NOT PC_NSS_FOUND)
+  return()
+endif()
+
+set(NSS_LIBRARIES ${PC_NSS_LINK_LIBRARIES})
+set(NSS_INCLUDE_DIRS ${PC_NSS_INCLUDE_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NSS DEFAULT_MSG NSS_INCLUDE_DIRS 
NSS_LIBRARIES)
+
+mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARIES)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c476facad..5419b525b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -233,6 +233,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
 endif()
 
 # Include all the necessary files for macros
+include(CMakePushCheckState)
 include(CheckFunctionExists)
 include(CheckIncludeFile)
 include(CheckIncludeFiles)
@@ -283,7 +284,7 @@ if(WIN32)
 endif()
 
 # check SSL libraries
-# TODO support GNUTLS, NSS, POLARSSL, CYASSL
+# TODO support GNUTLS, POLARSSL, CYASSL
 
 if(APPLE)
   option(CMAKE_USE_SECTRANSP "enable Apple OS native SSL/TLS" OFF)
@@ -294,9 +295,11 @@ if(WIN32)
     CMAKE_USE_WINSSL OFF)
 endif()
 option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
+option(CMAKE_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF)
+option(CMAKE_USE_NSS "Enable NSS for SSL/TLS" OFF)
 
 set(openssl_default OFF)
-if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
+if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR 
CMAKE_USE_NSS)
   set(openssl_default OFF)
 endif()
 option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
@@ -309,6 +312,8 @@ count_true(enabled_ssl_options_count
   CMAKE_USE_SECTRANSP
   CMAKE_USE_OPENSSL
   CMAKE_USE_MBEDTLS
+  CMAKE_USE_BEARSSL
+  CMAKE_USE_NSS
 )
 if(enabled_ssl_options_count GREATER "1")
   set(CURL_WITH_MULTI_SSL ON)
@@ -402,6 +407,144 @@ if(CMAKE_USE_GNUTLS)
   endif()
 endif()
 
+if(CMAKE_USE_BEARSSL)
+  find_package(BearSSL REQUIRED)
+  set(SSL_ENABLED ON)
+  set(USE_BEARSSL ON)
+  list(APPEND CURL_LIBS ${BEARSSL_LIBRARY})
+  include_directories(${BEARSSL_INCLUDE_DIRS})
+endif()
+
+if(CMAKE_USE_NSS)
+  find_package(NSS REQUIRED)
+  include_directories(${NSS_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NSS_LIBRARIES})
+  set(SSL_ENABLED ON)
+  set(USE_NSS ON)
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS})
+  set(CMAKE_REQUIRED_LIBRARIES ${NSS_LIBRARIES})
+  check_symbol_exists(PK11_CreateManagedGenericObject "pk11pub.h" 
HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
+  cmake_pop_check_state()
+endif()
+
+option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
+if(USE_NGHTTP2)
+  find_package(NGHTTP2 REQUIRED)
+  include_directories(${NGHTTP2_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
+endif()
+
+if(NOT CURL_DISABLE_LDAP)
+  if(WIN32)
+    option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
+    if(USE_WIN32_LDAP)
+      check_library_exists_concat("wldap32" cldap_open HAVE_WLDAP32)
+      if(NOT HAVE_WLDAP32)
+        set(USE_WIN32_LDAP OFF)
+      endif()
+    endif()
+  endif()
+
+  option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF)
+  mark_as_advanced(CMAKE_USE_OPENLDAP)
+  set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
+  set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
+
+  if(CMAKE_USE_OPENLDAP AND USE_WIN32_LDAP)
+    message(FATAL_ERROR "Cannot use USE_WIN32_LDAP and CMAKE_USE_OPENLDAP at 
the same time")
+  endif()
+
+  # Now that we know, we're not using windows LDAP...
+  if(USE_WIN32_LDAP)
+    check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
+    check_include_file_concat("winber.h"  HAVE_WINBER_H)
+else()
+    # Check for LDAP
+    set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
+    check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
+    check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
+
+    set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES})
+    set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include 
directory")
+    if(CMAKE_LDAP_INCLUDE_DIR)
+      list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
+    endif()
+    check_include_file_concat("ldap.h"           HAVE_LDAP_H)
+    check_include_file_concat("lber.h"           HAVE_LBER_H)
+
+    if(NOT HAVE_LDAP_H)
+      message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
+      set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
+      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP 
includes won't be used
+    elseif(NOT HAVE_LIBLDAP)
+      message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found 
CURL_DISABLE_LDAP set ON")
+      set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
+      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP 
includes won't be used
+    else()
+      if(CMAKE_USE_OPENLDAP)
+        set(USE_OPENLDAP ON)
+      endif()
+      if(CMAKE_LDAP_INCLUDE_DIR)
+        include_directories(${CMAKE_LDAP_INCLUDE_DIR})
+      endif()
+      set(NEED_LBER_H ON)
+      set(_HEADER_LIST)
+      if(HAVE_WINDOWS_H)
+        list(APPEND _HEADER_LIST "windows.h")
+      endif()
+      if(HAVE_SYS_TYPES_H)
+        list(APPEND _HEADER_LIST "sys/types.h")
+      endif()
+      list(APPEND _HEADER_LIST "ldap.h")
+
+      set(_SRC_STRING "")
+      foreach(_HEADER ${_HEADER_LIST})
+        set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n")
+      endforeach()
+
+      set(_SRC_STRING
+        "
+        ${_INCLUDE_STRING}
+        int main(int argc, char ** argv)
+        {
+          BerValue *bvp = NULL;
+          BerElement *bep = ber_init(bvp);
+          ber_free(bep, 1);
+          return 0;
+        }"
+      )
+      set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} 
-DLDAP_DEPRECATED=1")
+      list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
+      if(HAVE_LIBLBER)
+        list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
+      endif()
+      check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H)
+      unset(CMAKE_REQUIRED_LIBRARIES)
+
+      if(NOT_NEED_LBER_H)
+        set(NEED_LBER_H OFF)
+      else()
+        set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
+      endif()
+    endif()
+  endif()
+endif()
+
+# No ldap, no ldaps.
+if(CURL_DISABLE_LDAP)
+  if(NOT CURL_DISABLE_LDAPS)
+    message(STATUS "LDAP needs to be enabled to support LDAPS")
+    set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
+  endif()
+endif()
+
+if(NOT CURL_DISABLE_LDAPS)
+  check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H)
+  check_include_file_concat("ldapssl.h"  HAVE_LDAPSSL_H)
+endif()
+
+
 option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
 
 # Check for idn
@@ -539,7 +682,9 @@ elseif("${CURL_CA_PATH}" STREQUAL "none")
   unset(CURL_CA_PATH CACHE)
 elseif("${CURL_CA_PATH}" STREQUAL "auto")
   unset(CURL_CA_PATH CACHE)
-  set(CURL_CA_PATH_AUTODETECT TRUE)
+  if(NOT USE_NSS)
+    set(CURL_CA_PATH_AUTODETECT TRUE)
+  endif()
 else()
   set(CURL_CA_PATH_SET TRUE)
 endif()
@@ -1072,7 +1217,7 @@ _add_if("Kerberos"      NOT CURL_DISABLE_CRYPTO_AUTH AND
                         (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
 # NTLM support requires crypto function adaptions from various SSL libs
 # TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
-if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR 
USE_SECTRANSP OR USE_MBEDTLS OR USE_GNUTLS))
+if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR 
USE_SECTRANSP OR USE_MBEDTLS OR USE_NSS OR USE_GNUTLS))
   _add_if("NTLM"        1)
   # TODO missing option (autoconf: --enable-ntlm-wb)
   _add_if("NTLM_WB"     NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
@@ -1123,6 +1268,8 @@ _add_if("WinSSL"           SSL_ENABLED AND 
USE_WINDOWS_SSPI)
 _add_if("OpenSSL"          SSL_ENABLED AND USE_OPENSSL)
 _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
 _add_if("mbedTLS"          SSL_ENABLED AND USE_MBEDTLS)
+_add_if("BearSSL"          SSL_ENABLED AND USE_BEARSSL)
+_add_if("NSS"              SSL_ENABLED AND USE_NSS)
 if(_items)
   list(SORT _items)
 endif()
diff --git a/Makefile.am b/Makefile.am
index 50994764c..0a4785cff 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,15 @@ AUTOMAKE_OPTIONS = foreign
 
 ACLOCAL_AMFLAGS = -I m4
 
+CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in      \
+ CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake   \
+ CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake       \
+ CMake/Macros.cmake              \
+ CMake/CurlSymbolHiding.cmake CMake/FindCARES.cmake             \
+ CMake/FindLibSSH2.cmake CMake/FindNGHTTP2.cmake                \
+ CMake/FindMbedTLS.cmake CMake/FindBearSSL.cmake                \
+ CMake/cmake_uninstall.cmake.in CMake/curl-config.cmake.in
+
 PLAN9_DIST = plan9/include/mkfile \
  plan9/include/mkfile             \
  plan9/mkfile.proto               \
diff --git a/README.md b/README.md
index 480b53bab..8e1986ba1 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,6 @@
 [![Travis-CI Build 
Status](https://travis-ci.org/curl/curl.svg?branch=master)](https://travis-ci.org/curl/curl)
 [![AppVeyor Build 
Status](https://ci.appveyor.com/api/projects/status/l1vv31029huhf4g4?svg=true)](https://ci.appveyor.com/project/curlorg/curl)
 [![Cirrus Build 
Status](https://api.cirrus-ci.com/github/curl/curl.svg?branch=master)](https://cirrus-ci.com/github/curl/curl)
-[![Coverage 
Status](https://coveralls.io/repos/github/curl/curl/badge.svg)](https://coveralls.io/github/curl/curl)
 [![Backers on Open 
Collective](https://opencollective.com/curl/backers/badge.svg)](#backers)
 [![Sponsors on Open 
Collective](https://opencollective.com/curl/sponsors/badge.svg)](#sponsors)
 [![Language Grade: 
C/C++](https://img.shields.io/lgtm/grade/cpp/g/curl/curl.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/curl/curl/context:cpp)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index cea2debda..371482c1b 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,144 +1,103 @@
-curl and libcurl 7.67.0
+curl and libcurl 7.68.0
 
- Public curl releases:         186
- Command line options:         226
+ Public curl releases:         187
+ Command line options:         229
  curl_easy_setopt() options:   269
- Public functions in libcurl:  81
+ Public functions in libcurl:  82
  Contributors:                 2056
 
 This release includes the following changes:
 
- o curl: added --no-progress-meter [73]
- o setopt: CURLMOPT_MAX_CONCURRENT_STREAMS is new [55]
- o urlapi: CURLU_NO_AUTHORITY allows empty authority/host part [22]
+ o TLS: add BearSSL vtls implementation [37]
+ o XFERINFOFUNCTION: support CURL_PROGRESSFUNC_CONTINUE [36]
+ o curl: add --etag-compare and --etag-save [31]
+ o curl: add --parallel-immediate [29]
+ o multi: add curl_multi_wakeup() [38]
+ o openssl: CURLSSLOPT_NO_PARTIALCHAIN can disable partial cert chains [45]
 
 This release includes the following bugfixes:
 
- o BINDINGS: five new bindings addded
- o CURLOPT_TIMEOUT.3: Clarify transfer timeout time includes queue time [78]
- o CURLOPT_TIMEOUT.3: remove the mention of "minutes" [74]
- o ESNI: initial build/setup support [71]
- o FTP: FTPFILE_NOCWD: avoid redundant CWDs [28]
- o FTP: allow "rubbish" prepended to the SIZE response [15]
- o FTP: remove trailing slash from path for LIST/MLSD [6]
- o FTP: skip CWD to entry dir when target is absolute [16]
- o FTP: url-decode path before evaluation [36]
- o HTTP3.md: move -p for mkdir, remove -j for make [46]
- o HTTP3: fix invalid use of sendto for connected UDP socket [109]
- o HTTP3: fix ngtcp2 Windows build [93]
- o HTTP3: fix prefix parameter for ngtcp2 build [40]
- o HTTP3: fix typo somehere1 > somewhere1 [108]
- o HTTP3: show an --alt-svc using example too
- o INSTALL: add missing space for configure commands [106]
- o INSTALL: add vcpkg installation instructions [35]
- o README: minor grammar fix [39]
- o altsvc: accept quoted ma and persist values [60]
- o altsvc: both backends run h3-23 now [31]
- o appveyor: Add MSVC ARM64 build [87]
- o appveyor: Use two parallel compilation on appveyor with CMake [98]
- o appveyor: add --disable-proxy autotools build [94]
- o appveyor: add 32-bit MinGW-w64 build [58]
- o appveyor: add a winbuild [14]
- o appveyor: add a winbuild that uses VS2017 [84]
- o appveyor: make winbuilds with DEBUG=no/yes and VS 2015/2017 [95]
- o appveyor: publish artifacts on appveyor [105]
- o appveyor: upgrade VS2017 to VS2019 [29]
- o asyn-thread: make use of Curl_socketpair() where available [85]
- o asyn-thread: s/AF_LOCAL/AF_UNIX for Solaris [3]
- o build: Remove unused HAVE_LIBSSL and HAVE_LIBCRYPTO defines [77]
- o checksrc: fix uninitialized variable warning [57]
- o chunked-encoding: stop hiding the CURLE_BAD_CONTENT_ENCODING error [56]
- o cirrus: Increase the git clone depth
- o cirrus: Switch the FreeBSD 11.x build to 11.3 and add a 13.0 build
- o cirrus: switch off blackhole status on the freebsd CI machines [72]
- o cleanups: 21 various PVS-Studio warnings [24]
- o configure: only say ipv6 enabled when the variable is set [110]
- o configure: remove all cyassl references [90]
- o conn-reuse: requests wanting NTLM can reuse non-NTLM connections [99]
- o connect: return CURLE_OPERATION_TIMEDOUT for errno == ETIMEDOUT [72]
- o connect: silence sign-compare warning [83]
- o cookie: avoid harmless use after free [69]
- o cookie: pass in the correct cookie amount to qsort() [27]
- o cookies: change argument type for Curl_flush_cookies [67]
- o cookies: using a share with cookies shouldn't enable the cookie engine [63]
- o copyrights: update copyright notices to 2019 [101]
- o curl: create easy handles on-demand and not ahead of time [54]
- o curl: ensure HTTP 429 triggers --retry [64]
- o curl: exit the create_transfers loop on errors [33]
- o curl: fix memory leaked by parse_metalink() [17]
- o curl: load large files with -d @ much faster [19]
- o docs/HTTP3: fix `--with-ssl` ngtcp2 configure flag [21]
- o docs: added multi-event.c example [75]
- o docs: disambiguate CURLUPART_HOST is for host name (ie no port) [62]
- o docs: note on failed handles not being counted by curl_multi_perform [70]
- o doh: allow only http and https in debug mode [48]
- o doh: avoid truncating DNS QTYPE to lower octet [23]
- o doh: clean up dangling DOH memory on easy close [9]
- o doh: fix (harmless) buffer overrun [13]
- o doh: fix undefined behaviour and open up for gcc and clang optimization [12]
- o doh: return early if there is no time left [48]
- o examples/sslbackend: fix -Wchar-subscripts warning [89]
- o examples: remove the "this exact code has not been verified"
- o git: add tests/server/disabled to .gitignore [59]
- o gnutls: make gnutls_bye() not wait for response on shutdown [104]
- o http2: expire a timeout at end of stream [88]
- o http2: prevent dup'ed handles to send dummy PRIORITY frames [68]
- o http2: relax verification of :authority in push promise requests [8]
- o http2_recv: a closed stream trumps pause state [88]
- o http: lowercase headernames for HTTP/2 and HTTP/3 [49]
- o ldap: Stop using wide char version of ldapp_err2string [1]
- o ldap: fix OOM error on missing query string [76]
- o mbedtls: add error message for cert validity starting in the future [102]
- o mime: when disabled, avoid C99 macro [7]
- o ngtcp2: adapt to API change [66]
- o ngtcp2: compile with latest ngtcp2 + nghttp3 draft-23 [25]
- o ngtcp2: remove fprintf() calls [43]
- o openssl: close_notify on the FTP data connection doesn't mean closure [20]
- o openssl: fix compiler warning with LibreSSL [34]
- o openssl: use strerror on SSL_ERROR_SYSCALL [41]
- o os400: getpeername() and getsockname() return ebcdic AF_UNIX sockaddr [47]
- o parsedate: fix date parsing disabled builds [18]
- o quiche: don't close connection at end of stream
- o quiche: persist connection details (fixes -I with --http3) [11]
- o quiche: set 'drain' when returning without having drained the queues
- o quiche: update HTTP/3 config creation to new API [61]
- o redirect: handle redirects to absolute URLs containing spaces [52]
- o runtests: get textaware info from curl instead of perl [86]
- o schannel: reverse the order of certinfo insertions [96]
- o schannel_verify: Fix concurrent openings of CA file [103]
- o security: silence conversion warning [83]
- o setopt: handle ALTSVC set to NULL
- o setopt: make it easier to add new enum values [4]
- o setopt: store CURLOPT_RTSP_SERVER_CSEQ correctly [24]
- o smb: check for full size message before reading message details [10]
- o smbserver: fix Python 3 compatibility [82]
- o socks: Fix destination host shown on SOCKS5 error [32]
- o test1162: disable MSYS2's POSIX path conversion
- o test1591: fix spelling of http feature [97]
- o tests: add `connect to non-listen` keywords [91]
- o tests: fix narrowing conversion warnings [37]
- o tests: fix the test 3001 cert failures [100]
- o tests: makes tests succeed when using --disable-proxy [81]
- o tests: use %FILE_PWD for file:// URLs [92]
- o tests: use port 2 instead of 60000 for a safer non-listening port [72]
- o tool_operate: Fix retry sleep time shown to user when Retry-After [79]
- o travis: Add an ARM64 build
- o url: Curl_free_request_state() should also free doh handles [107]
- o url: don't set appconnect time for non-ssl/non-ssh connections [42]
- o url: fix the NULL hostname compiler warning [44]
- o url: normalize CURLINFO_EFFECTIVE_URL [80]
- o url: only reuse TLS connections with matching pinning [5]
- o urlapi: avoid index underflow for short ipv6 hostnames [26]
- o urlapi: fix URL encoding when setting a full URL [53]
- o urlapi: fix unused variable warning [57]
- o urlapi: question mark within fragment is still fragment [45]
- o urldata: use 'bool' for the bit type on MSVC compilers [30]
- o vtls: Fix comment typo about macosx-version-min compiler flag [38]
- o vtls: fix narrowing conversion warnings [50]
- o winbuild/MakefileBuild.vc: Add vssh [2]
- o winbuild/MakefileBuild.vc: Fix line endings
- o winbuild: Add manifest to curl.exe for proper OS version detection [51]
- o winbuild: add ENABLE_UNICODE option [65]
+ o Azure Pipelines: add several builds
+ o CMake: add support for building with the NSS vtls backend [43]
+ o CURL-DISABLE: initial docs for the CURL_DISABLE_* defines [19]
+ o CURLOPT_VERBOSE.3: see also ERRORBUFFER
+ o HISTORY: added cmake, HTTP/3 and parallel downloads with curl
+ o INSTALL.md: provide Android build instructions [10]
+ o OPENSOCKETFUNCTION.3: correct the purpose description [48]
+ o altsvc: bump to h3-24 [6]
+ o altsvc: make the save function ignore NULL filenames [67]
+ o build: Disable Visual Studio warning "conditional expression is constant" 
[49]
+ o build: fix for CURL_DISABLE_DOH [2]
+ o checksrc.bat: Add a check for vquic and vssh directories [40]
+ o checksrc: fix regexp for ASSIGNWITHINCONDITION [56]
+ o checksrc: repair the copyrightyear check [25]
+ o cirrus-ci: enable clang sanitizers on freebsd 13 [60]
+ o cirrus: Drop the FreeBSD 10.4 build
+ o config-win32: cpu-machine-OS for Windows on ARM [13]
+ o configure: avoid unportable `==' test(1) operator [1]
+ o configure: enable IPv6 support without `getaddrinfo` [44]
+ o configure: fix typo in help text [4]
+ o conncache: CONNECT_ONLY connections assumed always in-use [71]
+ o conncache: fix multi-thread use of shared connection cache [61]
+ o copyrights: fix copyright year range [25]
+ o curl: fix --upload-file . hangs if delay in STDIN [35]
+ o curl: fix -T globbing [16]
+ o curl: improved cleanup in upload error path [69]
+ o curl: show better error message when no homedir is found [47]
+ o curl_setup_once: consistently use WHILE_FALSE in macros [54]
+ o docs: Change 'experiemental' to 'experimental' [30]
+ o docs: fix several typos [62]
+ o doh: improved both encoding and decoding [11]
+ o doh: make it behave when built without proxy support [68]
+ o examples: add multi-poll.c [14]
+ o global_init: undo the "intialized" bump in case of failure [52]
+ o hostip: suppress compiler warning [64]
+ o http_ntlm: Remove duplicate NSS initialisation [55]
+ o lib: Move lib/ssh.h -> lib/vssh/ssh.h [9]
+ o multi: free sockhash on OOM [63]
+ o multi_poll: avoid busy-loop when called without easy handles attached [15]
+ o ngtcp2: fix thread-safety bug in error-handling [33]
+ o ngtcp2: free used resources on disconnect [7]
+ o ngtcp2: handle key updates as ngtcp2 master branch tells us [8]
+ o ngtcp2: increase QUIC window size when data is consumed [12]
+ o ngtcp2: use overflow buffer for extra HTTP/3 data [5]
+ o ntlm: USE_WIN32_CRYPTO check removed to get USE_NTLM2SESSION set [3]
+ o ntlm_wb: fix double-free in OOM [65]
+ o openssl: Revert to less sensitivity for SYSCALL errors [26]
+ o openssl: improve error message for SYSCALL during connect [27]
+ o openssl: prevent recursive function calls from ctx callbacks [18]
+ o openssl: retrieve reported LibreSSL version at runtime [50]
+ o openssl: set X509_V_FLAG_PARTIAL_CHAIN by default [46]
+ o parsedate: offer a getdate_capped() alternative [53]
+ o pause: avoid updating socket if done was already called [22]
+ o projects: Fix Visual Studio projects SSH builds [41]
+ o projects: Fix Visual Studio wolfSSL configurations
+ o quiche: reject HTTP/3 headers in the wrong order [17]
+ o remove_handle: clear expire timers after multi_done() [20]
+ o runtests: introduce --shallow to reduce huge torture tests [70]
+ o schannel: fix --tls-max for when min is --tlsv1 or default [39]
+ o setopt: Fix ALPN / NPN user option when built without HTTP2 [42]
+ o strerror: Add Curl_winapi_strerror for Win API specific errors [51]
+ o strerror: Fix an error looking up some Windows error strings
+ o system.h: fix for MCST lcc compiler [23]
+ o test1175: verify symbols-in-versions and libcurl-errors.3 in sync [28]
+ o test1558: use double slash after file: [21]
+ o test1560: require IPv6 for IPv6 aware URL parsing [24]
+ o tests/lib1557: fix mem-leak in OOM [66]
+ o tests/lib1559: fix mem-leak in OOM [66]
+ o tests/unit1607: fix mem-leak in OOM [66]
+ o tests/unit1609: fix mem-leak in OOM [66]
+ o tests/unit1620: fix bad free in OOM [66]
+ o tests: fix build with `CURL_DISABLE_DOH` [64]
+ o tests: fix permissions of ssh keys in WSL [58]
+ o tests: make it possible to set executable extensions [58]
+ o tests: use DoH feature for DoH tests [64]
+ o tests: use \r\n for log messages in WSL [58]
+ o travis: abandon coveralls, it is not reliable [57]
+ o travis: build ngtcp2 with --enable-lib-only [32]
+ o travis: export the CC/CXX variables when set [34]
+ o vtls: make BearSSL possible to set with CURL_SSL_BACKEND [72]
+ o winbuild: Define CARES_STATICLIB when WITH_CARES=static [59]
 
 This release includes the following known bugs:
 
@@ -147,136 +106,93 @@ This release includes the following known bugs:
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
-  Alessandro Ghedini, Alex Konev, Alex Samorukov, Andrei Valeriu BICA,
-  Barry Pollard, Bastien Bouclet, Bernhard Walle, Bylon2 on github,
-  Christophe Dervieux, Christoph M. Becker, Dagobert Michelsen, Dan Fandrich,
-  Daniel Silverstone, Daniel Stenberg, Denis Chaplygin, Emil Engler,
-  Francois Rivard, George Liu, Gilles Vollant, Griffin Downs, Harry Sintonen,
-  Ilya Kosarev, infinnovation-dev on github, Jacob Barthelmeh, Javier Blazquez,
-  Jens Finkhaeuser, Jeremy Lainé, Jeroen Ooms, Jimmy Gaussen, Joel Depooter,
-  Jojojov on github, jzinn on github, Kamil Dudka, Kunal Ekawde, Lucas Pardue,
-  Lucas Severo, Marcel Hernandez, Marcel Raad, Martin Gartner, Max Dymond,
-  Michael Kaufmann, Michał Janiszewski, momala454 on github,
-  Nathaniel J. Smith, Niall O'Reilly, nico-abram on github,
-  Nikos Mavrogiannopoulos, Patrick Monnerat, Paul B. Omta, Paul Dreik,
-  Peter Sumatra, Philippe Marguinaud, Piotr Komborski, Ray Satiro,
-  Richard Alcock, Roland Hieber, Samuel Surtees, Sebastian Haglund,
-  Spezifant on github, Stian Soiland-Reyes, SumatraPeter on github,
-  Tatsuhiro Tsujikawa, Tom van der Woerdt, Trivikram Kamat,
-  Valerii Zapodovnikov, Vilhelm Prytz, Yechiel Kalmenson, Zenju on github,
-  (68 contributors)
+  3dyd on github, Anderson Sasaki, Andreas Falkenhahn, Andrew Ishchuk,
+  bdry on github, Bjoern Franke, Christian Schmitz, Christopher Reid,
+  Christoph M. Becker, Cynthia Coan, Dan Fandrich, Daniel Gustafsson,
+  Daniel Stenberg, David Benjamin, Gergely Nagy, Gisle Vanem, JanB on github,
+  Javier Blazquez, Jeff Mears, Jeffrey Walton, John Schroeder, Kamil Dudka,
+  Leonardo Taccari, Marcel Raad, Marc Hörsken, Maros Priputen,
+  Massimiliano Fantuzzi, Max Kellermann, Melissa Mears, Michael Forney,
+  Mohammad Hasbini, Niall O'Reilly, Paul Groke, Paul Hoffman,
+  Paulo Roberto Tomasi, Pavel Löbl, Pavel Pavlov, Peter Wu, Ray Satiro,
+  Richard Alcock, Richard Bowker, Shailesh Kapse, SLDiggie on github,
+  Steve Holme, Tatsuhiro Tsujikawa, Tom van der Woerdt, Victor Magierski,
+  Vlastimil Ovčáčík, Wyatt O'Day, Xiaoyin Liu,
+  (50 contributors)
 
         Thanks! (and sorry if I forgot to mention someone)
 
 References to bug reports and discussions on issues:
 
- [1] = https://curl.haxx.se/bug/?i=4272
- [2] = https://curl.haxx.se/bug/?i=4322
- [3] = https://curl.haxx.se/bug/?i=4328
- [4] = https://curl.haxx.se/bug/?i=4321
- [5] = https://curl.haxx.se/mail/lib-2019-09/0061.html
- [6] = https://curl.haxx.se/bug/?i=4348
- [7] = https://curl.haxx.se/bug/?i=4368
- [8] = https://curl.haxx.se/bug/?i=4365
- [9] = https://curl.haxx.se/bug/?i=4366
- [10] = https://curl.haxx.se/bug/?i=4363
- [11] = https://curl.haxx.se/bug/?i=4358
- [12] = https://curl.haxx.se/bug/?i=4350
- [13] = https://curl.haxx.se/bug/?i=4352
- [14] = https://curl.haxx.se/bug/?i=4324
- [15] = https://curl.haxx.se/bug/?i=4339
- [16] = https://curl.haxx.se/bug/?i=4332
- [17] = https://curl.haxx.se/bug/?i=4326
- [18] = https://curl.haxx.se/bug/?i=4325
- [19] = https://curl.haxx.se/bug/?i=4336
- [20] = https://curl.haxx.se/bug/?i=4329
- [21] = https://curl.haxx.se/bug/?i=4338
- [22] = https://curl.haxx.se/bug/?i=4349
- [23] = https://curl.haxx.se/bug/?i=4381
- [24] = https://curl.haxx.se/bug/?i=4374
- [25] = https://curl.haxx.se/bug/?i=4392
- [26] = https://curl.haxx.se/bug/?i=4389
- [27] = https://curl.haxx.se/bug/?i=4386
- [28] = https://curl.haxx.se/bug/?i=4382
- [29] = https://curl.haxx.se/bug/?i=4383
- [30] = https://curl.haxx.se/bug/?i=4387
- [31] = https://curl.haxx.se/bug/?i=4395
- [32] = https://curl.haxx.se/bug/?i=4394
- [33] = https://curl.haxx.se/bug/?i=4393
- [34] = https://curl.haxx.se/bug/?i=4397
- [35] = https://curl.haxx.se/bug/?i=4435
- [36] = https://curl.haxx.se/bug/?i=4428
- [37] = https://curl.haxx.se/bug/?i=4415
- [38] = https://curl.haxx.se/bug/?i=4425
- [39] = https://curl.haxx.se/bug/?i=4431
- [40] = https://curl.haxx.se/bug/?i=4430
- [41] = https://curl.haxx.se/bug/?i=4411
- [42] = https://curl.haxx.se/bug/?i=3760
- [43] = https://curl.haxx.se/bug/?i=4421
- [44] = https://curl.haxx.se/bug/?i=4403
- [45] = https://curl.haxx.se/bug/?i=4412
- [46] = https://curl.haxx.se/bug/?i=4407
- [47] = https://curl.haxx.se/bug/?i=4214
- [48] = https://curl.haxx.se/bug/?i=4406
- [49] = https://curl.haxx.se/bug/?i=4400
- [50] = https://curl.haxx.se/bug/?i=4398
- [51] = https://curl.haxx.se/bug/?i=4399
- [52] = https://curl.haxx.se/bug/?i=4445
- [53] = https://curl.haxx.se/bug/?i=4447
- [54] = https://curl.haxx.se/bug/?i=4393
- [55] = https://curl.haxx.se/bug/?i=4410
- [56] = https://curl.haxx.se/bug/?i=4310
- [57] = https://curl.haxx.se/bug/?i=4444
- [58] = https://curl.haxx.se/bug/?i=4433
- [59] = https://curl.haxx.se/bug/?i=4441
- [60] = https://curl.haxx.se/bug/?i=4443
- [61] = https://curl.haxx.se/bug/?i=4437
- [62] = https://curl.haxx.se/bug/?i=4424
- [63] = https://curl.haxx.se/bug/?i=4429
- [64] = https://curl.haxx.se/bug/?i=4465
- [65] = https://curl.haxx.se/bug/?i=4308
- [66] = https://curl.haxx.se/bug/?i=4457
- [67] = https://curl.haxx.se/bug/?i=4455
- [68] = https://curl.haxx.se/bug/?i=4303
- [69] = https://curl.haxx.se/bug/?i=4454
- [70] = https://curl.haxx.se/bug/?i=4446
- [71] = https://curl.haxx.se/bug/?i=4011
- [72] = https://curl.haxx.se/bug/?i=4461
- [73] = https://curl.haxx.se/bug/?i=4422
- [74] = https://curl.haxx.se/bug/?i=4469
- [75] = https://curl.haxx.se/bug/?i=4471
- [76] = https://curl.haxx.se/bug/?i=4467
- [77] = https://curl.haxx.se/bug/?i=4460
- [78] = https://curl.haxx.se/bug/?i=4486
- [79] = https://curl.haxx.se/bug/?i=4498
- [80] = https://curl.haxx.se/bug/?i=4491
- [81] = https://curl.haxx.se/bug/?i=4488
- [82] = https://curl.haxx.se/bug/?i=4484
- [83] = https://curl.haxx.se/bug/?i=4483
- [84] = https://curl.haxx.se/bug/?i=4482
- [85] = https://curl.haxx.se/bug/?i=4466
- [86] = https://curl.haxx.se/bug/?i=4506
- [87] = https://curl.haxx.se/bug/?i=4507
- [88] = https://curl.haxx.se/bug/?i=4496
- [89] = https://curl.haxx.se/bug/?i=4503
- [90] = https://curl.haxx.se/bug/?i=4502
- [91] = https://curl.haxx.se/bug/?i=4511
- [92] = https://curl.haxx.se/bug/?i=4512
- [93] = https://curl.haxx.se/bug/?i=4531
- [94] = https://curl.haxx.se/bug/?i=4526
- [95] = https://curl.haxx.se/bug/?i=4523
- [96] = https://curl.haxx.se/bug/?i=4518
- [97] = https://curl.haxx.se/bug/?i=4520
- [98] = https://curl.haxx.se/bug/?i=4508
- [99] = https://curl.haxx.se/bug/?i=4499
- [100] = https://curl.haxx.se/bug/?i=4551
- [101] = https://curl.haxx.se/bug/?i=4547
- [102] = https://curl.haxx.se/bug/?i=4552
- [103] = https://curl.haxx.se/mail/lib-2019-10/0104.html
- [104] = https://curl.haxx.se/bug/?i=4487
- [105] = https://curl.haxx.se/bug/?i=4509
- [106] = https://curl.haxx.se/bug/?i=4539
- [107] = https://curl.haxx.se/bug/?i=4463
- [108] = https://curl.haxx.se/bug/?i=4535
- [109] = https://curl.haxx.se/bug/?i=4529
- [110] = https://curl.haxx.se/bug/?i=4555
+ [1] = https://curl.haxx.se/bug/?i=4567
+ [2] = https://curl.haxx.se/bug/?i=4565
+ [3] = https://curl.haxx.se/bug/?i=3704
+ [4] = https://curl.haxx.se/bug/?i=4570
+ [5] = https://curl.haxx.se/bug/?i=4525
+ [6] = https://curl.haxx.se/bug/?i=4604
+ [7] = https://curl.haxx.se/bug/?i=4614
+ [8] = https://curl.haxx.se/bug/?i=4612
+ [9] = https://curl.haxx.se/bug/?i=4609
+ [10] = https://curl.haxx.se/bug/?i=4606
+ [11] = https://curl.haxx.se/bug/?i=4598
+ [12] = https://curl.haxx.se/bug/?i=4600
+ [13] = https://curl.haxx.se/bug/?i=4590
+ [14] = https://curl.haxx.se/bug/?i=4596
+ [15] = https://curl.haxx.se/bug/?i=4594
+ [16] = https://curl.haxx.se/bug/?i=4588
+ [17] = https://curl.haxx.se/bug/?i=4571
+ [18] = https://curl.haxx.se/bug/?i=4585
+ [19] = https://curl.haxx.se/bug/?i=4545
+ [20] = https://curl.haxx.se/bug/?i=4575
+ [21] = https://curl.haxx.se/bug/?i=4554
+ [22] = https://curl.haxx.se/bug/?i=4563
+ [23] = https://curl.haxx.se/bug/?i=4576
+ [24] = https://curl.haxx.se/bug/?i=4556
+ [25] = https://curl.haxx.se/bug/?i=4549
+ [26] = https://curl.haxx.se/bug/?i=4624
+ [27] = https://curl.haxx.se/bug/?i=4593
+ [28] = https://curl.haxx.se/bug/?i=4628
+ [29] = https://curl.haxx.se/bug/?i=4500
+ [30] = https://curl.haxx.se/bug/?i=4618
+ [31] = https://curl.haxx.se/bug/?i=4543
+ [32] = https://curl.haxx.se/bug/?i=4646
+ [33] = https://curl.haxx.se/bug/?i=4645
+ [34] = https://curl.haxx.se/bug/?i=4637
+ [35] = https://curl.haxx.se/bug/?i=2051
+ [36] = https://curl.haxx.se/bug/?i=4599
+ [37] = https://curl.haxx.se/bug/?i=4597
+ [38] = https://curl.haxx.se/bug/?i=4418
+ [39] = https://curl.haxx.se/bug/?i=4633
+ [40] = https://curl.haxx.se/bug/?i=4607
+ [41] = https://curl.haxx.se/bug/?i=4492
+ [42] = https://curl.haxx.se/bug/?i=4668
+ [43] = https://curl.haxx.se/bug/?i=4663
+ [44] = https://curl.haxx.se/bug/?i=4662
+ [45] = https://curl.haxx.se/bug/?i=4665
+ [46] = https://curl.haxx.se/mail/lib-2019-11/0094.html
+ [47] = https://curl.haxx.se/bug/?i=4644
+ [48] = https://curl.haxx.se/mail/lib-2019-12/0007.html
+ [49] = https://curl.haxx.se/bug/?i=4658
+ [50] = https://curl.haxx.se/bug/?i=2425
+ [51] = https://curl.haxx.se/bug/?i=4550
+ [52] = https://curl.haxx.se/bug/?i=4636
+ [53] = https://curl.haxx.se/bug/?i=4152
+ [54] = https://curl.haxx.se/bug/?i=4649
+ [55] = https://curl.haxx.se/bug/?i=3935
+ [56] = https://curl.haxx.se/bug/?i=4647
+ [57] = https://curl.haxx.se/bug/?i=4694
+ [58] = https://curl.haxx.se/bug/?i=3899
+ [59] = https://curl.haxx.se/bug/?i=4688
+ [60] = https://curl.haxx.se/bug/?i=4557
+ [61] = https://curl.haxx.se/bug/?i=4544
+ [62] = https://curl.haxx.se/bug/?i=4680
+ [63] = https://curl.haxx.se/bug/?i=4713
+ [64] = https://curl.haxx.se/bug/?i=4692
+ [65] = https://curl.haxx.se/bug/?i=4710
+ [66] = https://curl.haxx.se/bug/?i=4709
+ [67] = https://curl.haxx.se/bug/?i=4707
+ [68] = https://curl.haxx.se/bug/?i=4704
+ [69] = https://curl.haxx.se/bug/?i=4705
+ [70] = https://curl.haxx.se/bug/?i=4699
+ [71] = https://curl.haxx.se/bug/?i=4369
+ [72] = https://curl.haxx.se/bug/?i=4698
diff --git a/aux-gnurl/makefile b/aux-gnurl/makefile
index 3ec12595c..0e165b44b 100644
--- a/aux-gnurl/makefile
+++ b/aux-gnurl/makefile
@@ -26,8 +26,6 @@ release:
        (cd .. ; make clean ; cd aux-gnurl ; git restore makefile)
        (cd .. ; MAKE="make" ./maketgz 7.67.0)
 
-.PHONE: clean
+.PHONY: clean
 clean:
        git restore ..
-
-.include <bsd.prog.mk>
diff --git a/configure.ac b/configure.ac
index 0ae2b0d6f..9b78ccd42 100755
--- a/configure.ac
+++ b/configure.ac
@@ -156,8 +156,8 @@ AC_SUBST(PKGADD_VENDOR)
 
 dnl
 dnl initialize all the info variables
-    curl_ssl_msg="no      
(--with-{ssl,gnutls,nss,mbedtls,wolfssl,schannel,secure-transport,mesalink,amissl}
 )"
-    curl_ssh_msg="no      (--with-libssh2)"
+    curl_ssl_msg="no      
(--with-{ssl,gnutls,nss,mbedtls,wolfssl,schannel,secure-transport,mesalink,amissl,bearssl}
 )"
+    curl_ssh_msg="no      (--with-{libssh,libssh2})"
    curl_zlib_msg="no      (--with-zlib)"
  curl_brotli_msg="no      (--with-brotli)"
     curl_gss_msg="no      (--with-gssapi)"
@@ -1284,16 +1284,23 @@ AC_HELP_STRING([--disable-ipv6],[Disable IPv6 support]),
        ;;
   esac ],
 
-  AC_TRY_RUN([ /* is AF_INET6 available? */
+  AC_TRY_RUN([ /* are AF_INET6 and sockaddr_in6 available? */
 #include <sys/types.h>
 #ifdef HAVE_WINSOCK2_H
 #include <winsock2.h>
+#include <ws2tcpip.h>
 #else
 #include <sys/socket.h>
+#include <netinet/in.h>
+#if defined (__TANDEM)
+# include <netinet/in6.h>
+#endif
 #endif
 #include <stdlib.h> /* for exit() */
 main()
 {
+ struct sockaddr_in6 s;
+ (void)s;
  if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
    exit(1);
  else
@@ -1308,8 +1315,12 @@ main()
   ipv6=yes
 ))
 
-# Check if struct sockaddr_in6 have sin6_scope_id member
 if test "$ipv6" = yes; then
+  curl_ipv6_msg="enabled"
+  AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support])
+  IPV6_ENABLED=1
+  AC_SUBST(IPV6_ENABLED)
+
   AC_MSG_CHECKING([if struct sockaddr_in6 has sin6_scope_id member])
   AC_TRY_COMPILE([
 #include <sys/types.h>
@@ -2486,6 +2497,98 @@ if test -z "$ssl_backends" -o "x$OPT_MESALINK" != xno; 
then
   test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
+dnl ----------------------------------------------------
+dnl check for BearSSL
+dnl ----------------------------------------------------
+
+OPT_BEARSSL=no
+
+_cppflags=$CPPFLAGS
+_ldflags=$LDFLAGS
+AC_ARG_WITH(bearssl,dnl
+AC_HELP_STRING([--with-bearssl=PATH],[where to look for BearSSL, PATH points 
to the installation root])
+AC_HELP_STRING([--without-bearssl], [disable BearSSL detection]),
+  OPT_BEARSSL=$withval)
+
+if test -z "$ssl_backends" -o "x$OPT_BEARSSL" != xno; then
+  ssl_msg=
+
+  if test X"$OPT_BEARSSL" != Xno; then
+
+    if test "$OPT_BEARSSL" = "yes"; then
+      OPT_BEARSSL=""
+    fi
+
+    if test -z "$OPT_BEARSSL" ; then
+      dnl check for lib first without setting any new path
+
+      AC_CHECK_LIB(bearssl, br_ssl_client_init_full,
+      dnl libbearssl found, set the variable
+       [
+         AC_DEFINE(USE_BEARSSL, 1, [if BearSSL is enabled])
+         AC_SUBST(USE_BEARSSL, [1])
+         BEARSSL_ENABLED=1
+         USE_BEARSSL="yes"
+         ssl_msg="BearSSL"
+        test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes
+        ], [], -lbearssl)
+    fi
+
+    addld=""
+    addlib=""
+    addcflags=""
+    bearssllib=""
+
+    if test "x$USE_BEARSSL" != "xyes"; then
+      dnl add the path and test again
+      addld=-L$OPT_BEARSSL/lib$libsuff
+      addcflags=-I$OPT_BEARSSL/include
+      bearssllib=$OPT_BEARSSL/lib$libsuff
+
+      LDFLAGS="$LDFLAGS $addld"
+      if test "$addcflags" != "-I/usr/include"; then
+         CPPFLAGS="$CPPFLAGS $addcflags"
+      fi
+
+      AC_CHECK_LIB(bearssl, br_ssl_client_init_full,
+       [
+       AC_DEFINE(USE_BEARSSL, 1, [if BearSSL is enabled])
+       AC_SUBST(USE_BEARSSL, [1])
+       BEARSSL_ENABLED=1
+       USE_BEARSSL="yes"
+       ssl_msg="BearSSL"
+       test bearssl != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes
+       ],
+       [
+         CPPFLAGS=$_cppflags
+         LDFLAGS=$_ldflags
+       ], -lbearssl)
+    fi
+
+    if test "x$USE_BEARSSL" = "xyes"; then
+      AC_MSG_NOTICE([detected BearSSL])
+      check_for_ca_bundle=1
+
+      LIBS="-lbearssl $LIBS"
+
+      if test -n "$bearssllib"; then
+        dnl when shared libs were found in a path that the run-time
+        dnl linker doesn't search through, we need to add it to
+        dnl CURL_LIBRARY_PATH to prevent further configure tests to fail
+        dnl due to this
+        if test "x$cross_compiling" != "xyes"; then
+          CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$bearssllib"
+          export CURL_LIBRARY_PATH
+          AC_MSG_NOTICE([Added $bearssllib to CURL_LIBRARY_PATH])
+        fi
+      fi
+    fi
+
+  fi dnl BearSSL not disabled
+
+  test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
+fi
+
 dnl ----------------------------------------------------
 dnl NSS. Only check if GnuTLS and OpenSSL are not enabled
 dnl ----------------------------------------------------
@@ -2616,10 +2719,10 @@ if test -z "$ssl_backends" -o "x$OPT_NSS" != xno; then
   test -z "$ssl_msg" || ssl_backends="${ssl_backends:+$ssl_backends, }$ssl_msg"
 fi
 
-case 
"x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$WINSSL_ENABLED$SECURETRANSPORT_ENABLED$MESALINK_ENABLED$AMISSL_ENABLED"
 in
+case 
"x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$MBEDTLS_ENABLED$WOLFSSL_ENABLED$WINSSL_ENABLED$SECURETRANSPORT_ENABLED$MESALINK_ENABLED$BEARSSL_ENABLED$AMISSL_ENABLED"
 in
 x)
   AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and 
more.])
-  AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-wolfssl, --with-mbedtls, 
--with-nss, --with-schannel, --with-secure-transport, --with-mesalink or 
--with-amissl to address this.])
+  AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-wolfssl, --with-mbedtls, 
--with-nss, --with-schannel, --with-secure-transport, --with-mesalink, 
--with-amissl or --with-bearssl to address this.])
   ;;
 x1)
   # one SSL backend is enabled
@@ -4057,15 +4160,6 @@ AC_CHECK_FUNCS([fnmatch \
   fi
 ])
 
-if test "$ipv6" = "yes"; then
-  if test "$curl_cv_func_getaddrinfo" = "yes"; then
-    AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support])
-    IPV6_ENABLED=1
-    AC_SUBST(IPV6_ENABLED)
-    curl_ipv6_msg="enabled"
-  fi
-fi
-
 CURL_CHECK_NONBLOCKING_SOCKET
 
 dnl ************************************************************
@@ -4504,7 +4598,7 @@ dnl
 AC_MSG_CHECKING([whether to support DNS shuffling])
 AC_ARG_ENABLE(dnsshuffle,
 AC_HELP_STRING([--enable-dnsshuffle],[Enable DNS shuffling])
-AC_HELP_STRING([--disable-dnsshuffle],[Disable DNS shufflinf]),
+AC_HELP_STRING([--disable-dnsshuffle],[Disable DNS shuffling]),
 [ case "$enableval" in
   no)
        AC_MSG_RESULT(no)
diff --git a/docs/ALTSVC.md b/docs/ALTSVC.md
index 48401415b..6a462bbbc 100644
--- a/docs/ALTSVC.md
+++ b/docs/ALTSVC.md
@@ -27,7 +27,7 @@ space separated fields.
 4. The ALPN id for the destination host
 5. The host name for the destination host
 6. The host number for the destination host
-7. The expiration date and time of this entry withing double quotes. The date 
format is "YYYYMMDD HH:MM:SS" and the time zone is GMT.
+7. The expiration date and time of this entry within double quotes. The date 
format is "YYYYMMDD HH:MM:SS" and the time zone is GMT.
 8. Boolean (1 or 0) if "persist" was set for this entry
 9. Integer priority value (not currently used)
 
diff --git a/docs/CURL-DISABLE.md b/docs/CURL-DISABLE.md
new file mode 100644
index 000000000..83436b473
--- /dev/null
+++ b/docs/CURL-DISABLE.md
@@ -0,0 +1,110 @@
+# Code defines to disable features and protocols
+
+## CURL_DISABLE_COOKIES
+
+Disable support for HTTP cookies.
+
+## CURL_DISABLE_CRYPTO_AUTH
+
+Disable support for authentication methods using crypto.
+
+## CURL_DISABLE_DICT
+
+Disable the DICT protocol
+
+## CURL_DISABLE_DOH
+
+Disable DNS-over-HTTPS
+
+## CURL_DISABLE_FILE
+
+Disable the FILE protocol
+
+## CURL_DISABLE_FTP
+
+Disable the FTP (and FTPS) protocol
+
+## CURL_DISABLE_GOPHER
+
+Disable the GOPHER protocol.
+
+## CURL_DISABLE_HTTP
+
+Disable the HTTP(S) protocols. Note that this then also disable HTTP proxy
+support.
+
+## CURL_DISABLE_HTTP_AUTH
+
+Disable support for all HTTP authentication methods.
+
+## CURL_DISABLE_IMAP
+
+Disable the IMAP(S) protocols.
+
+## CURL_DISABLE_LDAP
+
+Disable the LDAP(S) protocols.
+
+## CURL_DISABLE_LDAPS
+
+Disable the LDAPS protocol.
+
+## CURL_DISABLE_LIBCURL_OPTION
+
+Disable the --libcurl option from the curl tool.
+
+## CURL_DISABLE_MIME
+
+Disable MIME support.
+
+## CURL_DISABLE_NETRC
+
+Disable the netrc parser.
+
+## CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
+
+Disable the auto load config support in the OpenSSL backend.
+
+## CURL_DISABLE_PARSEDATE
+
+Disable date parsing
+
+## CURL_DISABLE_POP
+
+Disable the POP(S) protocols
+
+## CURL_DISABLE_PROGRESS_METER
+
+Disable the built-in progress meter
+
+## CURL_DISABLE_PROXY
+
+Disable support for proxies
+
+## CURL_DISABLE_RTSP
+
+Disable the RTSP protocol.
+
+## CURL_DISABLE_SHUFFLE_DNS
+
+Disable the shuffle DNS feature
+
+## CURL_DISABLE_SMB
+
+Disable the SMB(S) protocols
+
+## CURL_DISABLE_SMTP
+
+Disable the SMTP(S) protocols
+
+## CURL_DISABLE_TELNET
+
+Disable the TELNET protocol
+
+## CURL_DISABLE_TFTP
+
+Disable the TFTP protocol
+
+## CURL_DISABLE_VERBOSE_STRINGS
+
+Disable verbose strings and error messages.
diff --git a/docs/ESNI.md b/docs/ESNI.md
index eefb6662b..7feaa75ad 100644
--- a/docs/ESNI.md
+++ b/docs/ESNI.md
@@ -122,7 +122,7 @@ Limitations:
 
 ## References
 
-CloudFlare blog: [Encrypting SNI: Fixing One of the Core Internet 
Bugs][corebug]
+Cloudflare blog: [Encrypting SNI: Fixing One of the Core Internet 
Bugs][corebug]
 
 Cloudflare blog: [Encrypt it or lose it: how encrypted SNI works][esniworks]
 
diff --git a/docs/FAQ b/docs/FAQ
index 4136b9170..53f1c9e7a 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -447,9 +447,9 @@ FAQ
 
   curl can be built to use one of the following SSL alternatives: OpenSSL,
   libressl, BoringSSL, GnuTLS, wolfSSL, NSS, mbedTLS, MesaLink, Secure
-  Transport (native iOS/OS X), Schannel (native Windows) or GSKit (native IBM
-  i). They all have their pros and cons, and we try to maintain a comparison
-  of them here: https://curl.haxx.se/docs/ssl-compared.html
+  Transport (native iOS/OS X), Schannel (native Windows), GSKit (native IBM
+  i), or BearSSL. They all have their pros and cons, and we try to maintain a
+  comparison of them here: https://curl.haxx.se/docs/ssl-compared.html
 
   2.3 Where can I find a copy of LIBEAY32.DLL?
 
diff --git a/docs/HISTORY.md b/docs/HISTORY.md
index 30249071a..1e69f043f 100644
--- a/docs/HISTORY.md
+++ b/docs/HISTORY.md
@@ -218,6 +218,8 @@ November:
 
 March: security vulnerability: libcurl Arbitrary File Access
 
+April: added CMake support
+
 August: security vulnerability: libcurl embedded zero in cert name
 
 December: Added support for IMAP, POP3 and SMTP
@@ -344,3 +346,10 @@ April: added the cyassl backend (later renamed to WolfSSL)
     curl_easy_setopt() options:   261
     Public functions in libcurl:  80
     Contributors:                 1808
+
+2019
+----
+
+ August: the first HTTP/3 requests with curl.
+
+ September: 7.66.0 is released and the tool offers parallel downloads
diff --git a/docs/HTTP-COOKIES.md b/docs/HTTP-COOKIES.md
index 632cb4ebe..06790f8a7 100644
--- a/docs/HTTP-COOKIES.md
+++ b/docs/HTTP-COOKIES.md
@@ -24,7 +24,7 @@
   and in 2017, another update was
   [drafted](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-01)
   to deprecate modification of 'secure' cookies from non-secure origins. Both
-  of these drafs have been incorporated into a proposal to
+  of these drafts have been incorporated into a proposal to
   [replace](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02)
   RFC6265. Cookie prefixes and secure cookie modification protection has been
   implemented by curl.
diff --git a/docs/HTTP3.md b/docs/HTTP3.md
index 2dbd25688..c77f7743d 100644
--- a/docs/HTTP3.md
+++ b/docs/HTTP3.md
@@ -13,7 +13,7 @@ and libcurl.
 
 ## QUIC libraries
 
-QUIC libraries we're experiementing with:
+QUIC libraries we're experimenting with:
 
 [ngtcp2](https://github.com/ngtcp2/ngtcp2)
 
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 78d632c70..380f3b38e 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -120,6 +120,7 @@ libressl.
  - schannel: `--without-ssl --with-schannel`
  - secure transport: `--without-ssl --with-secure-transport`
  - MesaLink: `--without-ssl --with-mesalink`
+ - BearSSL: `--without-ssl --with-bearssl`
 
 # Windows
 
@@ -195,20 +196,8 @@ The configure utility, unfortunately, is not available for 
the Windows
 environment, therefore, you cannot use the various disable-protocol options of
 the configure utility on this platform.
 
-However, you can use the following defines to disable specific
-protocols:
-
- - `HTTP_ONLY`             disables all protocols except HTTP
- - `CURL_DISABLE_FTP`      disables FTP
- - `CURL_DISABLE_LDAP`     disables LDAP
- - `CURL_DISABLE_TELNET`   disables TELNET
- - `CURL_DISABLE_DICT`     disables DICT
- - `CURL_DISABLE_FILE`     disables FILE
- - `CURL_DISABLE_TFTP`     disables TFTP
- - `CURL_DISABLE_HTTP`     disables HTTP
- - `CURL_DISABLE_IMAP`     disables IMAP
- - `CURL_DISABLE_POP3`     disables POP3
- - `CURL_DISABLE_SMTP`     disables SMTP
+You can use specific defines to disable specific protocols and features. See
+[CURL-DISABLE.md](CURL-DISABLE-md) for the full list.
 
 If you want to set any of these defines you have the following options:
 
@@ -296,6 +285,47 @@ will run on cats as old as OS X 10.6 ("Snow Leopard") 
(using bash):
     ./configure --with-darwinssl
     make
 
+# Android
+
+When building curl for Android it's recommended to use a Linux environment
+since using curl's `configure` script is the easiest way to build curl
+for Android. Before you can build curl for Android, you need to install the
+Android NDK first. This can be done using the SDK Manager that is part of
+Android Studio. Once you have installed the Android NDK, you need to figure out
+where it has been installed and then set up some environment variables before
+launching `configure`. On macOS, those variables could look like this to 
compile
+for `aarch64` and API level 29:
+
+    export NDK=~/Library/Android/sdk/ndk/20.1.5948944
+    export HOST_TAG=darwin-x86_64
+    export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
+    export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
+    export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
+    export CC=$TOOLCHAIN/bin/aarch64-linux-android29-clang
+    export CXX=$TOOLCHAIN/bin/aarch64-linux-android29-clang++
+    export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
+    export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
+    export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
+
+When building on Linux or targeting other API levels or architectures, you need
+to adjust those variables accordingly. After that you can build curl like this:
+
+    ./configure --host aarch64-linux-android --with-pic --disable-shared
+
+Note that this won't give you SSL/TLS support. If you need SSL/TLS, you have
+to build curl against a SSL/TLS layer, e.g. OpenSSL, because it's impossible 
for
+curl to access Android's native SSL/TLS layer. To build curl for Android using
+OpenSSL, follow the OpenSSL build instructions and then install `libssl.a` and
+`libcrypto.a` to `$TOOLCHAIN/sysroot/usr/lib` and copy `include/openssl` to
+`$TOOLCHAIN/sysroot/usr/include`. Now you can build curl for Android using
+OpenSSL like this:
+    
+    ./configure --host aarch64-linux-android --with-pic --disable-shared 
--with-ssl="$TOOLCHAIN/sysroot/usr"
+
+Note, however, that you must target at least Android M (API level 23) or 
`configure`
+won't be able to detect OpenSSL since `stderr` (and the like) weren't defined
+before Android M.
+
 # Cross compile
 
 Download and unpack the curl package.
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index 5134e7367..5fd230f86 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -30,6 +30,7 @@ problems may have been fixed or changed somewhat since this 
was written!
  2.6 CURL_GLOBAL_SSL
  2.7 Client cert (MTLS) issues with Schannel
  2.8 Schannel disable CURLOPT_SSL_VERIFYPEER and verify hostname
+ 2.9 TLS session cache doesn't work with TFO
 
  3. Email protocols
  3.1 IMAP SEARCH ALL truncated response
@@ -102,6 +103,7 @@ problems may have been fixed or changed somewhat since this 
was written!
  12. LDAP and OpenLDAP
  12.1 OpenLDAP hangs after returning results
  12.2 LDAP on Windows does authentication wrong?
+ 12.3 LDAP on Windows doesn't work
 
  13. TCP/IP
  13.1 --interface for ipv6 binds to unusable IP address
@@ -255,6 +257,10 @@ problems may have been fixed or changed somewhat since 
this was written!
 
  https://github.com/curl/curl/issues/3284
 
+2.9 TLS session cache doesn't work with TFO
+
+ See https://github.com/curl/curl/issues/4301
+
 3. Email protocols
 
 3.1 IMAP SEARCH ALL truncated response
@@ -339,7 +345,7 @@ problems may have been fixed or changed somewhat since this 
was written!
 
 5.1 USE_UNIX_SOCKETS on Windows
 
- Due to incorrect CMake checks for the presense of the feature, it will never
+ Due to incorrect CMake checks for the presence of the feature, it will never
  be enabled for windows in a cmake build.
 
  See https://github.com/curl/curl/issues/4040
@@ -674,7 +680,8 @@ problems may have been fixed or changed somewhat since this 
was written!
  CURLINFO_LOCAL_PORT (and possibly a few other) fails when TCP Fast Open is
  enabled.
 
- See https://github.com/curl/curl/issues/1332
+ See https://github.com/curl/curl/issues/1332 and
+ https://github.com/curl/curl/issues/4296
 
 11.6 slow connect to localhost on Windows
 
@@ -728,6 +735,13 @@ problems may have been fixed or changed somewhat since 
this was written!
 
  https://github.com/curl/curl/issues/3116
 
+12.3 LDAP on Windows doesn't work
+
+ A simple curl command line getting "ldap://ldap.forumsys.com"; returns an
+ error that says "no memory" !
+
+ https://github.com/curl/curl/issues/4261
+
 13. TCP/IP
 
 13.1 --interface for ipv6 binds to unusable IP address
diff --git a/docs/LICENSE-MIXING.md b/docs/LICENSE-MIXING.md
index e4f6759e4..1083a2dcd 100644
--- a/docs/LICENSE-MIXING.md
+++ b/docs/LICENSE-MIXING.md
@@ -75,6 +75,11 @@ not have the announcement clause that collides with GPL.
  (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
  license as that.
 
+## BearSSL
+
+ (May be used for SSL/TLS support) Uses an MIT license that is very liberal
+ and imposes no restrictions on any other library or part you may link with.
+
 ## c-ares
 
  (Used for asynchronous name resolves) Uses an MIT license that is very
diff --git a/docs/MANUAL.md b/docs/MANUAL.md
index 80ab92a63..73ce57d44 100644
--- a/docs/MANUAL.md
+++ b/docs/MANUAL.md
@@ -701,7 +701,7 @@ Otherwise, curl will attempt to use a sensible TLS default 
version.
 ## Resuming File Transfers
 
 To continue a file transfer where it was previously aborted, curl supports
-esume on HTTP(S) downloads as well as FTP uploads and downloads.
+resume on HTTP(S) downloads as well as FTP uploads and downloads.
 
 Continue downloading a document:
 
diff --git a/docs/Makefile.am b/docs/Makefile.am
index fccdd8784..1f9f83911 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -47,6 +47,7 @@ EXTRA_DIST =                                    \
  CODE_OF_CONDUCT.md                             \
  CODE_STYLE.md                                  \
  CONTRIBUTE.md                                  \
+ CURL-DISABLE.md                                \
  DEPRECATE.md                                   \
  ESNI.md                                        \
  EXPERIMENTAL.md                                \
diff --git a/docs/PARALLEL-TRANSFERS.md b/docs/PARALLEL-TRANSFERS.md
index d3b38aee1..da688ea05 100644
--- a/docs/PARALLEL-TRANSFERS.md
+++ b/docs/PARALLEL-TRANSFERS.md
@@ -18,7 +18,7 @@ completely different than the regular one used for each 
single transfer.
 
  o percent download (if known, which means *all* transfers need to have a
    known size)
- o precent upload (if known, with the same caveat as for download)
+ o percent upload (if known, with the same caveat as for download)
  o total amount of downloaded data
  o total amount of uploaded data
  o number of transfers to perform
diff --git a/docs/TODO b/docs/TODO
index 42d37c1bc..6f4919c23 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -20,6 +20,7 @@
  1.1 TFO support on Windows
  1.2 Consult %APPDATA% also for .netrc
  1.3 struct lifreq
+ 1.4 alt-svc sharing
  1.5 get rid of PATH_MAX
  1.7 Support HTTP/2 for HTTP(S) proxies
  1.8 CURLOPT_RESOLVE for any port number
@@ -157,6 +158,7 @@
  20.5 Add support for concurrent connections
  20.6 Use the RFC6265 test suite
  20.7 Support LD_PRELOAD on macOS
+ 20.8 Run web-platform-tests url tests
 
  21. Next SONAME bump
  21.1 http-style HEAD output for FTP
@@ -195,6 +197,13 @@
  SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
  To support IPv6 interface addresses for network interfaces properly.
 
+1.4 alt-svc sharing
+
+ The share interface could benefit from allowing the alt-svc cache to be
+ possible to share between easy handles.
+
+ See https://github.com/curl/curl/issues/4476
+
 1.5 get rid of PATH_MAX
 
  Having code use and rely on PATH_MAX is not nice:
@@ -804,7 +813,7 @@ that doesn't exist on the server, just like 
--ftp-create-dirs.
 
  The SFTP code in libcurl checks the file size *before* a transfer starts and
  then proceeds to transfer exactly that amount of data. If the remote file
- grows while the tranfer is in progress libcurl won't notice and will not
+ grows while the transfer is in progress libcurl won't notice and will not
  adapt. The OpenSSH SFTP command line tool does and libcurl could also just
  attempt to download more to see if there is more to get...
 
@@ -1045,6 +1054,15 @@ that doesn't exist on the server, just like 
--ftp-create-dirs.
  properly. Look into making the preload support in runtests.pl portable such
  that it uses DYLD_INSERT_LIBRARIES on macOS.
 
+20.8 Run web-platform-tests url tests
+
+ Run web-platform-tests url tests and compare results with browsers on wpt.fyi
+
+ It would help us find issues to fix and help us document where our parser
+ differs from the WHATWG URL spec parsers.
+
+ See https://github.com/curl/curl/issues/4477
+
 21. Next SONAME bump
 
 21.1 http-style HEAD output for FTP
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc
index c90e9c5fb..829551ff6 100644
--- a/docs/cmdline-opts/Makefile.inc
+++ b/docs/cmdline-opts/Makefile.inc
@@ -38,6 +38,8 @@ DPAGES =                                      \
   dump-header.d                                        \
   egd-file.d                                   \
   engine.d                                     \
+  etag-save.d                   \
+  etag-compare.d                \
   expect100-timeout.d                          \
   fail-early.d                                 \
   fail.d                                       \
@@ -103,9 +105,10 @@ DPAGES =                                   \
   ntlm.d ntlm-wb.d                             \
   oauth2-bearer.d                              \
   output.d                                      \
+  parallel-immediate.d                          \
+  parallel-max.d                                \
   parallel.d                                    \
   pass.d                                       \
-  parallel-max.d                                \
   path-as-is.d                                 \
   pinnedpubkey.d                               \
   post301.d                                    \
diff --git a/docs/cmdline-opts/alt-svc.d b/docs/cmdline-opts/alt-svc.d
index ba2ded11c..df10bf257 100644
--- a/docs/cmdline-opts/alt-svc.d
+++ b/docs/cmdline-opts/alt-svc.d
@@ -4,7 +4,7 @@ Protocols: HTTPS
 Help: Enable alt-svc with this cache file
 Added: 7.64.1
 ---
-WARNING: this option is experiemental. Do not use in production.
+WARNING: this option is experimental. Do not use in production.
 
 This option enables the alt-svc parser in curl. If the file name points to an
 existing alt-svc cache file, that will be used. After a completed transfer,
diff --git a/docs/cmdline-opts/etag-compare.d b/docs/cmdline-opts/etag-compare.d
new file mode 100644
index 000000000..1a698a8ff
--- /dev/null
+++ b/docs/cmdline-opts/etag-compare.d
@@ -0,0 +1,18 @@
+Long: etag-compare
+Arg: <file>
+Help: Pass an ETag from a file as a custom header
+Protocols: HTTP
+Added: 7.68.0
+---
+This option makes a conditional HTTP request for the specific
+ETag read from the given file by sending a custom If-None-Match
+header using the extracted ETag.
+
+For correct results, make sure that specified file contains only a single
+line with a desired ETag. An empty file is parsed as an empty ETag.
+
+Use the option --etag-save to first save the ETag from a response, and
+then use this option to compare using the saved ETag in a subsequent request.
+
+\fCOMPARISON\fP: There are 2 types of comparison or ETags, Weak and Strong.
+This option expects, and uses a strong comparison.
diff --git a/docs/cmdline-opts/etag-save.d b/docs/cmdline-opts/etag-save.d
new file mode 100644
index 000000000..214723ff5
--- /dev/null
+++ b/docs/cmdline-opts/etag-save.d
@@ -0,0 +1,16 @@
+Long: etag-save
+Arg: <file>
+Help: Parse ETag from a request and save it to a file
+Protocols: HTTP
+Added: 7.68.0
+---
+This option saves an HTTP ETag to the specified file. Etag is
+usually part of headers returned by a request. When server sends an
+ETag, it must be enveloped by a double quote. This option extracts the
+ETag without the double quotes and saves it into the <file>.
+
+A server can send a week ETag which is prefixed by "W/". This identifier
+is not considered, and only relevant ETag between quotation marks is parsed.
+
+It an ETag wasn't send by the server or it cannot be parsed, and empty
+file is created.
diff --git a/docs/cmdline-opts/http3.d b/docs/cmdline-opts/http3.d
index ca85e3a64..8265937a3 100644
--- a/docs/cmdline-opts/http3.d
+++ b/docs/cmdline-opts/http3.d
@@ -8,7 +8,7 @@ Help: Use HTTP v3
 See-also: http1.1 http2
 ---
 
-WARNING: this option is experiemental. Do not use in production.
+WARNING: this option is experimental. Do not use in production.
 
 Tells curl to use HTTP version 3 directly to the host and port number used in
 the URL. A normal HTTP/3 transaction will be done to a host and then get
diff --git a/docs/cmdline-opts/parallel-immediate.d 
b/docs/cmdline-opts/parallel-immediate.d
new file mode 100644
index 000000000..343931085
--- /dev/null
+++ b/docs/cmdline-opts/parallel-immediate.d
@@ -0,0 +1,9 @@
+Long: parallel-immediate
+Help: Do not wait for multiplexing (with --parallel)
+Added: 7.68.0
+See-also: parallel parallel-max
+---
+When doing parallel transfers, this option will instruct curl that it should
+rather prefer opening up more connections in parallel at once rather than
+waiting to see if new transfers can be added as multiplexed streams on another
+connection.
diff --git a/docs/cmdline-opts/tlspassword.d b/docs/cmdline-opts/tlspassword.d
index 234a1168c..b2e65362e 100644
--- a/docs/cmdline-opts/tlspassword.d
+++ b/docs/cmdline-opts/tlspassword.d
@@ -4,3 +4,5 @@ Added: 7.21.4
 ---
 Set password for use with the TLS authentication method specified with
 --tlsauthtype. Requires that --tlsuser also be set.
+
+This doesn't work with TLS 1.3.
diff --git a/docs/cmdline-opts/tlsuser.d b/docs/cmdline-opts/tlsuser.d
index 72f1e1667..7192b9f1d 100644
--- a/docs/cmdline-opts/tlsuser.d
+++ b/docs/cmdline-opts/tlsuser.d
@@ -5,3 +5,5 @@ Added: 7.21.4
 ---
 Set username for use with the TLS authentication method specified with
 --tlsauthtype. Requires that --tlspassword also is set.
+
+This doesn't work with TLS 1.3.
diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc
index f03fcf2f0..b588b5fee 100644
--- a/docs/examples/Makefile.inc
+++ b/docs/examples/Makefile.inc
@@ -36,7 +36,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface 
debug fileupload \
   ftpuploadresume sslbackend postit2-formadd multi-formadd                 \
   shared-connection-cache sftpuploadresume http2-pushinmemory parseurl     \
   urlapi imap-authzid pop3-authzid smtp-authzid http3 altsvc               \
-  http3-present
+  http3-present multi-poll
 
 # These examples require external dependencies that may not be commonly
 # available on POSIX systems, so don't bother attempting to compile them here.
diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c
index b70a43385..908f59997 100644
--- a/docs/examples/anyauthput.c
+++ b/docs/examples/anyauthput.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/chkspeed.c b/docs/examples/chkspeed.c
index 7a53ff3a4..70964c70d 100644
--- a/docs/examples/chkspeed.c
+++ b/docs/examples/chkspeed.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/crawler.c b/docs/examples/crawler.c
index ec3c853fc..a16256d39 100644
--- a/docs/examples/crawler.c
+++ b/docs/examples/crawler.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Web crawler based on curl and libxml2.
- * Copyright (C) 2018 Jeroen Ooms <address@hidden>
+ * Copyright (C) 2018 - 2019 Jeroen Ooms <address@hidden>
  * License: MIT
  *
  * To compile:
diff --git a/docs/examples/curlgtk.c b/docs/examples/curlgtk.c
index 77352607f..62e894c8d 100644
--- a/docs/examples/curlgtk.c
+++ b/docs/examples/curlgtk.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- *  Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft
+ *  Copyright (c) 2000 - 2019 David Odin (aka DindinX) for MandrakeSoft
  */
 /* <DESC>
  * use the libcurl in a gtk-threaded application
diff --git a/docs/examples/curlx.c b/docs/examples/curlx.c
index a4d59427a..6a3645621 100644
--- a/docs/examples/curlx.c
+++ b/docs/examples/curlx.c
@@ -15,7 +15,7 @@
  */
 
 /*
- * Copyright (c) 2003 The OpenEvidence Project.  All rights reserved.
+ * Copyright (c) 2003 - 2019 The OpenEvidence Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/docs/examples/fileupload.c b/docs/examples/fileupload.c
index 71692a524..096acb0b1 100644
--- a/docs/examples/fileupload.c
+++ b/docs/examples/fileupload.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/fopen.c b/docs/examples/fopen.c
index 16aa555fe..9eb0fbae9 100644
--- a/docs/examples/fopen.c
+++ b/docs/examples/fopen.c
@@ -13,7 +13,7 @@
  * See the main() function at the bottom that shows an app that retrieves from
  * a specified url using fgets() and fread() and saves as two output files.
  *
- * Copyright (c) 2003, 2017 Simtec Electronics
+ * Copyright (c) 2003 - 2019 Simtec Electronics
  *
  * Re-implemented by Vincent Sanders <address@hidden> with extensive
  * reference to original curl example code
diff --git a/docs/examples/ftpupload.c b/docs/examples/ftpupload.c
index 3871f514a..ff4dbae32 100644
--- a/docs/examples/ftpupload.c
+++ b/docs/examples/ftpupload.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/href_extractor.c b/docs/examples/href_extractor.c
index 18c8ffdb2..2ec062cfb 100644
--- a/docs/examples/href_extractor.c
+++ b/docs/examples/href_extractor.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/http-post.c b/docs/examples/http-post.c
index bbcd5eb23..e09f6de3e 100644
--- a/docs/examples/http-post.c
+++ b/docs/examples/http-post.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/https.c b/docs/examples/https.c
index 342854467..7e6116499 100644
--- a/docs/examples/https.c
+++ b/docs/examples/https.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/imap-list.c b/docs/examples/imap-list.c
index cdbb89fd3..236d3101f 100644
--- a/docs/examples/imap-list.c
+++ b/docs/examples/imap-list.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/imap-lsub.c b/docs/examples/imap-lsub.c
index 3ad6157a0..ed150a0b6 100644
--- a/docs/examples/imap-lsub.c
+++ b/docs/examples/imap-lsub.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/imap-noop.c b/docs/examples/imap-noop.c
index 098386657..36aec963e 100644
--- a/docs/examples/imap-noop.c
+++ b/docs/examples/imap-noop.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/imap-store.c b/docs/examples/imap-store.c
index 8d3fba50d..eba5f72d4 100644
--- a/docs/examples/imap-store.c
+++ b/docs/examples/imap-store.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/multi-single.c b/docs/examples/multi-poll.c
similarity index 55%
copy from docs/examples/multi-single.c
copy to docs/examples/multi-poll.c
index 6d63c2d23..34e2ebc4b 100644
--- a/docs/examples/multi-single.c
+++ b/docs/examples/multi-poll.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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,7 +20,7 @@
  *
  ***************************************************************************/
 /* <DESC>
- * using the multi interface to do a single download
+ * single download with the multi interface's curl_multi_poll
  * </DESC>
  */
 
@@ -34,77 +34,42 @@
 /* curl stuff */
 #include <gnurl/curl.h>
 
-#ifdef _WIN32
-#define WAITMS(x) Sleep(x)
-#else
-/* Portable sleep for platforms other than Windows. */
-#define WAITMS(x)                               \
-  struct timeval wait = { 0, (x) * 1000 };      \
-  (void)select(0, NULL, NULL, NULL, &wait);
-#endif
-
-/*
- * Simply download a HTTP file.
- */
 int main(void)
 {
   CURL *http_handle;
   CURLM *multi_handle;
-
-  int still_running = 0; /* keep number of running handles */
-  int repeats = 0;
+  int still_running = 1; /* keep number of running handles */
 
   curl_global_init(CURL_GLOBAL_DEFAULT);
 
   http_handle = curl_easy_init();
 
-  /* set the options (I left out a few, you'll get the point anyway) */
   curl_easy_setopt(http_handle, CURLOPT_URL, "https://www.example.com/";);
 
-  /* init a multi stack */
   multi_handle = curl_multi_init();
 
-  /* add the individual transfers */
   curl_multi_add_handle(multi_handle, http_handle);
 
-  /* we start some action by calling perform right away */
-  curl_multi_perform(multi_handle, &still_running);
-
   while(still_running) {
-    CURLMcode mc; /* curl_multi_wait() return code */
+    CURLMcode mc; /* curl_multi_poll() return code */
     int numfds;
 
-    /* wait for activity, timeout or "nothing" */
-    mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
+    /* we start some action by calling perform right away */
+    mc = curl_multi_perform(multi_handle, &still_running);
+
+    if(still_running)
+      /* wait for activity, timeout or "nothing" */
+      mc = curl_multi_poll(multi_handle, NULL, 0, 1000, &numfds);
 
     if(mc != CURLM_OK) {
       fprintf(stderr, "curl_multi_wait() failed, code %d.\n", mc);
       break;
     }
-
-    /* 'numfds' being zero means either a timeout or no file descriptors to
-       wait for. Try timeout on first occurrence, then assume no file
-       descriptors and no file descriptors to wait for means wait for 100
-       milliseconds. */
-
-    if(!numfds) {
-      repeats++; /* count number of repeated zero numfds */
-      if(repeats > 1) {
-        WAITMS(100); /* sleep 100 milliseconds */
-      }
-    }
-    else
-      repeats = 0;
-
-    curl_multi_perform(multi_handle, &still_running);
   }
 
   curl_multi_remove_handle(multi_handle, http_handle);
-
   curl_easy_cleanup(http_handle);
-
   curl_multi_cleanup(multi_handle);
-
   curl_global_cleanup();
 
   return 0;
diff --git a/docs/examples/pop3-dele.c b/docs/examples/pop3-dele.c
index e316e1bb0..45dbaa0f8 100644
--- a/docs/examples/pop3-dele.c
+++ b/docs/examples/pop3-dele.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/pop3-list.c b/docs/examples/pop3-list.c
index 3b7ed9e5c..39b38a4d1 100644
--- a/docs/examples/pop3-list.c
+++ b/docs/examples/pop3-list.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/pop3-noop.c b/docs/examples/pop3-noop.c
index 867ac3828..f0675e068 100644
--- a/docs/examples/pop3-noop.c
+++ b/docs/examples/pop3-noop.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/pop3-retr.c b/docs/examples/pop3-retr.c
index 98ab5321c..308a82fcb 100644
--- a/docs/examples/pop3-retr.c
+++ b/docs/examples/pop3-retr.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/pop3-ssl.c b/docs/examples/pop3-ssl.c
index 20389d732..67aa647d3 100644
--- a/docs/examples/pop3-ssl.c
+++ b/docs/examples/pop3-ssl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/pop3-stat.c b/docs/examples/pop3-stat.c
index d6dbe4b23..62832e83e 100644
--- a/docs/examples/pop3-stat.c
+++ b/docs/examples/pop3-stat.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/pop3-uidl.c b/docs/examples/pop3-uidl.c
index 7d87508d5..9f6828c60 100644
--- a/docs/examples/pop3-uidl.c
+++ b/docs/examples/pop3-uidl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/rtsp.c b/docs/examples/rtsp.c
index bf4a219aa..e3fdc905b 100644
--- a/docs/examples/rtsp.c
+++ b/docs/examples/rtsp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Jim Hollinger
+ * Copyright (c) 2011 - 2019, Jim Hollinger
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/docs/examples/sessioninfo.c b/docs/examples/sessioninfo.c
index b1dd94ed7..3c0b143e8 100644
--- a/docs/examples/sessioninfo.c
+++ b/docs/examples/sessioninfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/smtp-expn.c b/docs/examples/smtp-expn.c
index 88383c669..2673ea2f6 100644
--- a/docs/examples/smtp-expn.c
+++ b/docs/examples/smtp-expn.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/smtp-ssl.c b/docs/examples/smtp-ssl.c
index dff450eea..fcb692326 100644
--- a/docs/examples/smtp-ssl.c
+++ b/docs/examples/smtp-ssl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/smtp-tls.c b/docs/examples/smtp-tls.c
index ffc0e504b..92ccec1ac 100644
--- a/docs/examples/smtp-tls.c
+++ b/docs/examples/smtp-tls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/smtp-vrfy.c b/docs/examples/smtp-vrfy.c
index 4f99d95be..e8c494423 100644
--- a/docs/examples/smtp-vrfy.c
+++ b/docs/examples/smtp-vrfy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/examples/usercertinmem.c b/docs/examples/usercertinmem.c
index c005f28b8..92f9655e2 100644
--- a/docs/examples/usercertinmem.c
+++ b/docs/examples/usercertinmem.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2013 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2013 - 2019, Daniel Stenberg, <address@hidden>, 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/docs/libcurl/Makefile.inc b/docs/libcurl/Makefile.inc
index 380c153b8..e1185e729 100644
--- a/docs/libcurl/Makefile.inc
+++ b/docs/libcurl/Makefile.inc
@@ -1,84 +1,85 @@
 # Shared between Makefile.am and CMakeLists.txt
 
 man_MANS = \
- gnurl_easy_cleanup.3 \
- gnurl_easy_duphandle.3 \
- gnurl_easy_escape.3 \
- gnurl_easy_getinfo.3 \
- gnurl_easy_init.3 \
- gnurl_easy_pause.3 \
- gnurl_easy_perform.3 \
- gnurl_easy_recv.3 \
- gnurl_easy_reset.3 \
- gnurl_easy_send.3 \
- gnurl_easy_setopt.3 \
- gnurl_easy_strerror.3 \
- gnurl_easy_unescape.3 \
- gnurl_easy_upkeep.3 \
- gnurl_escape.3 \
- gnurl_formadd.3 \
- gnurl_formfree.3 \
- gnurl_formget.3 \
- gnurl_free.3 \
- gnurl_getdate.3 \
- gnurl_getenv.3 \
- gnurl_global_cleanup.3 \
- gnurl_global_init.3 \
- gnurl_global_init_mem.3 \
- gnurl_global_sslset.3 \
- gnurl_mime_addpart.3 \
- gnurl_mime_data.3 \
- gnurl_mime_data_cb.3 \
- gnurl_mime_encoder.3 \
- gnurl_mime_filedata.3 \
- gnurl_mime_filename.3 \
- gnurl_mime_free.3 \
- gnurl_mime_headers.3 \
- gnurl_mime_init.3 \
- gnurl_mime_name.3 \
- gnurl_mime_subparts.3 \
- gnurl_mime_type.3 \
- gnurl_mprintf.3 \
- gnurl_multi_add_handle.3 \
- gnurl_multi_assign.3 \
- gnurl_multi_cleanup.3 \
- gnurl_multi_fdset.3 \
- gnurl_multi_info_read.3 \
- gnurl_multi_init.3 \
- gnurl_multi_perform.3 \
- gnurl_multi_poll.3 \
- gnurl_multi_remove_handle.3 \
- gnurl_multi_setopt.3 \
- gnurl_multi_socket.3 \
- gnurl_multi_socket_action.3 \
- gnurl_multi_socket_all.3 \
- gnurl_multi_strerror.3 \
- gnurl_multi_timeout.3 \
- gnurl_multi_wait.3 \
- gnurl_share_cleanup.3 \
- gnurl_share_init.3 \
- gnurl_share_setopt.3 \
- gnurl_share_strerror.3 \
- gnurl_slist_append.3 \
- gnurl_slist_free_all.3 \
- gnurl_strequal.3 \
- gnurl_strnequal.3 \
- gnurl_unescape.3 \
- gnurl_url.3 \
- gnurl_url_cleanup.3 \
- gnurl_url_dup.3 \
- gnurl_url_get.3 \
- gnurl_url_set.3 \
- gnurl_version.3 \
- gnurl_version_info.3 \
- libgnurl-easy.3 \
- libgnurl-env.3 \
- libgnurl-errors.3 \
- libgnurl-multi.3 \
- libgnurl-security.3 \
- libgnurl-share.3 \
- libgnurl-symbols.3 \
- libgnurl-thread.3 \
- libgnurl-tutorial.3 \
- libgnurl-url.3 \
- libgnurl.3
+ curl_easy_cleanup.3 \
+ curl_easy_duphandle.3 \
+ curl_easy_escape.3 \
+ curl_easy_getinfo.3 \
+ curl_easy_init.3 \
+ curl_easy_pause.3 \
+ curl_easy_perform.3 \
+ curl_easy_recv.3 \
+ curl_easy_reset.3 \
+ curl_easy_send.3 \
+ curl_easy_setopt.3 \
+ curl_easy_strerror.3 \
+ curl_easy_unescape.3 \
+ curl_easy_upkeep.3 \
+ curl_escape.3 \
+ curl_formadd.3 \
+ curl_formfree.3 \
+ curl_formget.3 \
+ curl_free.3 \
+ curl_getdate.3 \
+ curl_getenv.3 \
+ curl_global_cleanup.3 \
+ curl_global_init.3 \
+ curl_global_init_mem.3 \
+ curl_global_sslset.3 \
+ curl_mime_addpart.3 \
+ curl_mime_data.3 \
+ curl_mime_data_cb.3 \
+ curl_mime_encoder.3 \
+ curl_mime_filedata.3 \
+ curl_mime_filename.3 \
+ curl_mime_free.3 \
+ curl_mime_headers.3 \
+ curl_mime_init.3 \
+ curl_mime_name.3 \
+ curl_mime_subparts.3 \
+ curl_mime_type.3 \
+ curl_mprintf.3 \
+ curl_multi_add_handle.3 \
+ curl_multi_assign.3 \
+ curl_multi_cleanup.3 \
+ curl_multi_fdset.3 \
+ curl_multi_info_read.3 \
+ curl_multi_init.3 \
+ curl_multi_perform.3 \
+ curl_multi_poll.3 \
+ curl_multi_remove_handle.3 \
+ curl_multi_setopt.3 \
+ curl_multi_socket.3 \
+ curl_multi_socket_action.3 \
+ curl_multi_socket_all.3 \
+ curl_multi_strerror.3 \
+ curl_multi_timeout.3 \
+ curl_multi_wakeup.3 \
+ curl_multi_wait.3 \
+ curl_share_cleanup.3 \
+ curl_share_init.3 \
+ curl_share_setopt.3 \
+ curl_share_strerror.3 \
+ curl_slist_append.3 \
+ curl_slist_free_all.3 \
+ curl_strequal.3 \
+ curl_strnequal.3 \
+ curl_unescape.3 \
+ curl_url.3 \
+ curl_url_cleanup.3 \
+ curl_url_dup.3 \
+ curl_url_get.3 \
+ curl_url_set.3 \
+ curl_version.3 \
+ curl_version_info.3 \
+ libcurl-easy.3 \
+ libcurl-env.3 \
+ libcurl-errors.3 \
+ libcurl-multi.3 \
+ libcurl-security.3 \
+ libcurl-share.3 \
+ libcurl-symbols.3 \
+ libcurl-thread.3 \
+ libcurl-tutorial.3 \
+ libcurl-url.3 \
+ libcurl.3
diff --git a/docs/libcurl/gnurl_global_sslset.3 
b/docs/libcurl/gnurl_global_sslset.3
index c9f5a4027..a631d1893 100644
--- a/docs/libcurl/gnurl_global_sslset.3
+++ b/docs/libcurl/gnurl_global_sslset.3
@@ -43,7 +43,8 @@ typedef enum {
   CURLSSLBACKEND_DARWINSSL = 9,
   CURLSSLBACKEND_AXTLS = 10, /* deprecated */
   CURLSSLBACKEND_MBEDTLS = 11,
-  CURLSSLBACKEND_MESALINK = 12
+  CURLSSLBACKEND_MESALINK = 12,
+  CURLSSLBACKEND_BEARSSL = 13
 } curl_sslbackend;
 
 .B "CURLsslset curl_global_sslset(curl_sslbackend " id,
diff --git a/docs/libcurl/gnurl_multi_poll.3 b/docs/libcurl/gnurl_multi_poll.3
index d532dd6b2..adab68d5e 100644
--- a/docs/libcurl/gnurl_multi_poll.3
+++ b/docs/libcurl/gnurl_multi_poll.3
@@ -48,10 +48,16 @@ total number of file descriptors on which interesting 
events occurred. This
 number can include both libcurl internal descriptors as well as descriptors
 provided in \fIextra_fds\fP.
 
+The \fIcurl_multi_wakeup(3)\fP function can be used from another thread to
+wake up this function and return faster. This is one of the details
+that makes this function different than \fIcurl_multi_wait(3)\fP which cannot
+be woken up this way.
+
 If no extra file descriptors are provided and libcurl has no file descriptor
 to offer to wait for, this function will instead wait during \fItimeout_ms\fP
 milliseconds (or shorter if an internal timer indicates so). This is the
-detail that makes this function different than \fIcurl_multi_wait(3)\fP.
+other detail that makes this function different than
+\fIcurl_multi_wait(3)\fP.
 
 This function is encouraged to be used instead of select(3) when using the
 multi interface to allow applications to easier circumvent the common problem
@@ -107,4 +113,5 @@ CURLMcode type, general libcurl multi interface error code. 
See
 .SH AVAILABILITY
 This function was added in libcurl 7.66.0.
 .SH "SEE ALSO"
-.BR curl_multi_fdset "(3), " curl_multi_perform "(3), " curl_multi_wait "(3)"
+.BR curl_multi_fdset "(3), " curl_multi_perform "(3), "
+.BR curl_multi_wait "(3), " curl_multi_wakeup "(3)"
diff --git a/docs/libcurl/gnurl_multi_wait.3 b/docs/libcurl/gnurl_multi_wait.3
index 34d7c0411..21c0842b4 100644
--- a/docs/libcurl/gnurl_multi_wait.3
+++ b/docs/libcurl/gnurl_multi_wait.3
@@ -49,7 +49,8 @@ number can include both libcurl internal descriptors as well 
as descriptors
 provided in \fIextra_fds\fP.
 
 If no extra file descriptors are provided and libcurl has no file descriptor
-to offer to wait for, this function will return immediately.
+to offer to wait for, this function will return immediately. (Try
+\fIcurl_multi_poll(3)\fP instead if you rather avoid this behavior.)
 
 This function is encouraged to be used instead of select(3) when using the
 multi interface to allow applications to easier circumvent the common problem
@@ -119,4 +120,4 @@ CURLMcode type, general libcurl multi interface error code. 
See
 .SH AVAILABILITY
 This function was added in libcurl 7.28.0.
 .SH "SEE ALSO"
-.BR curl_multi_fdset "(3), " curl_multi_perform "(3)"
+.BR curl_multi_fdset "(3), " curl_multi_perform "(3)", curl_multi_poll "(3) ",
diff --git a/docs/libcurl/gnurl_multi_wakeup.3 
b/docs/libcurl/gnurl_multi_wakeup.3
new file mode 100644
index 000000000..c47f85549
--- /dev/null
+++ b/docs/libcurl/gnurl_multi_wakeup.3
@@ -0,0 +1,86 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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.
+.\" *
+.\" **************************************************************************
+.TH gnurl_multi_wakeup 3 "17 Nov 2019" "libcurl 7.68.0" "libgnurl Manual"
+.SH NAME
+curl_multi_wakeup - wakes up a sleeping curl_multi_poll call
+.SH SYNOPSIS
+#include <gnurl/curl.h>
+
+CURLMcode curl_multi_wakeup(CURLM *multi_handle);
+.ad
+.SH DESCRIPTION
+This function can be called from any thread and it wakes up a
+sleeping \fIcurl_multi_poll(3)\fP call that is currently (or will be)
+waiting for activity or a timeout.
+
+If the function is called when there is no \fIcurl_multi_poll(3)\fP call,
+it will cause the next call to return immediately.
+
+Calling this function only guarantees to wake up the current (or the next
+if there is no current) \fIcurl_multi_poll(3)\fP call, which means it is
+possible that multiple calls to this function will wake up the same waiting
+operation.
+
+This function has no effect on \fIcurl_multi_wait(3)\fP calls.
+.SH RETURN VALUE
+CURLMcode type, general libcurl multi interface error code.
+.SH AVAILABILITY
+Added in 7.68.0
+.SH EXAMPLE
+.nf
+CURL *easy_handle;
+CURLM *multi_handle;
+
+/* add the individual easy handle */
+curl_multi_add_handle(multi_handle, easy_handle);
+
+/* this is thread 1 */
+do {
+  CURLMcode mc;
+  int numfds;
+
+  mc = curl_multi_perform(multi_handle, &still_running);
+
+  if(mc == CURLM_OK) {
+    /* wait for activity, timeout or wakeup */
+    mc = curl_multi_poll(multi_handle, NULL, 0, 10000, &numfds);
+  }
+
+  if(time_to_die())
+    exit(1);
+
+} while(still_running);
+
+curl_multi_remove_handle(multi_handle, easy_handle);
+
+/* this is thread 2 */
+
+if(something makes us decide to stop thread 1) {
+
+  set_something_to_signal_thread_1_to_exit();
+
+  curl_multi_wakeup(multi_handle);
+}
+
+.fi
+.SH "SEE ALSO"
+.BR curl_multi_poll "(3), " curl_multi_wait "(3)"
diff --git a/docs/libcurl/libgnurl-errors.3 b/docs/libcurl/libgnurl-errors.3
index f3c714aab..0305af43e 100644
--- a/docs/libcurl/libgnurl-errors.3
+++ b/docs/libcurl/libgnurl-errors.3
@@ -59,9 +59,9 @@ Couldn't resolve proxy. The given proxy host could not be 
resolved.
 Couldn't resolve host. The given remote host was not resolved.
 .IP "CURLE_COULDNT_CONNECT (7)"
 Failed to connect() to host or proxy.
-.IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)"
-The server sent data libcurl couldn't parse. This error code is used for more
-than just FTP and is aliased as \fICURLE_WEIRD_SERVER_REPLY\fP since 7.51.0.
+.IP "CURLE_WEIRD_SERVER_REPLY (8)"
+The server sent data libcurl couldn't parse. This error code was known as as
+\fICURLE_FTP_WEIRD_SERVER_REPLY\fP before 7.51.0.
 .IP "CURLE_REMOTE_ACCESS_DENIED (9)"
 We were denied access to the resource given in the URL.  For FTP, this occurs
 while trying to change to the remote directory.
@@ -256,6 +256,9 @@ Stream error in the HTTP/2 framing layer.
 An API function was called from inside a callback.
 .IP "CURLE_AUTH_ERROR (94)"
 An authentication function returned an error.
+.IP "CURLE_HTTP3 (95)"
+A problem was detected in the HTTP/3 layer. This is somewhat generic and can
+be one out of several problems, see the error buffer for details.
 .IP "CURLE_OBSOLETE*"
 These error codes will never be returned. They were used in an old libcurl
 version and are currently unused.
@@ -268,6 +271,9 @@ This is not really an error. It means you should call
 between. Before version 7.20.0 this could be returned by
 \fIcurl_multi_perform(3)\fP, but in later versions this return code is never
 used.
+.IP "CURLM_CALL_MULTI_SOCKET (-1)"
+An alias for CURLM_CALL_MULTI_PERFORM. Never returned by modern libcurl
+versions.
 .IP "CURLM_OK (0)"
 Things are fine.
 .IP "CURLM_BAD_HANDLE (1)"
@@ -291,6 +297,8 @@ An easy handle already added to a multi handle was 
attempted to get added a
 second time. (Added in 7.32.1)
 .IP "CURLM_RECURSIVE_API_CALL (8)"
 An API function was called from inside a callback.
+.IP "CURLM_WAKEUP_FAILURE (9)"
+Wakeup is unavailable or failed.
 .SH "CURLSHcode"
 The "share" interface will return a CURLSHcode to indicate when an error has
 occurred.  Also consider \fIcurl_share_strerror(3)\fP.
diff --git a/docs/libcurl/libgnurl-multi.3 b/docs/libcurl/libgnurl-multi.3
index 5d7c27b95..4674abdce 100644
--- a/docs/libcurl/libgnurl-multi.3
+++ b/docs/libcurl/libgnurl-multi.3
@@ -85,7 +85,7 @@ returns back to the calling application.
 
 Your application extracts info from libcurl about when it would like to get
 invoked to transfer data or do other work. The most convenient way is to use
-\fIcurl_multi_wait(3)\fP that will help you wait until the application should
+\fIcurl_multi_poll(3)\fP that will help you wait until the application should
 call libcurl again. The older API to accomplish the same thing is
 \fIcurl_multi_fdset(3)\fP that extracts fd_sets from libcurl to use in
 select() or poll() calls in order to get to know when the transfers in the
diff --git a/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3
index 64da37724..1197f8170 100644
--- a/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -29,8 +29,6 @@ CURLOPT_OPENSOCKETFUNCTION \- set callback for opening sockets
 
 typedef enum  {
   CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
-  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
-  CURLSOCKTYPE_LAST    /* never use */
 } curlsocktype;
 
 struct curl_sockaddr {
@@ -52,10 +50,9 @@ shown above.
 
 This callback function gets called by libcurl instead of the \fIsocket(2)\fP
 call. The callback's \fIpurpose\fP argument identifies the exact purpose for
-this particular socket: \fICURLSOCKTYPE_IPCXN\fP is for IP based connections
-and \fICURLSOCKTYPE_ACCEPT\fP is for sockets created after accept() - such as
-when doing active FTP. Future versions of libcurl may support more
-purposes.
+this particular socket. \fICURLSOCKTYPE_IPCXN\fP is for IP based connections
+and is the only purpose currently used in libcurl. Future versions of libcurl
+may support more purposes.
 
 The \fIclientp\fP pointer contains whatever user-defined value set using the
 \fICURLOPT_OPENSOCKETDATA(3)\fP function.
diff --git a/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
index 46fbdc7f1..47ca33b27 100644
--- a/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
@@ -60,8 +60,11 @@ Unknown/unused argument values passed to the callback will 
be set to zero
 the callback will be called one or more times first, before it knows the data
 sizes so a program must be made to handle that.
 
-Returning a non-zero value from this callback will cause libcurl to abort the
-transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
+If your callback function returns CURL_PROGRESSFUNC_CONTINUE it will cause
+libcurl to continue executing the default progress function.
+
+Returning any other non-zero value from this callback will cause libcurl to
+abort the transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
 
 If you transfer data with the multi interface, this function will not be
 called during periods of idleness unless you call the appropriate libcurl
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3 
b/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
index f3fc74ab3..bf7fee028 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
@@ -28,23 +28,27 @@ CURLOPT_SSL_OPTIONS \- set SSL behavior options
 
 CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_OPTIONS, long bitmask);
 .SH DESCRIPTION
-Pass a long with a bitmask to tell libcurl about specific SSL behaviors.
-
-\fICURLSSLOPT_ALLOW_BEAST\fP tells libcurl to not attempt to use any
-workarounds for a security flaw in the SSL3 and TLS1.0 protocols.  If this
-option isn't used or this bit is set to 0, the SSL layer libcurl uses may use a
-work-around for this flaw although it might cause interoperability problems
-with some (older) SSL implementations. WARNING: avoiding this work-around
-lessens the security, and by setting this option to 1 you ask for exactly that.
-This option is only supported for DarwinSSL, NSS and OpenSSL.
-
-Added in 7.44.0:
-
-\fICURLSSLOPT_NO_REVOKE\fP tells libcurl to disable certificate revocation
-checks for those SSL backends where such behavior is present. This option is
-only supported for Schannel (the native Windows SSL library), with an
-exception in the case of Windows' Untrusted Publishers blacklist which it
-seems can't be bypassed.
+Pass a long with a bitmask to tell libcurl about specific SSL
+behaviors. Available bits:
+.IP CURLSSLOPT_ALLOW_BEAST
+Tells libcurl to not attempt to use any workarounds for a security flaw in the
+SSL3 and TLS1.0 protocols.  If this option isn't used or this bit is set to 0,
+the SSL layer libcurl uses may use a work-around for this flaw although it
+might cause interoperability problems with some (older) SSL
+implementations. WARNING: avoiding this work-around lessens the security, and
+by setting this option to 1 you ask for exactly that.  This option is only
+supported for DarwinSSL, NSS and OpenSSL.
+.IP CURLSSLOPT_NO_REVOKE
+Tells libcurl to disable certificate revocation checks for those SSL backends
+where such behavior is present. This option is only supported for Schannel
+(the native Windows SSL library), with an exception in the case of Windows'
+Untrusted Publishers blacklist which it seems can't be bypassed. (Added in
+7.44.0)
+.IP CURLSSLOPT_NO_PARTIALCHAIN
+Tells libcurl to not accept "partial" certificate chains, which it otherwise
+does by default. This option is only supported for OpenSSL and will fail the
+certificate verification if the chain ends with an intermediate certificate
+and not with a root cert. (Added in 7.68.0)
 .SH DEFAULT
 0
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3 
b/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3
index be67bdbdb..7fe983e2e 100644
--- a/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3
+++ b/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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 @@ to use for the TLS authentication method specified with the
 
 The application does not have to keep the string around after setting this
 option.
+
+This feature relies in TLS SRP which doesn't work with TLS 1.3.
 .SH DEFAULT
 NULL
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3 
b/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3
index 15e697d31..f480f341e 100644
--- a/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -28,8 +28,8 @@ CURLOPT_TLSAUTH_TYPE \- set TLS authentication methods
 
 CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TLSAUTH_TYPE, char *type);
 .SH DESCRIPTION
-Pass a pointer to a zero terminated string as parameter. The string
-should be the method of the TLS authentication. Supported method is "SRP".
+Pass a pointer to a zero terminated string as parameter. The string should be
+the method of the TLS authentication. Supported method is "SRP".
 
 .IP SRP
 TLS-SRP authentication. Secure Remote Password authentication for TLS is
@@ -40,6 +40,8 @@ options.
 
 The application does not have to keep the string around after setting this
 option.
+
+TLS SRP doesn't work with TLS 1.3.
 .SH DEFAULT
 blank
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3 
b/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3
index e7c4fe8a3..807ba9abb 100644
--- a/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3
+++ b/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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 @@ to use for the TLS authentication method specified with the
 
 The application does not have to keep the string around after setting this
 option.
+
+This feature relies in TLS SRP which doesn't work with TLS 1.3.
 .SH DEFAULT
 NULL
 .SH PROTOCOLS
diff --git a/docs/libcurl/opts/GNURLOPT_VERBOSE.3 
b/docs/libcurl/opts/GNURLOPT_VERBOSE.3
index 79a002c44..c2d6523c4 100644
--- a/docs/libcurl/opts/GNURLOPT_VERBOSE.3
+++ b/docs/libcurl/opts/GNURLOPT_VERBOSE.3
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -61,3 +61,4 @@ Always
 Returns CURLE_OK
 .SH "SEE ALSO"
 .BR CURLOPT_STDERR "(3), " CURLOPT_DEBUGFUNCTION "(3), "
+.BR CURLOPT_ERRORBUFFER "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3 
b/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
index 60cf2d9fa..02f471535 100644
--- a/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
@@ -57,8 +57,11 @@ Unknown/unused argument values passed to the callback will 
be set to zero
 the callback will be called one or more times first, before it knows the data
 sizes so a program must be made to handle that.
 
-Returning a non-zero value from this callback will cause libcurl to abort the
-transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
+If your callback function returns CURL_PROGRESSFUNC_CONTINUE it will cause
+libcurl to continue executing the default progress function.
+
+Returning any other non-zero value from this callback will cause libcurl to
+abort the transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
 
 If you transfer data with the multi interface, this function will not be
 called during periods of idleness unless you call the appropriate libcurl
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index bf23b4488..18f04bd70 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -38,7 +38,7 @@ CURLCLOSEPOLICY_OLDEST          7.7
 CURLCLOSEPOLICY_SLOWEST         7.7
 CURLE_ABORTED_BY_CALLBACK       7.1
 CURLE_AGAIN                     7.18.2
-CURLE_ALREADY_COMPLETE          7.7.2
+CURLE_ALREADY_COMPLETE          7.7.2         7.8
 CURLE_AUTH_ERROR                7.66.0
 CURLE_BAD_CALLING_ORDER         7.1           7.17.0
 CURLE_BAD_CONTENT_ENCODING      7.10
@@ -56,7 +56,7 @@ CURLE_FILESIZE_EXCEEDED         7.10.8
 CURLE_FILE_COULDNT_READ_FILE    7.1
 CURLE_FTP_ACCEPT_FAILED         7.24.0
 CURLE_FTP_ACCEPT_TIMEOUT        7.24.0
-CURLE_FTP_ACCESS_DENIED         7.1
+CURLE_FTP_ACCESS_DENIED         7.1           7.17.0
 CURLE_FTP_BAD_DOWNLOAD_RESUME   7.1           7.1
 CURLE_FTP_BAD_FILE_LIST         7.21.0
 CURLE_FTP_CANT_GET_HOST         7.1
@@ -66,7 +66,7 @@ CURLE_FTP_COULDNT_RETR_FILE     7.1
 CURLE_FTP_COULDNT_SET_ASCII     7.1           7.17.0
 CURLE_FTP_COULDNT_SET_BINARY    7.1           7.17.0
 CURLE_FTP_COULDNT_SET_TYPE      7.17.0
-CURLE_FTP_COULDNT_STOR_FILE     7.1
+CURLE_FTP_COULDNT_STOR_FILE     7.1           7.16.3
 CURLE_FTP_COULDNT_USE_REST      7.1
 CURLE_FTP_PARTIAL_FILE          7.1           7.1
 CURLE_FTP_PORT_FAILED           7.1
@@ -77,14 +77,15 @@ CURLE_FTP_USER_PASSWORD_INCORRECT 7.1         7.17.0
 CURLE_FTP_WEIRD_227_FORMAT      7.1
 CURLE_FTP_WEIRD_PASS_REPLY      7.1
 CURLE_FTP_WEIRD_PASV_REPLY      7.1
-CURLE_FTP_WEIRD_SERVER_REPLY    7.1
+CURLE_FTP_WEIRD_SERVER_REPLY    7.1           7.51.0
 CURLE_FTP_WEIRD_USER_REPLY      7.1           7.17.0
 CURLE_FTP_WRITE_ERROR           7.1           7.17.0
 CURLE_FUNCTION_NOT_FOUND        7.1
 CURLE_GOT_NOTHING               7.9.1
 CURLE_HTTP2                     7.38.0
 CURLE_HTTP2_STREAM              7.49.0
-CURLE_HTTP_NOT_FOUND            7.1
+CURLE_HTTP3                     7.68.0
+CURLE_HTTP_NOT_FOUND            7.1           7.10.3
 CURLE_HTTP_PORT_FAILED          7.3           7.12.0
 CURLE_HTTP_POST_ERROR           7.1
 CURLE_HTTP_RANGE_ERROR          7.1           7.17.0
@@ -143,7 +144,7 @@ CURLE_TFTP_PERM                 7.15.0
 CURLE_TFTP_UNKNOWNID            7.15.0
 CURLE_TOO_MANY_REDIRECTS        7.5
 CURLE_UNKNOWN_OPTION            7.21.5
-CURLE_UNKNOWN_TELNET_OPTION     7.7
+CURLE_UNKNOWN_TELNET_OPTION     7.7           7.21.5
 CURLE_UNSUPPORTED_PROTOCOL      7.1
 CURLE_UPLOAD_FAILED             7.16.3
 CURLE_URL_MALFORMAT             7.1
@@ -341,6 +342,7 @@ CURLM_INTERNAL_ERROR            7.9.6
 CURLM_OK                        7.9.6
 CURLM_OUT_OF_MEMORY             7.9.6
 CURLM_RECURSIVE_API_CALL        7.59.0
+CURLM_WAKEUP_FAILURE            7.68.0
 CURLM_UNKNOWN_OPTION            7.15.4
 CURLOPTTYPE_FUNCTIONPOINT       7.1
 CURLOPTTYPE_LONG                7.1
@@ -718,6 +720,7 @@ CURLSSH_AUTH_NONE               7.16.1
 CURLSSH_AUTH_PASSWORD           7.16.1
 CURLSSH_AUTH_PUBLICKEY          7.16.1
 CURLSSLBACKEND_AXTLS            7.38.0       7.61.0
+CURLSSLBACKEND_BEARSSL          7.68.0
 CURLSSLBACKEND_BORINGSSL        7.49.0
 CURLSSLBACKEND_CYASSL           7.34.0
 CURLSSLBACKEND_DARWINSSL        7.34.0       7.64.1
@@ -735,6 +738,7 @@ CURLSSLBACKEND_SCHANNEL         7.34.0
 CURLSSLBACKEND_SECURETRANSPORT  7.64.1
 CURLSSLBACKEND_WOLFSSL          7.49.0
 CURLSSLOPT_ALLOW_BEAST          7.25.0
+CURLSSLOPT_NO_PARTIALCHAIN      7.68.0
 CURLSSLOPT_NO_REVOKE            7.44.0
 CURLSSLSET_NO_BACKENDS          7.56.0
 CURLSSLSET_OK                   7.56.0
@@ -866,6 +870,7 @@ CURL_POLL_INOUT                 7.14.0
 CURL_POLL_NONE                  7.14.0
 CURL_POLL_OUT                   7.14.0
 CURL_POLL_REMOVE                7.14.0
+CURL_PROGRESSFUNC_CONTINUE      7.68.0
 CURL_PROGRESS_BAR               7.1.1         -           7.4.1
 CURL_PROGRESS_STATS             7.1.1         -           7.4.1
 CURL_PUSH_DENY                  7.44.0
diff --git a/include/gnurl/curl.h b/include/gnurl/curl.h
index dcbe8995c..bef8a0bca 100644
--- a/include/gnurl/curl.h
+++ b/include/gnurl/curl.h
@@ -154,7 +154,8 @@ typedef enum {
   CURLSSLBACKEND_SECURETRANSPORT = 9,
   CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */
   CURLSSLBACKEND_MBEDTLS = 11,
-  CURLSSLBACKEND_MESALINK = 12
+  CURLSSLBACKEND_MESALINK = 12,
+  CURLSSLBACKEND_BEARSSL = 13
 } curl_sslbackend;
 
 /* aliases for library clones and renames */
@@ -209,6 +210,11 @@ struct curl_httppost {
                                        set. Added in 7.46.0 */
 };
 
+
+/* This is a return code for the progress callback that, when returned, will
+   signal libcurl to continue executing the default progress function */
+#define CURL_PROGRESSFUNC_CONTINUE 0x10000001
+
 /* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now
    considered deprecated but was the only choice up until 7.31.0 */
 typedef int (*curl_progress_callback)(void *clientp,
@@ -602,6 +608,7 @@ typedef enum {
                                     inside a callback */
   CURLE_AUTH_ERROR,              /* 94 - an authentication function returned an
                                     error */
+  CURLE_HTTP3,                   /* 95 - An HTTP/3 layer problem */
   CURL_LAST /* never use! */
 } CURLcode;
 
@@ -821,6 +828,10 @@ typedef enum {
    SSL backends where such behavior is present. */
 #define CURLSSLOPT_NO_REVOKE (1<<1)
 
+/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain
+   if possible. The OpenSSL backend has this ability. */
+#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
+
 /* 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. */
diff --git a/include/gnurl/curlver.h b/include/gnurl/curlver.h
index 31fc72d12..5b0df8ede 100644
--- a/include/gnurl/curlver.h
+++ b/include/gnurl/curlver.h
@@ -30,12 +30,12 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.67.0-DEV"
+#define LIBCURL_VERSION "7.68.0-DEV"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 67
+#define LIBCURL_VERSION_MINOR 68
 #define LIBCURL_VERSION_PATCH 0
 
 /* This is the numeric version of the libcurl version number, meant for easier
@@ -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 0x074300
+#define LIBCURL_VERSION_NUM 0x074400
 
 /*
  * This is the date and time when the full source package was created. The
diff --git a/include/gnurl/multi.h b/include/gnurl/multi.h
index fce68f4ff..3521d85bf 100644
--- a/include/gnurl/multi.h
+++ b/include/gnurl/multi.h
@@ -72,6 +72,7 @@ typedef enum {
                             attempted to get added - again */
   CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
                                callback */
+  CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
   CURLM_LAST
 } CURLMcode;
 
@@ -187,6 +188,15 @@ CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
                                       int timeout_ms,
                                       int *ret);
 
+/*
+ * Name:     curl_multi_wakeup()
+ *
+ * Desc:     wakes up a sleeping curl_multi_poll call.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
+
  /*
   * Name:    curl_multi_perform()
   *
diff --git a/include/gnurl/system.h b/include/gnurl/system.h
index cd37c2bf5..867af6141 100644
--- a/include/gnurl/system.h
+++ b/include/gnurl/system.h
@@ -137,15 +137,26 @@
 #  define CURL_TYPEOF_CURL_SOCKLEN_T int
 
 #elif defined(__LCC__)
-#  define CURL_TYPEOF_CURL_OFF_T     long
-#  define CURL_FORMAT_CURL_OFF_T     "ld"
-#  define CURL_FORMAT_CURL_OFF_TU    "lu"
-#  define CURL_SUFFIX_CURL_OFF_T     L
-#  define CURL_SUFFIX_CURL_OFF_TU    UL
-#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  if defined(__e2k__) /* MCST eLbrus C Compiler */
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  else                /* Local (or Little) C Compiler */
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  endif
 
 #elif defined(__SYMBIAN32__)
-#  if defined(__EABI__)  /* Treat all ARM compilers equally */
+#  if defined(__EABI__) /* Treat all ARM compilers equally */
 #    define CURL_TYPEOF_CURL_OFF_T     long long
 #    define CURL_FORMAT_CURL_OFF_T     "lld"
 #    define CURL_FORMAT_CURL_OFF_TU    "llu"
@@ -288,7 +299,6 @@
 #  define CURL_TYPEOF_CURL_SOCKLEN_T int
 
 #elif defined(__TINYC__) /* also known as tcc */
-
 #  define CURL_TYPEOF_CURL_OFF_T     long long
 #  define CURL_FORMAT_CURL_OFF_T     "lld"
 #  define CURL_FORMAT_CURL_OFF_TU    "llu"
@@ -377,6 +387,7 @@
 #    define CURL_SUFFIX_CURL_OFF_TU    ULL
 #  elif defined(__LP64__) || \
         defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
+        defined(__e2k__) || \
         (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
         (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
 #    define CURL_TYPEOF_CURL_OFF_T     long
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 8d2d73567..5bd15654c 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -20,7 +20,6 @@ list(APPEND HHEADERS
 
 if(MSVC)
   list(APPEND CSOURCES libcurl.rc)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127")
 endif()
 
 # SET(CSOURCES
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 72ef428ee..6c90c2675 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -30,12 +30,13 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
 LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c     \
   vtls/polarssl.c vtls/polarssl_threadlock.c                            \
   vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c                 \
-  vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
+  vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c          \
+  vtls/bearssl.c
 
 LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h                \
   vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h                \
   vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h          \
-  vtls/mbedtls.h vtls/mesalink.h
+  vtls/mbedtls.h vtls/mesalink.h vtls/bearssl.h
 
 LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
 
@@ -43,6 +44,8 @@ LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
 
 LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c
 
+LIB_VSSH_HFILES = vssh/ssh.h
+
 LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
   cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c       \
   ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c         \
@@ -72,7 +75,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h 
progress.h \
   http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h         \
   inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h    \
   easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h     \
-  socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h      \
+  socks.h curl_base64.h curl_addrinfo.h curl_sspi.h                     \
   slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h     \
   rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h              \
   curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h           \
@@ -89,4 +92,4 @@ LIB_RCFILES = libcurl.rc
 CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \
   $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES)
 HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \
-  $(LIB_VQUIC_HFILES)
+  $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES)
diff --git a/lib/Makefile.m32 b/lib/Makefile.m32
index ae88f4dce..b6ef0a5cb 100644
--- a/lib/Makefile.m32
+++ b/lib/Makefile.m32
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1999 - 2017, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 1999 - 2019, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -271,7 +271,7 @@ ifdef SSL
   endif
   INCLUDES += -I"$(OPENSSL_INCLUDE)"
   CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \
-            -DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5
+            -DOPENSSL_NO_KRB5
   DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
   ifdef SRP
     ifeq "$(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h)" 
"$(OPENSSL_INCLUDE)/openssl/srp.h"
diff --git a/lib/altsvc.c b/lib/altsvc.c
index c773b7bdc..1533a274b 100644
--- a/lib/altsvc.c
+++ b/lib/altsvc.c
@@ -55,7 +55,7 @@ static enum alpnid alpn2alpnid(char *name)
   if(strcasecompare(name, "h2"))
     return ALPN_h2;
 #if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
-  if(strcasecompare(name, "h3-23"))
+  if(strcasecompare(name, "h3-24"))
     return ALPN_h3;
 #else
   if(strcasecompare(name, "h3"))
@@ -74,7 +74,7 @@ const char *Curl_alpnid2str(enum alpnid id)
     return "h2";
   case ALPN_h3:
 #if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
-    return "h3-23";
+    return "h3-24";
 #else
     return "h3";
 #endif
@@ -161,7 +161,7 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char 
*line)
               date, &persist, &prio);
   if(9 == rc) {
     struct altsvc *as;
-    time_t expires = curl_getdate(date, NULL);
+    time_t expires = Curl_getdate_capped(date);
     as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
     if(as) {
       as->expires = expires;
@@ -320,8 +320,8 @@ CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const 
char *file)
     /* no cache activated */
     return CURLE_OK;
 
-  if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0])
-    /* marked as read-only or zero length file name */
+  if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
+    /* marked as read-only, no file or zero length file name */
     return CURLE_OK;
   out = fopen(file, FOPEN_WRITETEXT);
   if(!out)
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 8c552baa9..b08497aaa 100755
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -698,6 +698,16 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct 
connectdata *conn,
 
   *waitp = 0; /* default to synchronous response */
 
+#ifdef ENABLE_IPV6
+  {
+    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 */
+      return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+  }
+#endif /* ENABLE_IPV6 */
+
   if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
     /* This is a dotted IP address 123.123.123.123-style */
     return Curl_ip2addr(AF_INET, &in, hostname, port);
@@ -741,7 +751,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata 
*conn,
       /* This is a dotted IP address 123.123.123.123-style */
       return Curl_ip2addr(AF_INET, &in, hostname, port);
   }
-#ifdef CURLRES_IPV6
+#ifdef ENABLE_IPV6
   {
     struct in6_addr in6;
     /* check if this is an IPv6 address string */
@@ -749,7 +759,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata 
*conn,
       /* This is an IPv6 address literal */
       return Curl_ip2addr(AF_INET6, &in6, hostname, port);
   }
-#endif /* CURLRES_IPV6 */
+#endif /* ENABLE_IPV6 */
 #endif /* !USE_RESOLVE_ON_IPS */
 
 #ifdef CURLRES_IPV6
diff --git a/lib/checksrc.pl b/lib/checksrc.pl
index b2cfa8355..834364561 100755
--- a/lib/checksrc.pl
+++ b/lib/checksrc.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2011 - 2018, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2011 - 2019, Daniel Stenberg, <address@hidden>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -717,12 +717,17 @@ sub scanfile {
         my $commityear = undef;
         @copyright = sort {$$b{year} cmp $$a{year}} @copyright;
 
+        # if the file is modified, assume commit year this year
         if(`git status -s -- $file` =~ /^ [MARCU]/) {
             $commityear = (localtime(time))[5] + 1900;
         }
-        elsif (`git rev-list --count origin/master..HEAD -- $file` !~ /^0/) {
-            my $grl = `git rev-list --max-count=1 --timestamp HEAD -- $file`;
-            $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900;
+        else {
+            # min-parents=1 to ignore wrong initial commit in truncated repos
+            my $grl = `git rev-list --max-count=1 --min-parents=1 --timestamp 
HEAD -- $file`;
+            if($grl) {
+                chomp $grl;
+                $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900;
+            }
         }
 
         if(defined($commityear) && scalar(@copyright) &&
diff --git a/lib/config-dos.h b/lib/config-dos.h
index 3e973de0b..25f751eb5 100644
--- a/lib/config-dos.h
+++ b/lib/config-dos.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/config-mac.h b/lib/config-mac.h
index 3c12bdfac..14b98fe57 100644
--- a/lib/config-mac.h
+++ b/lib/config-mac.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/config-plan9.h b/lib/config-plan9.h
index 64bfbdea0..4063d4bbd 100644
--- a/lib/config-plan9.h
+++ b/lib/config-plan9.h
@@ -102,7 +102,6 @@
 #define HAVE_BASENAME 1
 #define HAVE_BOOL_T 1
 #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
-#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
 #define HAVE_ERRNO_H 1
 #define HAVE_FCNTL 1
 #define HAVE_FCNTL_H 1
diff --git a/lib/config-symbian.h b/lib/config-symbian.h
index cb2e96d5d..c01e1bfab 100644
--- a/lib/config-symbian.h
+++ b/lib/config-symbian.h
@@ -128,9 +128,6 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
-/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
-/*#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1*/
-
 /* Define to 1 if you have the <errno.h> header file. */
 #define HAVE_ERRNO_H 1
 
diff --git a/lib/config-tpf.h b/lib/config-tpf.h
index f0c095bb0..85b634f9d 100644
--- a/lib/config-tpf.h
+++ b/lib/config-tpf.h
@@ -119,10 +119,6 @@
 /* #undef HAVE_DES_H */
 #define HAVE_DES_H 1
 
-/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
-/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
-#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
-
 /* Define to 1 if you have the <errno.h> header file. */
 #define HAVE_ERRNO_H 1
 
diff --git a/lib/config-vxworks.h b/lib/config-vxworks.h
index d352578e3..004fd4e80 100644
--- a/lib/config-vxworks.h
+++ b/lib/config-vxworks.h
@@ -143,9 +143,6 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
-/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
-#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
-
 /* Define to 1 if you have the <errno.h> header file. */
 #define HAVE_ERRNO_H 1
 
diff --git a/lib/config-win32.h b/lib/config-win32.h
index 90c105476..1dcce0db4 100644
--- a/lib/config-win32.h
+++ b/lib/config-win32.h
@@ -735,8 +735,12 @@ Vista
 #define OS "i386-pc-win32"
 #elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */
 #define OS "x86_64-pc-win32"
-#elif defined(_M_IA64) /* Itanium */
+#elif defined(_M_IA64) || defined(__ia64__) /* Itanium */
 #define OS "ia64-pc-win32"
+#elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 (Windows RT) */
+#define OS "thumbv7a-pc-win32"
+#elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */
+#define OS "aarch64-pc-win32"
 #else
 #define OS "unknown-pc-win32"
 #endif
diff --git a/lib/config-win32ce.h b/lib/config-win32ce.h
index 182052290..5eb1c18f6 100644
--- a/lib/config-win32ce.h
+++ b/lib/config-win32ce.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/conncache.c b/lib/conncache.c
index 270352255..d26272459 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -40,27 +40,6 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
-#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) {                                   \
-    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) {                                 \
-    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)                                     \
-    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
-#define CONN_UNLOCK(x) if((x)->share)                   \
-    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
-#endif
-
 #define HASHKEY_SIZE 128
 
 static void conn_llist_dtor(void *user, void *element)
@@ -122,6 +101,7 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr,
     }
     curr = curr->next;
   }
+  DEBUGASSERT(0);
   return 0;
 }
 
@@ -428,17 +408,15 @@ conncache_find_first_connection(struct conncache *connc)
  *
  * Return TRUE if stored, FALSE if closed.
  */
-bool Curl_conncache_return_conn(struct connectdata *conn)
+bool Curl_conncache_return_conn(struct Curl_easy *data,
+                                struct connectdata *conn)
 {
-  struct Curl_easy *data = conn->data;
-
   /* data->multi->maxconnects can be negative, deal with it. */
   size_t maxconnects =
     (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
     data->multi->maxconnects;
   struct connectdata *conn_candidate = NULL;
 
-  conn->data = NULL; /* no owner anymore */
   conn->lastused = Curl_now(); /* it was used up until now */
   if(maxconnects > 0 &&
      Curl_conncache_size(data) > maxconnects) {
@@ -541,7 +519,8 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
     while(curr) {
       conn = curr->ptr;
 
-      if(!CONN_INUSE(conn) && !conn->data) {
+      if(!CONN_INUSE(conn) && !conn->data && !conn->bits.close &&
+         !conn->bits.connect_only) {
         /* Set higher score for the age passed since the connection was used */
         score = Curl_timediff(now, conn->lastused);
 
diff --git a/lib/conncache.h b/lib/conncache.h
index 58f902409..5fe80b4c8 100644
--- a/lib/conncache.h
+++ b/lib/conncache.h
@@ -42,6 +42,27 @@ struct conncache {
 #define BUNDLE_UNKNOWN     0  /* initial value */
 #define BUNDLE_MULTIPLEX   2
 
+#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) {                                   \
+    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) {                                 \
+    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)                                     \
+    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
+#define CONN_UNLOCK(x) if((x)->share)                   \
+    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
+#endif
+
 struct connectbundle {
   int multiuse;                 /* supports multi-use */
   size_t num_connections;       /* Number of connections in the bundle */
@@ -61,7 +82,8 @@ void Curl_conncache_unlock(struct Curl_easy *data);
 size_t Curl_conncache_size(struct Curl_easy *data);
 size_t Curl_conncache_bundle_size(struct connectdata *conn);
 
-bool Curl_conncache_return_conn(struct connectdata *conn);
+bool Curl_conncache_return_conn(struct Curl_easy *data,
+                                struct connectdata *conn);
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
                                  struct connectdata *conn) WARN_UNUSED_RESULT;
 void Curl_conncache_remove_conn(struct Curl_easy *data,
diff --git a/lib/cookie.c b/lib/cookie.c
index f56bd85a9..0091132aa 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -96,6 +96,7 @@ Example set of cookies:
 #include "curl_get_line.h"
 #include "curl_memrchr.h"
 #include "inet_pton.h"
+#include "parsedate.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -715,7 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
     else if(co->expirestr) {
       /* Note that if the date couldn't get parsed for whatever reason,
          the cookie will be treated as a session cookie */
-      co->expires = curl_getdate(co->expirestr, NULL);
+      co->expires = Curl_getdate_capped(co->expirestr);
 
       /* Session cookies have expires set to 0 so if we get that back
          from the date parser let's add a second to make it a
diff --git a/lib/curl_base64.h b/lib/curl_base64.h
index 7e9fc2606..cfb6ee75b 100644
--- a/lib/curl_base64.h
+++ b/lib/curl_base64.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index e0793a7ee..2c3b6562d 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -148,9 +148,6 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #cmakedefine HAVE_DLFCN_H 1
 
-/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
-#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
-
 /* Define to 1 if you have the <errno.h> header file. */
 #cmakedefine HAVE_ERRNO_H 1
 
@@ -948,6 +945,9 @@ ${SIZEOF_TIME_T_CODE}
 /* if mbedTLS is enabled */
 #cmakedefine USE_MBEDTLS 1
 
+/* if BearSSL is enabled */
+#cmakedefine USE_BEARSSL 1
+
 /* if libSSH2 is in use */
 #cmakedefine USE_LIBSSH2 1
 
@@ -957,6 +957,9 @@ ${SIZEOF_TIME_T_CODE}
 /* if NSS is enabled */
 #cmakedefine USE_NSS 1
 
+/* if you have the PK11_CreateManagedGenericObject function */
+#cmakedefine HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1
+
 /* if you want to use OpenLDAP code instead of legacy ldap implementation */
 #cmakedefine USE_OPENLDAP 1
 
diff --git a/lib/curl_des.c b/lib/curl_des.c
index b123a00f0..39c0f35ee 100644
--- a/lib/curl_des.c
+++ b/lib/curl_des.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015, Steve Holme, <address@hidden>.
+ * Copyright (C) 2015 - 2019, Steve Holme, <address@hidden>.
  *
  * 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/lib/curl_des.h b/lib/curl_des.h
index 129060ff7..a42eeb53f 100644
--- a/lib/curl_des.h
+++ b/lib/curl_des.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015, Steve Holme, <address@hidden>.
+ * Copyright (C) 2015 - 2019, Steve Holme, <address@hidden>.
  *
  * 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/lib/curl_fnmatch.h b/lib/curl_fnmatch.h
index 69ffe392f..34fccae48 100644
--- a/lib/curl_fnmatch.h
+++ b/lib/curl_fnmatch.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_gethostname.h b/lib/curl_gethostname.h
index 07517c535..8ae15e6c1 100644
--- a/lib/curl_gethostname.h
+++ b/lib/curl_gethostname.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_ldap.h b/lib/curl_ldap.h
index 94c002948..912e13107 100644
--- a/lib/curl_ldap.h
+++ b/lib/curl_ldap.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_memrchr.h b/lib/curl_memrchr.h
index 747509c45..90a8a07cc 100644
--- a/lib/curl_memrchr.h
+++ b/lib/curl_memrchr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_multibyte.c b/lib/curl_multibyte.c
index 74cc459f3..9dfa6d027 100644
--- a/lib/curl_multibyte.c
+++ b/lib/curl_multibyte.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_multibyte.h b/lib/curl_multibyte.h
index 615f5c086..3becf41cf 100644
--- a/lib/curl_multibyte.h
+++ b/lib/curl_multibyte.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -61,8 +61,13 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
 
 #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) \
-  do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
+#define Curl_unicodefree(ptr)                           \
+  do {                                                  \
+    if(ptr) {                                           \
+      free(ptr);                                        \
+      (ptr) = NULL;                                     \
+    }                                                   \
+  } while(0)
 
 typedef union {
   unsigned short       *tchar_ptr;
@@ -76,7 +81,7 @@ typedef union {
 #define Curl_convert_UTF8_to_tchar(ptr) (ptr)
 #define Curl_convert_tchar_to_UTF8(ptr) (ptr)
 #define Curl_unicodefree(ptr) \
-  do {(ptr) = NULL;} WHILE_FALSE
+  do {(ptr) = NULL;} while(0)
 
 typedef union {
   char                *tchar_ptr;
diff --git a/lib/curl_ntlm_core.h b/lib/curl_ntlm_core.h
index 3b4b8053c..392a1b81d 100644
--- a/lib/curl_ntlm_core.h
+++ b/lib/curl_ntlm_core.h
@@ -48,7 +48,9 @@
 /* Define USE_NTLM2SESSION in order to make the type-3 message include the
    NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
    Crypto engine that we have curl_ssl_md5sum() for. */
-#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
+#if defined(USE_NTRESPONSES) && \
+  (!defined(USE_WIN32_CRYPTO) || \
+  (defined(USE_SSL) && !defined(CURL_DISABLE_CRYPTO_AUTH)))
 #define USE_NTLM2SESSION
 #endif
 
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index 80266e2a4..30b54de44 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -108,10 +108,8 @@ void Curl_http_auth_cleanup_ntlm_wb(struct connectdata 
*conn)
     conn->ntlm_auth_hlpr_pid = 0;
   }
 
-  free(conn->challenge_header);
-  conn->challenge_header = NULL;
-  free(conn->response_header);
-  conn->response_header = NULL;
+  Curl_safefree(conn->challenge_header);
+  Curl_safefree(conn->response_header);
 }
 
 static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
@@ -393,7 +391,6 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
   struct auth *authp;
 
   CURLcode res = CURLE_OK;
-  char *input;
 
   DEBUGASSERT(conn);
   DEBUGASSERT(conn->data);
@@ -444,19 +441,17 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
                             proxy ? "Proxy-" : "",
                             conn->response_header);
     DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
-    free(conn->response_header);
+    Curl_safefree(conn->response_header);
     if(!*allocuserpwd)
       return CURLE_OUT_OF_MEMORY;
-    conn->response_header = NULL;
     break;
 
-  case NTLMSTATE_TYPE2:
-    input = aprintf("TT %s\n", conn->challenge_header);
+  case NTLMSTATE_TYPE2: {
+    char *input = aprintf("TT %s\n", conn->challenge_header);
     if(!input)
       return CURLE_OUT_OF_MEMORY;
     res = ntlm_wb_response(conn, input, *state);
     free(input);
-    input = NULL;
     if(res)
       return res;
 
@@ -471,7 +466,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
     if(!*allocuserpwd)
       return CURLE_OUT_OF_MEMORY;
     break;
-
+  }
   case NTLMSTATE_TYPE3:
     /* connection is already authenticated,
      * don't send a header in future requests */
diff --git a/lib/curl_rtmp.h b/lib/curl_rtmp.h
index 3306e2200..86a01382d 100644
--- a/lib/curl_rtmp.h
+++ b/lib/curl_rtmp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010, Howard Chu, <address@hidden>
+ * Copyright (C) 2010 - 2019, Howard Chu, <address@hidden>
  *
  * 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/lib/curl_setup.h b/lib/curl_setup.h
index 8e5c064dd..e015e3e3b 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -26,6 +26,14 @@
 #define CURL_NO_OLDIES
 #endif
 
+/*
+ * Disable Visual Studio warnings:
+ * 4127 "conditional expression is constant"
+ */
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+
 /*
  * Define WIN32 when build target is Win32 API
  */
@@ -563,6 +571,12 @@
  * Mutually exclusive CURLRES_* definitions.
  */
 
+#if defined(ENABLE_IPV6) && defined(HAVE_GETADDRINFO)
+#  define CURLRES_IPV6
+#else
+#  define CURLRES_IPV4
+#endif
+
 #ifdef USE_ARES
 #  define CURLRES_ASYNCH
 #  define CURLRES_ARES
@@ -577,12 +591,6 @@
 #  define CURLRES_SYNCH
 #endif
 
-#ifdef ENABLE_IPV6
-#  define CURLRES_IPV6
-#else
-#  define CURLRES_IPV4
-#endif
-
 /* ---------------------------------------------------------------- */
 
 /*
@@ -644,7 +652,8 @@ int netware_init(void);
 #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
     defined(USE_MBEDTLS) || \
     defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \
-    defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK)
+    defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \
+    defined(USE_BEARSSL)
 #define USE_SSL    /* SSL support has been enabled */
 #endif
 
@@ -713,7 +722,7 @@ int netware_init(void);
  */
 
 #ifndef Curl_nop_stmt
-#  define Curl_nop_stmt do { } WHILE_FALSE
+#  define Curl_nop_stmt do { } while(0)
 #endif
 
 /*
diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h
index 413ccea91..8db74e9b4 100644
--- a/lib/curl_setup_once.h
+++ b/lib/curl_setup_once.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -329,27 +329,6 @@ struct timeval {
 
 #include "curl_ctype.h"
 
-/*
- * Macro WHILE_FALSE may be used to build single-iteration do-while loops,
- * avoiding compiler warnings. Mostly intended for other macro definitions.
- */
-
-#define WHILE_FALSE  while(0)
-
-#if defined(_MSC_VER) && !defined(__POCC__)
-#  undef WHILE_FALSE
-#  if (_MSC_VER < 1500)
-#    define WHILE_FALSE  while(1, 0)
-#  else
-#    define WHILE_FALSE \
-__pragma(warning(push)) \
-__pragma(warning(disable:4127)) \
-while(0) \
-__pragma(warning(pop))
-#  endif
-#endif
-
-
 /*
  * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
  */
@@ -387,7 +366,7 @@ typedef int sig_atomic_t;
 #ifdef DEBUGBUILD
 #define DEBUGF(x) x
 #else
-#define DEBUGF(x) do { } WHILE_FALSE
+#define DEBUGF(x) do { } while(0)
 #endif
 
 
@@ -398,7 +377,7 @@ typedef int sig_atomic_t;
 #if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
 #define DEBUGASSERT(x) assert(x)
 #else
-#define DEBUGASSERT(x) do { } WHILE_FALSE
+#define DEBUGASSERT(x) do { } while(0)
 #endif
 
 
diff --git a/lib/curl_sha256.h b/lib/curl_sha256.h
index 6db4b04db..14b6414ea 100644
--- a/lib/curl_sha256.h
+++ b/lib/curl_sha256.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Florin Petriuc, <address@hidden>
+ * Copyright (C) 1998 - 2019, Florin Petriuc, <address@hidden>
  *
  * 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/lib/curl_sspi.c b/lib/curl_sspi.c
index a00210ec1..a824d48f4 100644
--- a/lib/curl_sspi.c
+++ b/lib/curl_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_sspi.h b/lib/curl_sspi.h
index 694289900..cad6fe93f 100644
--- a/lib/curl_sspi.h
+++ b/lib/curl_sspi.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_threads.c b/lib/curl_threads.c
index 2b36c87b4..12a693fa3 100644
--- a/lib/curl_threads.c
+++ b/lib/curl_threads.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/curl_threads.h b/lib/curl_threads.h
index 2a93644c5..65d1a790c 100644
--- a/lib/curl_threads.h
+++ b/lib/curl_threads.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/dict.h b/lib/dict.h
index 12c0f3394..38a55ac0d 100644
--- a/lib/dict.h
+++ b/lib/dict.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/doh.c b/lib/doh.c
index d1795789e..7f4eee5d8 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -86,12 +86,36 @@ UNITTEST DOHcode doh_encode(const char *host,
   unsigned char *orig = dnsp;
   const char *hostp = host;
 
-  /* The expected output length does not depend on the number of dots within
-   * the host name. It will always be two more than the length of the host
-   * name, one for the size and one trailing null. In case there are dots,
-   * each dot adds one size but removes the need to store the dot, net zero.
+  /* The expected output length is 16 bytes more than the length of
+   * the QNAME-encoding of the host name.
+   *
+   * A valid DNS name may not contain a zero-length label, except at
+   * the end.  For this reason, a name beginning with a dot, or
+   * containing a sequence of two or more consecutive dots, is invalid
+   * and cannot be encoded as a QNAME.
+   *
+   * If the host name ends with a trailing dot, the corresponding
+   * QNAME-encoding is one byte longer than the host name. If (as is
+   * also valid) the hostname is shortened by the omission of the
+   * trailing dot, then its QNAME-encoding will be two bytes longer
+   * than the host name.
+   *
+   * Each [ label, dot ] pair is encoded as [ length, label ],
+   * preserving overall length.  A final [ label ] without a dot is
+   * also encoded as [ length, label ], increasing overall length
+   * by one. The encoding is completed by appending a zero byte,
+   * representing the zero-length root label, again increasing
+   * the overall length by one.
    */
-  const size_t expected_len = 12 + ( 1 + hostlen + 1) + 4;
+
+  size_t expected_len;
+  DEBUGASSERT(hostlen);
+  expected_len = 12 + 1 + hostlen + 4;
+  if(host[hostlen-1]!='.')
+    expected_len++;
+
+  if(expected_len > (256 + 16)) /* RFCs 1034, 1035 */
+    return DOH_DNS_NAME_TOO_LONG;
 
   if(len < expected_len)
     return DOH_TOO_SMALL_BUFFER;
@@ -109,31 +133,30 @@ UNITTEST DOHcode doh_encode(const char *host,
   *dnsp++ = '\0';
   *dnsp++ = '\0'; /* ARCOUNT */
 
-  /* store a QNAME */
-  do {
-    char *dot = strchr(hostp, '.');
+  /* encode each label and store it in the QNAME */
+  while(*hostp) {
     size_t labellen;
-    bool found = false;
-    if(dot) {
-      found = true;
+    char *dot = strchr(hostp, '.');
+    if(dot)
       labellen = dot - hostp;
-    }
     else
       labellen = strlen(hostp);
-    if(labellen > 63) {
-      /* too long label, error out */
+    if((labellen > 63) || (!labellen)) {
+      /* label is too long or too short, error out */
       *olen = 0;
       return DOH_DNS_BAD_LABEL;
     }
+    /* label is non-empty, process it */
     *dnsp++ = (unsigned char)labellen;
     memcpy(dnsp, hostp, labellen);
     dnsp += labellen;
-    hostp += labellen + 1;
-    if(!found) {
-      *dnsp++ = 0; /* terminating zero */
-      break;
-    }
-  } while(1);
+    hostp += labellen;
+    /* advance past dot, but only if there is one */
+    if(dot)
+      hostp++;
+  } /* next label */
+
+  *dnsp++ = 0; /* append zero-length label for root */
 
   /* There are assigned TYPE codes beyond 255: use range [1..65535]  */
   *dnsp++ = (unsigned char)(255 & (dnstype>>8)); /* upper 8 bit TYPE */
@@ -144,8 +167,8 @@ UNITTEST DOHcode doh_encode(const char *host,
 
   *olen = dnsp - orig;
 
-  /* verify that our assumption of length is valid, since
-   * this has lead to buffer overflows in this function */
+  /* verify that our estimation of length is valid, since
+   * this has led to buffer overflows in this function */
   DEBUGASSERT(*olen == expected_len);
   return DOH_OK;
 }
@@ -195,7 +218,7 @@ do {                                      \
   result = curl_easy_setopt(doh, x, y);   \
   if(result)                              \
     goto error;                           \
-} WHILE_FALSE
+} while(0)
 
 static CURLcode dohprobe(struct Curl_easy *data,
                          struct dnsprobe *p, DNStype dnstype,
@@ -280,38 +303,42 @@ static CURLcode dohprobe(struct Curl_easy *data,
       ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L);
     if(data->set.ssl.primary.verifyhost)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L);
+#ifndef CURL_DISABLE_PROXY
     if(data->set.proxy_ssl.primary.verifyhost)
       ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L);
-    if(data->set.ssl.primary.verifypeer)
-      ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L);
     if(data->set.proxy_ssl.primary.verifypeer)
       ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+    if(data->set.str[STRING_SSL_CAFILE_PROXY]) {
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO,
+        data->set.str[STRING_SSL_CAFILE_PROXY]);
+    }
+    if(data->set.str[STRING_SSL_CRLFILE_PROXY]) {
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE,
+        data->set.str[STRING_SSL_CRLFILE_PROXY]);
+    }
+    if(data->set.proxy_ssl.no_revoke)
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+    if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
+        data->set.str[STRING_SSL_CAPATH_PROXY]);
+    }
+#endif
+    if(data->set.ssl.primary.verifypeer)
+      ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L);
     if(data->set.ssl.primary.verifystatus)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L);
     if(data->set.str[STRING_SSL_CAFILE_ORIG]) {
       ERROR_CHECK_SETOPT(CURLOPT_CAINFO,
         data->set.str[STRING_SSL_CAFILE_ORIG]);
     }
-    if(data->set.str[STRING_SSL_CAFILE_PROXY]) {
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO,
-        data->set.str[STRING_SSL_CAFILE_PROXY]);
-    }
     if(data->set.str[STRING_SSL_CAPATH_ORIG]) {
       ERROR_CHECK_SETOPT(CURLOPT_CAPATH,
         data->set.str[STRING_SSL_CAPATH_ORIG]);
     }
-    if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
-        data->set.str[STRING_SSL_CAPATH_PROXY]);
-    }
     if(data->set.str[STRING_SSL_CRLFILE_ORIG]) {
       ERROR_CHECK_SETOPT(CURLOPT_CRLFILE,
         data->set.str[STRING_SSL_CRLFILE_ORIG]);
     }
-    if(data->set.str[STRING_SSL_CRLFILE_PROXY]) {
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE,
-        data->set.str[STRING_SSL_CRLFILE_PROXY]);
-    }
     if(data->set.ssl.certinfo)
       ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L);
     if(data->set.str[STRING_SSL_RANDOM_FILE]) {
@@ -324,8 +351,6 @@ static CURLcode dohprobe(struct Curl_easy *data,
     }
     if(data->set.ssl.no_revoke)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
-    if(data->set.proxy_ssl.no_revoke)
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
     if(data->set.ssl.fsslctx)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
     if(data->set.ssl.fsslctxp)
@@ -362,6 +387,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
 {
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
+  int slot;
   *waitp = TRUE; /* this never returns synchronously */
   (void)conn;
   (void)hostname;
@@ -380,8 +406,8 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
 
   if(conn->ip_version != CURL_IPRESOLVE_V6) {
     /* create IPv4 DOH request */
-    result = dohprobe(data, &data->req.doh.probe[0], DNS_TYPE_A,
-                      hostname, data->set.str[STRING_DOH],
+    result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4],
+                      DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
                       data->multi, data->req.doh.headers);
     if(result)
       goto error;
@@ -390,8 +416,8 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
 
   if(conn->ip_version != CURL_IPRESOLVE_V4) {
     /* create IPv6 DOH request */
-    result = dohprobe(data, &data->req.doh.probe[1], DNS_TYPE_AAAA,
-                      hostname, data->set.str[STRING_DOH],
+    result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6],
+                      DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
                       data->multi, data->req.doh.headers);
     if(result)
       goto error;
@@ -402,8 +428,9 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
   error:
   curl_slist_free_all(data->req.doh.headers);
   data->req.doh.headers = NULL;
-  Curl_close(&data->req.doh.probe[0].easy);
-  Curl_close(&data->req.doh.probe[1].easy);
+  for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
+    Curl_close(&data->req.doh.probe[slot].easy);
+  }
   return NULL;
 }
 
@@ -586,6 +613,9 @@ static DOHcode rdata(unsigned char *doh,
     if(rc)
       return rc;
     break;
+  case DNS_TYPE_DNAME:
+    /* explicit for clarity; just skip; rely on synthesized CNAME  */
+    break;
   default:
     /* unsupported type, just skip it */
     break;
@@ -647,8 +677,10 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
       return DOH_DNS_OUT_OF_RANGE;
 
     type = get16bit(doh, index);
-    if((type != DNS_TYPE_CNAME) && (type != dnstype))
-      /* Not the same type as was asked for nor CNAME */
+    if((type != DNS_TYPE_CNAME)    /* may be synthesized from DNAME */
+       && (type != DNS_TYPE_DNAME) /* if present, accept and ignore */
+       && (type != dnstype))
+      /* Not the same type as was asked for nor CNAME nor DNAME */
       return DOH_DNS_UNEXPECTED_TYPE;
     index += 2;
 
@@ -909,46 +941,43 @@ UNITTEST void de_cleanup(struct dohentry *d)
 CURLcode Curl_doh_is_resolved(struct connectdata *conn,
                               struct Curl_dns_entry **dnsp)
 {
+  CURLcode result;
   struct Curl_easy *data = conn->data;
   *dnsp = NULL; /* defaults to no response */
 
-  if(!data->req.doh.probe[0].easy && !data->req.doh.probe[1].easy) {
+  if(!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
+     !data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
     failf(data, "Could not DOH-resolve: %s", conn->async.hostname);
     return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
       CURLE_COULDNT_RESOLVE_HOST;
   }
   else if(!data->req.doh.pending) {
-    DOHcode rc;
-    DOHcode rc2;
+    DOHcode rc[DOH_PROBE_SLOTS];
     struct dohentry de;
+    int slot;
     /* remove DOH handles from multi handle and close them */
-    curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy);
-    Curl_close(&data->req.doh.probe[0].easy);
-    curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy);
-    Curl_close(&data->req.doh.probe[1].easy);
+    for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
+      curl_multi_remove_handle(data->multi, data->req.doh.probe[slot].easy);
+      Curl_close(&data->req.doh.probe[slot].easy);
+    }
     /* parse the responses, create the struct and return it! */
     init_dohentry(&de);
-    rc = doh_decode(data->req.doh.probe[0].serverdoh.memory,
-                    data->req.doh.probe[0].serverdoh.size,
-                    data->req.doh.probe[0].dnstype,
-                    &de);
-    Curl_safefree(data->req.doh.probe[0].serverdoh.memory);
-    if(rc) {
-      infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc),
-            type2name(data->req.doh.probe[0].dnstype),
-            data->req.doh.host);
-    }
-    rc2 = doh_decode(data->req.doh.probe[1].serverdoh.memory,
-                     data->req.doh.probe[1].serverdoh.size,
-                     data->req.doh.probe[1].dnstype,
-                     &de);
-    Curl_safefree(data->req.doh.probe[1].serverdoh.memory);
-    if(rc2) {
-      infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2),
-            type2name(data->req.doh.probe[1].dnstype),
-            data->req.doh.host);
-    }
-    if(!rc || !rc2) {
+    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,
+                            &de);
+      Curl_safefree(data->req.doh.probe[slot].serverdoh.memory);
+      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);
+      }
+    } /* next slot */
+
+    result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */
+    if(!rc[DOH_PROBE_SLOT_IPADDR_V4] || !rc[DOH_PROBE_SLOT_IPADDR_V6]) {
+      /* we have an address, of one kind or other */
       struct Curl_dns_entry *dns;
       struct Curl_addrinfo *ai;
 
@@ -970,21 +999,26 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
       if(data->share)
         Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 
-      de_cleanup(&de);
-      if(!dns)
+      if(!dns) {
         /* returned failure, bail out nicely */
         Curl_freeaddrinfo(ai);
+      }
       else {
         conn->async.dns = dns;
         *dnsp = dns;
-        return CURLE_OK;
+        result = CURLE_OK;      /* address resolution OK */
       }
-    }
+    } /* address processing done */
+
+    /* Now process any build-specific attributes retrieved from DNS */
+
+    /* All done */
     de_cleanup(&de);
+    return result;
 
-    return CURLE_COULDNT_RESOLVE_HOST;
-  }
+  } /* !data->req.doh.pending */
 
+  /* else wait for pending DOH transactions to complete */
   return CURLE_OK;
 }
 
diff --git a/lib/doh.h b/lib/doh.h
index f522d3308..fc053eddf 100644
--- a/lib/doh.h
+++ b/lib/doh.h
@@ -55,14 +55,16 @@ typedef enum {
   DOH_DNS_UNEXPECTED_TYPE,  /* 9 */
   DOH_DNS_UNEXPECTED_CLASS, /* 10 */
   DOH_NO_CONTENT,           /* 11 */
-  DOH_DNS_BAD_ID            /* 12 */
+  DOH_DNS_BAD_ID,           /* 12 */
+  DOH_DNS_NAME_TOO_LONG     /* 13 */
 } DOHcode;
 
 typedef enum {
   DNS_TYPE_A = 1,
   DNS_TYPE_NS = 2,
   DNS_TYPE_CNAME = 5,
-  DNS_TYPE_AAAA = 28
+  DNS_TYPE_AAAA = 28,
+  DNS_TYPE_DNAME = 39           /* RFC6672 */
 } DNStype;
 
 #define DOH_MAX_ADDR 24
diff --git a/lib/dotdot.c b/lib/dotdot.c
index bb15426c6..de1e1070e 100644
--- a/lib/dotdot.c
+++ b/lib/dotdot.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/dotdot.h b/lib/dotdot.h
index 125af4367..f70b1db3f 100644
--- a/lib/dotdot.h
+++ b/lib/dotdot.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/easy.c b/lib/easy.c
index 9ff93fa89..d281be6dd 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -72,7 +72,7 @@
 #include "warnless.h"
 #include "multiif.h"
 #include "sigpipe.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "setopt.h"
 #include "http_digest.h"
 #include "system_win32.h"
@@ -157,20 +157,20 @@ static CURLcode global_init(long flags, bool memoryfuncs)
 
   if(!Curl_ssl_init()) {
     DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 
 #ifdef WIN32
   if(Curl_win32_init(flags)) {
     DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 #endif
 
 #ifdef __AMIGA__
   if(!Curl_amiga_init()) {
     DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 #endif
 
@@ -182,14 +182,14 @@ static CURLcode global_init(long flags, bool memoryfuncs)
 
   if(Curl_resolver_global_init()) {
     DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 
   (void)Curl_ipv6works();
 
 #if defined(USE_SSH)
   if(Curl_ssh_init()) {
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 #endif
 
@@ -201,6 +201,10 @@ static CURLcode global_init(long flags, bool memoryfuncs)
   Curl_version_init();
 
   return CURLE_OK;
+
+  fail:
+  initialized--; /* undo the increase */
+  return CURLE_FAILED_INIT;
 }
 
 
@@ -1027,9 +1031,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int 
action)
       Curl_update_timer(data->multi);
   }
 
-  /* This transfer may have been moved in or out of the bundle, update
-     the corresponding socket callback, if used */
-  Curl_updatesocket(data);
+  if(!data->state.done)
+    /* This transfer may have been moved in or out of the bundle, update the
+       corresponding socket callback, if used */
+    Curl_updatesocket(data);
 
   return result;
 }
diff --git a/lib/easyif.h b/lib/easyif.h
index 6ba7e549d..8a309c55b 100644
--- a/lib/easyif.h
+++ b/lib/easyif.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/file.h b/lib/file.h
index 20828ad4a..f6b74a7f7 100644
--- a/lib/file.h
+++ b/lib/file.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/ftp.c b/lib/ftp.c
index 250ac566c..acdac63a2 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2039,13 +2039,11 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata 
*conn,
                      &year, &month, &day, &hour, &minute, &second)) {
         /* we have a time, reformat it */
         char timebuf[24];
-        time_t secs = time(NULL);
-
         msnprintf(timebuf, sizeof(timebuf),
                   "%04d%02d%02d %02d:%02d:%02d GMT",
                   year, month, day, hour, minute, second);
         /* now, convert this into a time() value: */
-        data->info.filetime = curl_getdate(timebuf, &secs);
+        data->info.filetime = Curl_getdate_capped(timebuf);
       }
 
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
diff --git a/lib/ftplistparser.h b/lib/ftplistparser.h
index 8128887c0..b34ae9b63 100644
--- a/lib/ftplistparser.h
+++ b/lib/ftplistparser.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/getinfo.h b/lib/getinfo.h
index aecf717f7..8d2af4266 100644
--- a/lib/getinfo.h
+++ b/lib/getinfo.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/gopher.h b/lib/gopher.h
index 501c990a8..dec2557fc 100644
--- a/lib/gopher.h
+++ b/lib/gopher.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/hostcheck.h b/lib/hostcheck.h
index fcc5d40d6..ee23e4366 100644
--- a/lib/hostcheck.h
+++ b/lib/hostcheck.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/hostip.c b/lib/hostip.c
index d4e8f9366..b434b390a 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -1021,6 +1021,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
 CURLcode Curl_resolv_check(struct connectdata *conn,
                            struct Curl_dns_entry **dns)
 {
+#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
+  (void)dns;
+#endif
+
   if(conn->data->set.doh)
     return Curl_doh_is_resolved(conn, dns);
   return Curl_resolver_is_resolved(conn, dns);
diff --git a/lib/hostip4.c b/lib/hostip4.c
index e6ba710d8..2636851e6 100644
--- a/lib/hostip4.c
+++ b/lib/hostip4.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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,6 +131,16 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
   struct in_addr in;
   struct hostent *buf = NULL;
 
+#ifdef ENABLE_IPV6
+  {
+    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 */
+      return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+  }
+#endif /* ENABLE_IPV6 */
+
   if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
     /* This is a dotted IP address 123.123.123.123-style */
     return Curl_ip2addr(AF_INET, &in, hostname, port);
diff --git a/lib/hostsyn.c b/lib/hostsyn.c
index 3de6746f5..9e31008d2 100644
--- a/lib/hostsyn.c
+++ b/lib/hostsyn.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/http.c b/lib/http.c
index 7d3f7b021..db79c7d3d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1617,7 +1617,8 @@ CURLcode Curl_http_done(struct connectdata *conn,
     Curl_add_buffer_free(&http->send_buffer);
   }
 
-  Curl_http2_done(conn, premature);
+  Curl_http2_done(data, premature);
+  Curl_quic_done(data, premature);
 
   Curl_mime_cleanpart(&http->form);
 
@@ -3973,7 +3974,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy 
*data,
     else if(checkprefix("Retry-After:", k->p)) {
       /* Retry-After = HTTP-date / delay-seconds */
       curl_off_t retry_after = 0; /* zero for unknown or "now" */
-      time_t date = curl_getdate(&k->p[12], NULL);
+      time_t date = Curl_getdate_capped(&k->p[12]);
       if(-1 == date) {
         /* not a date, try it as a decimal number */
         (void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
@@ -4031,9 +4032,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy 
*data,
 #endif
     else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) &&
             (data->set.timecondition || data->set.get_filetime) ) {
-      time_t secs = time(NULL);
-      k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
-                                  &secs);
+      k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:"));
       if(data->set.get_filetime)
         data->info.filetime = k->timeofdoc;
     }
diff --git a/lib/http.h b/lib/http.h
index 9b446e8aa..a59c96ba4 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -193,12 +193,17 @@ struct HTTP {
 #ifdef ENABLE_QUIC
   /*********** for HTTP/3 we store stream-local data here *************/
   int64_t stream3_id; /* stream we are interested in */
+  bool firstheader;  /* FALSE until headers arrive */
   bool firstbody;  /* FALSE until body arrives */
   bool h3req;    /* FALSE until request is issued */
   bool upload_done;
 #endif
 #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 */
 #endif
 };
 
diff --git a/lib/http2.c b/lib/http2.c
index 631c92da7..7d44e2e4b 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -68,7 +68,7 @@
 #ifdef DEBUG_HTTP2
 #define H2BUGF(x) x
 #else
-#define H2BUGF(x) do { } WHILE_FALSE
+#define H2BUGF(x) do { } while(0)
 #endif
 
 
@@ -1169,11 +1169,10 @@ static void populate_settings(struct connectdata *conn,
   httpc->local_settings_num = 3;
 }
 
-void Curl_http2_done(struct connectdata *conn, bool premature)
+void Curl_http2_done(struct Curl_easy *data, bool premature)
 {
-  struct Curl_easy *data = conn->data;
   struct HTTP *http = data->req.protop;
-  struct http_conn *httpc = &conn->proto.httpc;
+  struct http_conn *httpc = &data->conn->proto.httpc;
 
   /* there might be allocated resources done before this got the 'h2' pointer
      setup */
diff --git a/lib/http2.h b/lib/http2.h
index 93058ccb3..12d36eef9 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -50,7 +50,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
 /* called from http_setup_conn */
 void Curl_http2_setup_conn(struct connectdata *conn);
 void Curl_http2_setup_req(struct Curl_easy *data);
-void Curl_http2_done(struct connectdata *conn, bool premature);
+void Curl_http2_done(struct Curl_easy *data, bool premature);
 CURLcode Curl_http2_done_sending(struct connectdata *conn);
 CURLcode Curl_http2_add_child(struct Curl_easy *parent,
                               struct Curl_easy *child,
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index e4a4fe05d..342b2424f 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -44,9 +44,7 @@
 
 /* SSL backend-specific #if branches in this file must be kept in the order
    documented in curl_ntlm_core. */
-#if defined(NTLM_NEEDS_NSS_INIT)
-#include "vtls/nssg.h"
-#elif defined(USE_WINDOWS_SSPI)
+#if defined(USE_WINDOWS_SSPI)
 #include "curl_sspi.h"
 #endif
 
@@ -137,11 +135,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool 
proxy)
   DEBUGASSERT(conn);
   DEBUGASSERT(conn->data);
 
-#if defined(NTLM_NEEDS_NSS_INIT)
-  if(CURLE_OK != Curl_nss_force_init(conn->data))
-    return CURLE_OUT_OF_MEMORY;
-#endif
-
   if(proxy) {
     allocuserpwd = &conn->allocptr.proxyuserpwd;
     userp = conn->http_proxy.user;
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index b6f31af32..440405460 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -58,8 +58,9 @@ static CURLcode https_proxy_connect(struct connectdata *conn, 
int sockindex)
       Curl_ssl_connect_nonblocking(conn, sockindex,
                                    &conn->bits.proxy_ssl_connected[sockindex]);
     if(result)
-      conn->bits.close = TRUE; /* a failed connection is marked for closure to
-                                  prevent (bad) re-use or similar */
+      /* a failed connection is marked for closure to prevent (bad) re-use or
+         similar */
+      connclose(conn, "TLS handshake failed");
   }
   return result;
 #else
diff --git a/lib/imap.h b/lib/imap.h
index 0efcfd293..4786f5624 100644
--- a/lib/imap.h
+++ b/lib/imap.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2009 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/inet_ntop.c b/lib/inet_ntop.c
index 855981c66..9a5af7f42 100644
--- a/lib/inet_ntop.c
+++ b/lib/inet_ntop.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2001  Internet Software Consortium.
+ * Copyright (C) 1996-2019  Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/inet_ntop.h b/lib/inet_ntop.h
index d150bb693..9d3f237f3 100644
--- a/lib/inet_ntop.h
+++ b/lib/inet_ntop.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/inet_pton.c b/lib/inet_pton.c
index 0d65ae0ec..9c87a0562 100644
--- a/lib/inet_pton.c
+++ b/lib/inet_pton.c
@@ -1,6 +1,6 @@
 /* This is from the BIND 4.9.4 release, modified to compile by itself */
 
-/* Copyright (c) 1996 by Internet Software Consortium.
+/* Copyright (c) 1996 - 2019 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/inet_pton.h b/lib/inet_pton.h
index 0209b9b7b..e695af9c6 100644
--- a/lib/inet_pton.h
+++ b/lib/inet_pton.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/krb5.c b/lib/krb5.c
index 5a47d481b..f50287aec 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -2,7 +2,7 @@
  *
  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2017 Daniel Stenberg
+ * Copyright (c) 2004 - 2019 Daniel Stenberg
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/lib/ldap.c b/lib/ldap.c
index 95f2f1a98..60a423d45 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -112,7 +112,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp);
   #define LDAP_TRACE(x)   do { \
                             _ldap_trace("%u: ", __LINE__); \
                             _ldap_trace x; \
-                          } WHILE_FALSE
+                          } while(0)
 
   static void _ldap_trace(const char *fmt, ...);
 #else
diff --git a/lib/llist.h b/lib/llist.h
index b9d4c89a9..a5e2ecbfb 100644
--- a/lib/llist.h
+++ b/lib/llist.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/memdebug.h b/lib/memdebug.h
index 5236f60fa..7ca442626 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -169,6 +169,6 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const 
char *source);
  */
 
 #define Curl_safefree(ptr) \
-  do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
+  do { free((ptr)); (ptr) = NULL;} while(0)
 
 #endif /* HEADER_CURL_MEMDEBUG_H */
diff --git a/lib/mprintf.c b/lib/mprintf.c
index 4c43ad7b2..726853312 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1999 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1999 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -104,7 +104,7 @@ static const char upper_digits[] = 
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
       done++; \
     else \
      return done; /* return immediately on failure */ \
-  } WHILE_FALSE
+  } while(0)
 
 /* Data type to read from the arglist */
 typedef enum {
diff --git a/lib/multi.c b/lib/multi.c
index 4875afec5..dbf95f473 100755
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -46,6 +46,7 @@
 #include "connect.h"
 #include "http_proxy.h"
 #include "http2.h"
+#include "socketpair.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -259,6 +260,7 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash 
*sh,
 
   /* make/add new hash entry */
   if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+    Curl_hash_destroy(&check->transfers);
     free(check);
     return NULL; /* major failure */
   }
@@ -367,6 +369,21 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* 
socket hash */
 
   /* -1 means it not set by user, use the default value */
   multi->maxconnects = -1;
+
+#ifdef ENABLE_WAKEUP
+  if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
+    multi->wakeup_pair[0] = CURL_SOCKET_BAD;
+    multi->wakeup_pair[1] = CURL_SOCKET_BAD;
+  }
+  else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 ||
+          curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) {
+    sclose(multi->wakeup_pair[0]);
+    sclose(multi->wakeup_pair[1]);
+    multi->wakeup_pair[0] = CURL_SOCKET_BAD;
+    multi->wakeup_pair[1] = CURL_SOCKET_BAD;
+  }
+#endif
+
   return multi;
 
   error:
@@ -531,6 +548,8 @@ static CURLcode multi_done(struct Curl_easy *data,
     /* Stop if multi_done() has already been called */
     return CURLE_OK;
 
+  conn->data = data; /* ensure the connection uses this transfer now */
+
   /* Stop the resolver and free its own resources (but not dns_entry yet). */
   Curl_resolver_kill(conn);
 
@@ -567,15 +586,17 @@ static CURLcode multi_done(struct Curl_easy *data,
 
   process_pending_handles(data->multi); /* connection / multiplex */
 
+  CONN_LOCK(data);
   detach_connnection(data);
   if(CONN_INUSE(conn)) {
     /* Stop if still used. */
+    CONN_UNLOCK(data);
     DEBUGF(infof(data, "Connection still in use %zu, "
                  "no more multi_done now!\n",
                  conn->easyq.size));
     return CURLE_OK;
   }
-
+  conn->data = NULL; /* the connection now has no owner */
   data->state.done = TRUE; /* called just now! */
 
   if(conn->dns_entry) {
@@ -618,7 +639,10 @@ static CURLcode multi_done(struct Curl_easy *data,
 #endif
      ) || conn->bits.close
        || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
-    CURLcode res2 = Curl_disconnect(data, conn, premature);
+    CURLcode res2;
+    connclose(conn, "disconnecting");
+    CONN_UNLOCK(data);
+    res2 = Curl_disconnect(data, conn, premature);
 
     /* If we had an error already, make sure we return that one. But
        if we got a new error, return that. */
@@ -635,9 +659,9 @@ static CURLcode multi_done(struct Curl_easy *data,
               conn->bits.httpproxy ? conn->http_proxy.host.dispname :
               conn->bits.conn_to_host ? conn->conn_to_host.dispname :
               conn->host.dispname);
-
     /* the connection is no longer in use by this transfer */
-    if(Curl_conncache_return_conn(conn)) {
+    CONN_UNLOCK(data);
+    if(Curl_conncache_return_conn(data, conn)) {
       /* remember the most recently used connection */
       data->state.lastconnect = conn;
       infof(data, "%s\n", buffer);
@@ -695,11 +719,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi 
*multi,
     easy_owns_conn = TRUE;
   }
 
-  /* The timer must be shut down before data->multi is set to NULL,
-     else the timenode will remain in the splay tree after
-     curl_easy_cleanup is called. */
-  Curl_expire_clear(data);
-
   if(data->conn) {
 
     /* we must call multi_done() here (if we still own the connection) so that
@@ -715,6 +734,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi 
*multi,
     }
   }
 
+  /* The timer must be shut down before data->multi is set to NULL, else the
+     timenode will remain in the splay tree after curl_easy_cleanup is
+     called. Do it after multi_done() in case that sets another time! */
+  Curl_expire_clear(data);
+
   if(data->connect_queue.ptr)
     /* the handle was in the pending list waiting for an available connection,
        so go ahead and remove it */
@@ -744,10 +768,8 @@ 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) {
-    data->conn->data = NULL;
+  if(data->conn)
     detach_connnection(data);
-  }
 
 #ifdef USE_LIBPSL
   /* Remove the PSL association. */
@@ -1005,7 +1027,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
                                  unsigned int extra_nfds,
                                  int timeout_ms,
                                  int *ret,
-                                 bool extrawait) /* when no socket, wait */
+                                 bool extrawait, /* when no socket, wait */
+                                 bool use_wakeup)
 {
   struct Curl_easy *data;
   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
@@ -1059,6 +1082,12 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
   curlfds = nfds; /* number of internal file descriptors */
   nfds += extra_nfds; /* add the externally provided ones */
 
+#ifdef ENABLE_WAKEUP
+  if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+    ++nfds;
+  }
+#endif
+
   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
@@ -1117,6 +1146,14 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
     ++nfds;
   }
 
+#ifdef ENABLE_WAKEUP
+  if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+    ufds[nfds].fd = multi->wakeup_pair[0];
+    ufds[nfds].events = POLLIN;
+    ++nfds;
+  }
+#endif
+
   if(nfds) {
     int pollrc;
     /* wait... */
@@ -1140,6 +1177,29 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
 
         extra_fds[i].revents = mask;
       }
+
+#ifdef ENABLE_WAKEUP
+      if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+        if(ufds[curlfds + extra_nfds].revents & POLLIN) {
+          char buf[64];
+          while(1) {
+            /* the reading socket is non-blocking, try to read
+               data from it until it receives an error (except EINTR).
+               In normal cases it will get EAGAIN or EWOULDBLOCK
+               when there is no more data, breaking the loop. */
+            if(sread(multi->wakeup_pair[0], buf, sizeof(buf)) < 0) {
+#ifndef USE_WINSOCK
+              if(EINTR == SOCKERRNO)
+                continue;
+#endif
+              break;
+            }
+          }
+          /* do not count the wakeup socket into the returned value */
+          retcode--;
+        }
+      }
+#endif
     }
   }
 
@@ -1147,7 +1207,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
     free(ufds);
   if(ret)
     *ret = retcode;
-  if(!extrawait || extra_fds || curlfds)
+  if(!extrawait || nfds)
     /* if any socket was checked */
     ;
   else {
@@ -1157,6 +1217,10 @@ static CURLMcode Curl_multi_wait(struct Curl_multi 
*multi,
     if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
       if(sleep_ms > timeout_ms)
         sleep_ms = timeout_ms;
+      /* when there are no easy handles in the multi, this holds a -1
+         timeout */
+      else if((sleep_ms < 0) && extrawait)
+        sleep_ms = timeout_ms;
       Curl_wait_ms((int)sleep_ms);
     }
   }
@@ -1170,7 +1234,8 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
                           int timeout_ms,
                           int *ret)
 {
-  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE);
+  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
+                         FALSE);
 }
 
 CURLMcode curl_multi_poll(struct Curl_multi *multi,
@@ -1179,7 +1244,55 @@ CURLMcode curl_multi_poll(struct Curl_multi *multi,
                           int timeout_ms,
                           int *ret)
 {
-  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE);
+  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
+                         TRUE);
+}
+
+CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
+{
+  /* this function is usually called from another thread,
+     it has to be careful only to access parts of the
+     Curl_multi struct that are constant */
+
+  /* GOOD_MULTI_HANDLE can be safely called */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+#ifdef ENABLE_WAKEUP
+  /* 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 */
+  if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
+    char buf[1];
+    buf[0] = 1;
+    while(1) {
+      /* swrite() is not thread-safe in general, because concurrent calls
+         can have their messages interleaved, but in this case the content
+         of the messages does not matter, which makes it ok to call.
+
+         The write socket is set to non-blocking, this way this function
+         cannot block, making it safe to call even from the same thread
+         that will call Curl_multi_wait(). If swrite() returns that it
+         would block, it's considered successful because it means that
+         previous calls to this function will wake up the poll(). */
+      if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
+        int err = SOCKERRNO;
+        int return_success;
+#ifdef USE_WINSOCK
+        return_success = WSAEWOULDBLOCK == err;
+#else
+        if(EINTR == err)
+          continue;
+        return_success = EWOULDBLOCK == err || EAGAIN == err;
+#endif
+        if(!return_success)
+          return CURLM_WAKEUP_FAILURE;
+      }
+      return CURLM_OK;
+    }
+  }
+#endif
+  return CURLM_WAKEUP_FAILURE;
 }
 
 /*
@@ -1242,6 +1355,7 @@ static CURLcode multi_do(struct Curl_easy *data, bool 
*done)
 
   DEBUGASSERT(conn);
   DEBUGASSERT(conn->handler);
+  DEBUGASSERT(conn->data == data);
 
   if(conn->handler->do_it) {
     /* generic protocol-specific function pointer set in curl_connect() */
@@ -2305,6 +2419,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
 
     Curl_hash_destroy(&multi->hostcache);
     Curl_psl_destroy(&multi->psl);
+
+#ifdef ENABLE_WAKEUP
+    sclose(multi->wakeup_pair[0]);
+    sclose(multi->wakeup_pair[1]);
+#endif
     free(multi);
 
     return CURLM_OK;
diff --git a/lib/multihandle.h b/lib/multihandle.h
index b65bd9638..a26fb619a 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.h
@@ -24,6 +24,7 @@
 
 #include "conncache.h"
 #include "psl.h"
+#include "socketpair.h"
 
 struct Curl_message {
   struct curl_llist_element list;
@@ -66,6 +67,10 @@ typedef enum {
 
 #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
 
+#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS)
+#define ENABLE_WAKEUP
+#endif
+
 /* This is the struct known as CURLM on the outside */
 struct Curl_multi {
   /* First a simple identifier to easier detect if a user mix up
@@ -134,6 +139,11 @@ struct Curl_multi {
                                     previous callback */
   bool in_callback;            /* true while executing a callback */
   long max_concurrent_streams; /* max concurrent streams client to support */
+
+#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 /* HEADER_CURL_MULTIHANDLE_H */
diff --git a/lib/nonblock.c b/lib/nonblock.c
index 4d105c1fe..abeb6598c 100644
--- a/lib/nonblock.c
+++ b/lib/nonblock.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/nonblock.h b/lib/nonblock.h
index eb45910c5..6be2aea50 100644
--- a/lib/nonblock.h
+++ b/lib/nonblock.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/parsedate.c b/lib/parsedate.c
index 428101741..a06a60f64 100644
--- a/lib/parsedate.c
+++ b/lib/parsedate.c
@@ -587,6 +587,30 @@ time_t curl_getdate(const char *p, const time_t *now)
   return -1;
 }
 
+/* Curl_getdate_capped() differs from curl_getdate() in that this will return
+   TIME_T_MAX in case the parsed time value was too big, instead of an
+   error. */
+
+time_t Curl_getdate_capped(const char *p)
+{
+  time_t parsed = -1;
+  int rc = parsedate(p, &parsed);
+
+  switch(rc) {
+  case PARSEDATE_OK:
+    if(parsed == -1)
+      /* avoid returning -1 for a working scenario */
+      parsed++;
+    return parsed;
+  case PARSEDATE_LATER:
+    /* this returns the maximum time value */
+    return parsed;
+  default:
+    return -1; /* everything else is fail */
+  }
+  /* UNREACHABLE */
+}
+
 /*
  * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
  * gmtime_r() or gmtime() functions anywhere else but here.
diff --git a/lib/parsedate.h b/lib/parsedate.h
index 8dc3b90ec..8c7ae94e4 100644
--- a/lib/parsedate.h
+++ b/lib/parsedate.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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,4 +27,10 @@ extern const char * const Curl_month[12];
 
 CURLcode Curl_gmtime(time_t intime, struct tm *store);
 
+/* Curl_getdate_capped() differs from curl_getdate() in that this will return
+   TIME_T_MAX in case the parsed time value was too big, instead of an
+   error. */
+
+time_t Curl_getdate_capped(const char *p);
+
 #endif /* HEADER_CURL_PARSEDATE_H */
diff --git a/lib/pop3.h b/lib/pop3.h
index a8e697cde..3ba799977 100644
--- a/lib/pop3.h
+++ b/lib/pop3.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2009 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/progress.c b/lib/progress.c
index 2aa929599..60a941ab2 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -594,11 +594,13 @@ int Curl_pgrsUpdate(struct connectdata *conn)
                                    data->progress.size_ul,
                                    data->progress.uploaded);
       Curl_set_in_callback(data, false);
-      if(result)
-        failf(data, "Callback aborted");
-      return result;
+      if(result != CURL_PROGRESSFUNC_CONTINUE) {
+        if(result)
+          failf(data, "Callback aborted");
+        return result;
+      }
     }
-    if(data->set.fprogress) {
+    else if(data->set.fprogress) {
       int result;
       /* The older deprecated callback is set, call that */
       Curl_set_in_callback(data, true);
@@ -608,9 +610,11 @@ int Curl_pgrsUpdate(struct connectdata *conn)
                                    (double)data->progress.size_ul,
                                    (double)data->progress.uploaded);
       Curl_set_in_callback(data, false);
-      if(result)
-        failf(data, "Callback aborted");
-      return result;
+      if(result != CURL_PROGRESSFUNC_CONTINUE) {
+        if(result)
+          failf(data, "Callback aborted");
+        return result;
+      }
     }
 
     if(showprogress)
diff --git a/lib/quic.h b/lib/quic.h
index 6c132a324..1eb23e976 100644
--- a/lib/quic.h
+++ b/lib/quic.h
@@ -45,9 +45,13 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
                                 bool *connected);
 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);
 
 #else /* ENABLE_QUIC */
 #define Curl_quic_done_sending(x)
+#define Curl_quic_done(x,y)
+#define Curl_quic_data_pending(x)
 #endif /* !ENABLE_QUIC */
 
 #endif /* HEADER_CURL_QUIC_H */
diff --git a/lib/rtsp.h b/lib/rtsp.h
index 2f9cc32c8..1aae86456 100644
--- a/lib/rtsp.h
+++ b/lib/rtsp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/select.c b/lib/select.c
index f7c53e7b3..190fb51ff 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/select.h b/lib/select.h
index f5652a74f..687ab164c 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -109,7 +109,7 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* 
writes,
     SET_SOCKERRNO(EINVAL); \
     return -1; \
   } \
-} WHILE_FALSE
+} while(0)
 #endif
 
 #endif /* HEADER_CURL_SELECT_H */
diff --git a/lib/sendf.c b/lib/sendf.c
index 5f1f7f316..4bfc97864 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -36,7 +36,7 @@
 #include "sendf.h"
 #include "connect.h"
 #include "vtls/vtls.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "easyif.h"
 #include "multiif.h"
 #include "non-ascii.h"
@@ -224,7 +224,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, 
int sockindex)
   (void)sockindex;
   return false;
 }
-#define pre_receive_plain(c,n) do {} WHILE_FALSE
+#define pre_receive_plain(c,n) do {} while(0)
 #define get_pre_recved(c,n,b,l) 0
 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 
diff --git a/lib/setopt.c b/lib/setopt.c
index e18fa1149..29cea3590 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2133,6 +2133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption 
option, va_list param)
     data->set.ssl.enable_beast =
       (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
     data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
     break;
 
 #ifndef CURL_DISABLE_PROXY
@@ -2141,6 +2142,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption 
option, va_list param)
     data->set.proxy_ssl.enable_beast =
       (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);
     break;
 #endif
 
@@ -2612,14 +2614,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, 
CURLoption option, va_list param)
     result = CURLE_NOT_BUILT_IN;
 #endif
     break;
-#ifdef USE_NGHTTP2
   case CURLOPT_SSL_ENABLE_NPN:
     data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
     break;
   case CURLOPT_SSL_ENABLE_ALPN:
     data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
     break;
-#endif
 #ifdef USE_UNIX_SOCKETS
   case CURLOPT_UNIX_SOCKET_PATH:
     data->set.abstract_unix_socket = FALSE;
diff --git a/lib/sha256.c b/lib/sha256.c
index f9287af23..bcaaeae30 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Florin Petriuc, <address@hidden>
+ * Copyright (C) 1998 - 2019, Florin Petriuc, <address@hidden>
  *
  * 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/lib/slist.c b/lib/slist.c
index 093465c97..b59eda449 100644
--- a/lib/slist.c
+++ b/lib/slist.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/slist.h b/lib/slist.h
index d73dbf672..799b3c060 100644
--- a/lib/slist.h
+++ b/lib/slist.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/smtp.h b/lib/smtp.h
index b67340a40..20fc08119 100644
--- a/lib/smtp.h
+++ b/lib/smtp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2009 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/sockaddr.h b/lib/sockaddr.h
index db146803a..b037ee06c 100644
--- a/lib/sockaddr.h
+++ b/lib/sockaddr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/socks.h b/lib/socks.h
index daa07c127..3b319a6ef 100644
--- a/lib/socks.h
+++ b/lib/socks.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/strdup.c b/lib/strdup.c
index e1330ddf1..cca97f3c6 100644
--- a/lib/strdup.c
+++ b/lib/strdup.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/strerror.c b/lib/strerror.c
index e3be16397..c0b92692d 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -314,6 +314,9 @@ curl_easy_strerror(CURLcode error)
   case CURLE_AUTH_ERROR:
     return "An authentication function returned an error";
 
+  case CURLE_HTTP3:
+    return "HTTP/3 error";
+
     /* error codes not used by current libcurl */
   case CURLE_OBSOLETE20:
   case CURLE_OBSOLETE24:
@@ -386,6 +389,9 @@ curl_multi_strerror(CURLMcode error)
   case CURLM_RECURSIVE_API_CALL:
     return "API function called from within callback";
 
+  case CURLM_WAKEUP_FAILURE:
+    return "Wakeup is unavailable or failed";
+
   case CURLM_LAST:
     break;
   }
@@ -436,19 +442,23 @@ curl_share_strerror(CURLSHcode error)
 }
 
 #ifdef USE_WINSOCK
-
-/* This function handles most / all (?) Winsock errors curl is able to produce.
+/* This is a helper function for Curl_strerror that converts Winsock error
+ * codes (WSAGetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
  */
 static const char *
 get_winsock_error (int err, char *buf, size_t len)
 {
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
-  DWORD old_win_err = GetLastError();
-#endif
-  int old_errno = errno;
   const char *p;
 
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  if(!len)
+    return NULL;
+
+  *buf = '\0';
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  return NULL;
+#else
   switch(err) {
   case WSAEINTR:
     p = "Call interrupted";
@@ -617,26 +627,63 @@ get_winsock_error (int err, char *buf, size_t len)
   default:
     return NULL;
   }
-#else
-  if(!err)
-    return NULL;
-  else
-    p = "error";
-#endif
   strncpy(buf, p, len);
   buf [len-1] = '\0';
+  return buf;
+#endif
+}
+#endif   /* USE_WINSOCK */
 
-  if(errno != old_errno)
-    errno = old_errno;
+#if defined(WIN32) || defined(_WIN32_WCE)
+/* This is a helper function for Curl_strerror that converts Windows API error
+ * codes (GetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
+ */
+static const char *
+get_winapi_error(int err, char *buf, size_t buflen)
+{
+  char *p;
 
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
-  if(old_win_err != GetLastError())
-    SetLastError(old_win_err);
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
+
+#ifdef _WIN32_WCE
+  {
+    wchar_t wbuf[256];
+    wbuf[0] = L'\0';
+
+    if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+                     LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+      size_t written = wcstombs(buf, wbuf, buflen - 1);
+      if(written != (size_t)-1)
+        buf[written] = '\0';
+      else
+        *buf = '\0';
+    }
+  }
+#else
+  if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+                     LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) {
+    *buf = '\0';
+  }
 #endif
 
-  return buf;
+  /* Truncate multiple lines */
+  p = strchr(buf, '\n');
+  if(p) {
+    if(p > buf && *(p-1) == '\r')
+      *(p-1) = '\0';
+    else
+      *p = '\0';
+  }
+
+  return (*buf ? buf : NULL);
 }
-#endif   /* USE_WINSOCK */
+#endif /* WIN32 || _WIN32_WCE */
 
 /*
  * Our thread-safe and smart strerror() replacement.
@@ -648,6 +695,14 @@ get_winsock_error (int err, char *buf, size_t len)
  *
  * We don't do range checking (on systems other than Windows) since there is
  * no good reliable and portable way to do it.
+ *
+ * On Windows different types of error codes overlap. This function has an
+ * order of preference when trying to match error codes:
+ * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError).
+ *
+ * It may be more correct to call one of the variant functions instead:
+ * Call Curl_sspi_strerror if the error code is definitely Windows SSPI.
+ * Call Curl_winapi_strerror if the error code is definitely Windows API.
  */
 const char *Curl_strerror(int err, char *buf, size_t buflen)
 {
@@ -658,35 +713,30 @@ const char *Curl_strerror(int err, char *buf, size_t 
buflen)
   char *p;
   size_t max;
 
+  if(!buflen)
+    return NULL;
+
   DEBUGASSERT(err >= 0);
 
   max = buflen - 1;
   *buf = '\0';
 
-#ifdef USE_WINSOCK
-
-#ifdef _WIN32_WCE
-  {
-    wchar_t wbuf[256];
-    wbuf[0] = L'\0';
-
-    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
-                  LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
-    wcstombs(buf, wbuf, max);
-  }
-#else
+#if defined(WIN32) || defined(_WIN32_WCE)
+#if defined(WIN32)
   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
   if(err >= 0 && err < sys_nerr)
     strncpy(buf, strerror(err), max);
-  else {
-    if(!get_winsock_error(err, buf, max) &&
-       !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
-                       LANG_NEUTRAL, buf, (DWORD)max, NULL))
+  else
+#endif
+  {
+    if(
+#ifdef USE_WINSOCK
+       !get_winsock_error(err, buf, max) &&
+#endif
+       !get_winapi_error((DWORD)err, buf, max))
       msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
   }
-#endif
-
-#else /* not USE_WINSOCK coming up */
+#else /* not Windows coming up */
 
 #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
  /*
@@ -734,7 +784,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
   }
 #endif
 
-#endif /* end of ! USE_WINSOCK */
+#endif /* end of not Windows */
 
   buf[max] = '\0'; /* make sure the string is zero terminated */
 
@@ -757,7 +807,52 @@ const char *Curl_strerror(int err, char *buf, size_t 
buflen)
   return buf;
 }
 
+/*
+ * Curl_winapi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows API.
+ */
+#if defined(WIN32) || defined(_WIN32_WCE)
+const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  DWORD old_win_err = GetLastError();
+#endif
+  int old_errno = errno;
+
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  if(!get_winapi_error(err, buf, buflen)) {
+    msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err);
+  }
+#else
+  {
+    const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
+    strncpy(buf, txt, buflen);
+    buf[buflen - 1] = '\0';
+  }
+#endif
+
+  if(errno != old_errno)
+    errno = old_errno;
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  if(old_win_err != GetLastError())
+    SetLastError(old_win_err);
+#endif
+
+  return buf;
+}
+#endif /* WIN32 || _WIN32_WCE */
+
 #ifdef USE_WINDOWS_SSPI
+/*
+ * Curl_sspi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows SSPI.
+ */
 const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
 {
 #ifdef PRESERVE_WINDOWS_ERROR_CODE
@@ -765,18 +860,11 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t 
buflen)
 #endif
   int old_errno = errno;
   const char *txt;
-  char *outbuf;
-  size_t outmax;
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-  char txtbuf[80];
-  char msgbuf[256];
-  char *p, *str, *msg = NULL;
-  bool msg_formatted = FALSE;
-#endif
 
-  outbuf = buf;
-  outmax = buflen - 1;
-  *outbuf = '\0';
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 
@@ -784,314 +872,121 @@ const char *Curl_sspi_strerror(int err, char *buf, 
size_t buflen)
     case SEC_E_OK:
       txt = "No error";
       break;
-    case CRYPT_E_REVOKED:
-      txt = "CRYPT_E_REVOKED";
-      break;
-    case SEC_E_ALGORITHM_MISMATCH:
-      txt = "SEC_E_ALGORITHM_MISMATCH";
-      break;
-    case SEC_E_BAD_BINDINGS:
-      txt = "SEC_E_BAD_BINDINGS";
-      break;
-    case SEC_E_BAD_PKGID:
-      txt = "SEC_E_BAD_PKGID";
-      break;
-    case SEC_E_BUFFER_TOO_SMALL:
-      txt = "SEC_E_BUFFER_TOO_SMALL";
-      break;
-    case SEC_E_CANNOT_INSTALL:
-      txt = "SEC_E_CANNOT_INSTALL";
-      break;
-    case SEC_E_CANNOT_PACK:
-      txt = "SEC_E_CANNOT_PACK";
-      break;
-    case SEC_E_CERT_EXPIRED:
-      txt = "SEC_E_CERT_EXPIRED";
-      break;
-    case SEC_E_CERT_UNKNOWN:
-      txt = "SEC_E_CERT_UNKNOWN";
-      break;
-    case SEC_E_CERT_WRONG_USAGE:
-      txt = "SEC_E_CERT_WRONG_USAGE";
-      break;
-    case SEC_E_CONTEXT_EXPIRED:
-      txt = "SEC_E_CONTEXT_EXPIRED";
-      break;
-    case SEC_E_CROSSREALM_DELEGATION_FAILURE:
-      txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
-      break;
-    case SEC_E_CRYPTO_SYSTEM_INVALID:
-      txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
-      break;
-    case SEC_E_DECRYPT_FAILURE:
-      txt = "SEC_E_DECRYPT_FAILURE";
-      break;
-    case SEC_E_DELEGATION_POLICY:
-      txt = "SEC_E_DELEGATION_POLICY";
-      break;
-    case SEC_E_DELEGATION_REQUIRED:
-      txt = "SEC_E_DELEGATION_REQUIRED";
-      break;
-    case SEC_E_DOWNGRADE_DETECTED:
-      txt = "SEC_E_DOWNGRADE_DETECTED";
-      break;
-    case SEC_E_ENCRYPT_FAILURE:
-      txt = "SEC_E_ENCRYPT_FAILURE";
-      break;
-    case SEC_E_ILLEGAL_MESSAGE:
-      txt = "SEC_E_ILLEGAL_MESSAGE";
-      break;
-    case SEC_E_INCOMPLETE_CREDENTIALS:
-      txt = "SEC_E_INCOMPLETE_CREDENTIALS";
-      break;
-    case SEC_E_INCOMPLETE_MESSAGE:
-      txt = "SEC_E_INCOMPLETE_MESSAGE";
-      break;
-    case SEC_E_INSUFFICIENT_MEMORY:
-      txt = "SEC_E_INSUFFICIENT_MEMORY";
-      break;
-    case SEC_E_INTERNAL_ERROR:
-      txt = "SEC_E_INTERNAL_ERROR";
-      break;
-    case SEC_E_INVALID_HANDLE:
-      txt = "SEC_E_INVALID_HANDLE";
-      break;
-    case SEC_E_INVALID_PARAMETER:
-      txt = "SEC_E_INVALID_PARAMETER";
-      break;
-    case SEC_E_INVALID_TOKEN:
-      txt = "SEC_E_INVALID_TOKEN";
-      break;
-    case SEC_E_ISSUING_CA_UNTRUSTED:
-      txt = "SEC_E_ISSUING_CA_UNTRUSTED";
-      break;
-    case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
-      txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
-      break;
-    case SEC_E_KDC_CERT_EXPIRED:
-      txt = "SEC_E_KDC_CERT_EXPIRED";
-      break;
-    case SEC_E_KDC_CERT_REVOKED:
-      txt = "SEC_E_KDC_CERT_REVOKED";
-      break;
-    case SEC_E_KDC_INVALID_REQUEST:
-      txt = "SEC_E_KDC_INVALID_REQUEST";
-      break;
-    case SEC_E_KDC_UNABLE_TO_REFER:
-      txt = "SEC_E_KDC_UNABLE_TO_REFER";
-      break;
-    case SEC_E_KDC_UNKNOWN_ETYPE:
-      txt = "SEC_E_KDC_UNKNOWN_ETYPE";
-      break;
-    case SEC_E_LOGON_DENIED:
-      txt = "SEC_E_LOGON_DENIED";
-      break;
-    case SEC_E_MAX_REFERRALS_EXCEEDED:
-      txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
-      break;
-    case SEC_E_MESSAGE_ALTERED:
-      txt = "SEC_E_MESSAGE_ALTERED";
-      break;
-    case SEC_E_MULTIPLE_ACCOUNTS:
-      txt = "SEC_E_MULTIPLE_ACCOUNTS";
-      break;
-    case SEC_E_MUST_BE_KDC:
-      txt = "SEC_E_MUST_BE_KDC";
-      break;
-    case SEC_E_NOT_OWNER:
-      txt = "SEC_E_NOT_OWNER";
-      break;
-    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
-      txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
-      break;
-    case SEC_E_NO_CREDENTIALS:
-      txt = "SEC_E_NO_CREDENTIALS";
-      break;
-    case SEC_E_NO_IMPERSONATION:
-      txt = "SEC_E_NO_IMPERSONATION";
-      break;
-    case SEC_E_NO_IP_ADDRESSES:
-      txt = "SEC_E_NO_IP_ADDRESSES";
-      break;
-    case SEC_E_NO_KERB_KEY:
-      txt = "SEC_E_NO_KERB_KEY";
-      break;
-    case SEC_E_NO_PA_DATA:
-      txt = "SEC_E_NO_PA_DATA";
-      break;
-    case SEC_E_NO_S4U_PROT_SUPPORT:
-      txt = "SEC_E_NO_S4U_PROT_SUPPORT";
-      break;
-    case SEC_E_NO_TGT_REPLY:
-      txt = "SEC_E_NO_TGT_REPLY";
-      break;
-    case SEC_E_OUT_OF_SEQUENCE:
-      txt = "SEC_E_OUT_OF_SEQUENCE";
-      break;
-    case SEC_E_PKINIT_CLIENT_FAILURE:
-      txt = "SEC_E_PKINIT_CLIENT_FAILURE";
-      break;
-    case SEC_E_PKINIT_NAME_MISMATCH:
-      txt = "SEC_E_PKINIT_NAME_MISMATCH";
-      break;
-    case SEC_E_POLICY_NLTM_ONLY:
-      txt = "SEC_E_POLICY_NLTM_ONLY";
-      break;
-    case SEC_E_QOP_NOT_SUPPORTED:
-      txt = "SEC_E_QOP_NOT_SUPPORTED";
-      break;
-    case SEC_E_REVOCATION_OFFLINE_C:
-      txt = "SEC_E_REVOCATION_OFFLINE_C";
-      break;
-    case SEC_E_REVOCATION_OFFLINE_KDC:
-      txt = "SEC_E_REVOCATION_OFFLINE_KDC";
-      break;
-    case SEC_E_SECPKG_NOT_FOUND:
-      txt = "SEC_E_SECPKG_NOT_FOUND";
-      break;
-    case SEC_E_SECURITY_QOS_FAILED:
-      txt = "SEC_E_SECURITY_QOS_FAILED";
-      break;
-    case SEC_E_SHUTDOWN_IN_PROGRESS:
-      txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
-      break;
-    case SEC_E_SMARTCARD_CERT_EXPIRED:
-      txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
-      break;
-    case SEC_E_SMARTCARD_CERT_REVOKED:
-      txt = "SEC_E_SMARTCARD_CERT_REVOKED";
-      break;
-    case SEC_E_SMARTCARD_LOGON_REQUIRED:
-      txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
-      break;
-    case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
-      txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
-      break;
-    case SEC_E_TARGET_UNKNOWN:
-      txt = "SEC_E_TARGET_UNKNOWN";
-      break;
-    case SEC_E_TIME_SKEW:
-      txt = "SEC_E_TIME_SKEW";
-      break;
-    case SEC_E_TOO_MANY_PRINCIPALS:
-      txt = "SEC_E_TOO_MANY_PRINCIPALS";
-      break;
-    case SEC_E_UNFINISHED_CONTEXT_DELETED:
-      txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
-      break;
-    case SEC_E_UNKNOWN_CREDENTIALS:
-      txt = "SEC_E_UNKNOWN_CREDENTIALS";
-      break;
-    case SEC_E_UNSUPPORTED_FUNCTION:
-      txt = "SEC_E_UNSUPPORTED_FUNCTION";
-      break;
-    case SEC_E_UNSUPPORTED_PREAUTH:
-      txt = "SEC_E_UNSUPPORTED_PREAUTH";
-      break;
-    case SEC_E_UNTRUSTED_ROOT:
-      txt = "SEC_E_UNTRUSTED_ROOT";
-      break;
-    case SEC_E_WRONG_CREDENTIAL_HANDLE:
-      txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
-      break;
-    case SEC_E_WRONG_PRINCIPAL:
-      txt = "SEC_E_WRONG_PRINCIPAL";
-      break;
-    case SEC_I_COMPLETE_AND_CONTINUE:
-      txt = "SEC_I_COMPLETE_AND_CONTINUE";
-      break;
-    case SEC_I_COMPLETE_NEEDED:
-      txt = "SEC_I_COMPLETE_NEEDED";
-      break;
-    case SEC_I_CONTEXT_EXPIRED:
-      txt = "SEC_I_CONTEXT_EXPIRED";
-      break;
-    case SEC_I_CONTINUE_NEEDED:
-      txt = "SEC_I_CONTINUE_NEEDED";
-      break;
-    case SEC_I_INCOMPLETE_CREDENTIALS:
-      txt = "SEC_I_INCOMPLETE_CREDENTIALS";
-      break;
-    case SEC_I_LOCAL_LOGON:
-      txt = "SEC_I_LOCAL_LOGON";
-      break;
-    case SEC_I_NO_LSA_CONTEXT:
-      txt = "SEC_I_NO_LSA_CONTEXT";
-      break;
-    case SEC_I_RENEGOTIATE:
-      txt = "SEC_I_RENEGOTIATE";
-      break;
-    case SEC_I_SIGNATURE_NEEDED:
-      txt = "SEC_I_SIGNATURE_NEEDED";
-      break;
+#define SEC2TXT(sec) case sec: txt = #sec; break;
+    SEC2TXT(CRYPT_E_REVOKED);
+    SEC2TXT(SEC_E_ALGORITHM_MISMATCH);
+    SEC2TXT(SEC_E_BAD_BINDINGS);
+    SEC2TXT(SEC_E_BAD_PKGID);
+    SEC2TXT(SEC_E_BUFFER_TOO_SMALL);
+    SEC2TXT(SEC_E_CANNOT_INSTALL);
+    SEC2TXT(SEC_E_CANNOT_PACK);
+    SEC2TXT(SEC_E_CERT_EXPIRED);
+    SEC2TXT(SEC_E_CERT_UNKNOWN);
+    SEC2TXT(SEC_E_CERT_WRONG_USAGE);
+    SEC2TXT(SEC_E_CONTEXT_EXPIRED);
+    SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE);
+    SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID);
+    SEC2TXT(SEC_E_DECRYPT_FAILURE);
+    SEC2TXT(SEC_E_DELEGATION_POLICY);
+    SEC2TXT(SEC_E_DELEGATION_REQUIRED);
+    SEC2TXT(SEC_E_DOWNGRADE_DETECTED);
+    SEC2TXT(SEC_E_ENCRYPT_FAILURE);
+    SEC2TXT(SEC_E_ILLEGAL_MESSAGE);
+    SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS);
+    SEC2TXT(SEC_E_INCOMPLETE_MESSAGE);
+    SEC2TXT(SEC_E_INSUFFICIENT_MEMORY);
+    SEC2TXT(SEC_E_INTERNAL_ERROR);
+    SEC2TXT(SEC_E_INVALID_HANDLE);
+    SEC2TXT(SEC_E_INVALID_PARAMETER);
+    SEC2TXT(SEC_E_INVALID_TOKEN);
+    SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED);
+    SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC);
+    SEC2TXT(SEC_E_KDC_CERT_EXPIRED);
+    SEC2TXT(SEC_E_KDC_CERT_REVOKED);
+    SEC2TXT(SEC_E_KDC_INVALID_REQUEST);
+    SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER);
+    SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE);
+    SEC2TXT(SEC_E_LOGON_DENIED);
+    SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED);
+    SEC2TXT(SEC_E_MESSAGE_ALTERED);
+    SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS);
+    SEC2TXT(SEC_E_MUST_BE_KDC);
+    SEC2TXT(SEC_E_NOT_OWNER);
+    SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY);
+    SEC2TXT(SEC_E_NO_CREDENTIALS);
+    SEC2TXT(SEC_E_NO_IMPERSONATION);
+    SEC2TXT(SEC_E_NO_IP_ADDRESSES);
+    SEC2TXT(SEC_E_NO_KERB_KEY);
+    SEC2TXT(SEC_E_NO_PA_DATA);
+    SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT);
+    SEC2TXT(SEC_E_NO_TGT_REPLY);
+    SEC2TXT(SEC_E_OUT_OF_SEQUENCE);
+    SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE);
+    SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH);
+    SEC2TXT(SEC_E_POLICY_NLTM_ONLY);
+    SEC2TXT(SEC_E_QOP_NOT_SUPPORTED);
+    SEC2TXT(SEC_E_REVOCATION_OFFLINE_C);
+    SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC);
+    SEC2TXT(SEC_E_SECPKG_NOT_FOUND);
+    SEC2TXT(SEC_E_SECURITY_QOS_FAILED);
+    SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS);
+    SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED);
+    SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED);
+    SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED);
+    SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED);
+    SEC2TXT(SEC_E_TARGET_UNKNOWN);
+    SEC2TXT(SEC_E_TIME_SKEW);
+    SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS);
+    SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED);
+    SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS);
+    SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION);
+    SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH);
+    SEC2TXT(SEC_E_UNTRUSTED_ROOT);
+    SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE);
+    SEC2TXT(SEC_E_WRONG_PRINCIPAL);
+    SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE);
+    SEC2TXT(SEC_I_COMPLETE_NEEDED);
+    SEC2TXT(SEC_I_CONTEXT_EXPIRED);
+    SEC2TXT(SEC_I_CONTINUE_NEEDED);
+    SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS);
+    SEC2TXT(SEC_I_LOCAL_LOGON);
+    SEC2TXT(SEC_I_NO_LSA_CONTEXT);
+    SEC2TXT(SEC_I_RENEGOTIATE);
+    SEC2TXT(SEC_I_SIGNATURE_NEEDED);
     default:
       txt = "Unknown error";
   }
 
-  if(err == SEC_E_OK)
-    strncpy(outbuf, txt, outmax);
-  else if(err == SEC_E_ILLEGAL_MESSAGE)
-    msnprintf(outbuf, outmax,
+  if(err == SEC_E_ILLEGAL_MESSAGE) {
+    msnprintf(buf, buflen,
               "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
               "when a fatal SSL/TLS alert is received (e.g. handshake failed)."
               " More detail may be available in the Windows System event log.",
               err);
+  }
   else {
-    str = txtbuf;
+    char txtbuf[80];
+    char msgbuf[256];
+
     msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
-    txtbuf[sizeof(txtbuf)-1] = '\0';
 
-#ifdef _WIN32_WCE
-    {
-      wchar_t wbuf[256];
-      wbuf[0] = L'\0';
-
-      if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
-                       FORMAT_MESSAGE_IGNORE_INSERTS,
-                       NULL, err, LANG_NEUTRAL,
-                       wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
-        wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
-        msg_formatted = TRUE;
-      }
-    }
-#else
-    if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
-                      FORMAT_MESSAGE_IGNORE_INSERTS,
-                      NULL, err, LANG_NEUTRAL,
-                      msgbuf, sizeof(msgbuf)-1, NULL)) {
-      msg_formatted = TRUE;
+    if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
+      msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf);
+    else {
+      strncpy(buf, txtbuf, buflen);
+      buf[buflen - 1] = '\0';
     }
-#endif
-    if(msg_formatted) {
-      msgbuf[sizeof(msgbuf)-1] = '\0';
-      /* strip trailing '\r\n' or '\n' */
-      p = strrchr(msgbuf, '\n');
-      if(p && (p - msgbuf) >= 2)
-        *p = '\0';
-      p = strrchr(msgbuf, '\r');
-      if(p && (p - msgbuf) >= 1)
-        *p = '\0';
-      msg = msgbuf;
-    }
-    if(msg)
-      msnprintf(outbuf, outmax, "%s - %s", str, msg);
-    else
-      strncpy(outbuf, str, outmax);
   }
 
 #else
-
   if(err == SEC_E_OK)
     txt = "No error";
   else
     txt = "Error";
-
-  strncpy(outbuf, txt, outmax);
-
+  strncpy(buf, txt, buflen);
+  buf[buflen - 1] = '\0';
 #endif
 
-  outbuf[outmax] = '\0';
-
   if(errno != old_errno)
     errno = old_errno;
 
@@ -1100,6 +995,6 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t 
buflen)
     SetLastError(old_win_err);
 #endif
 
-  return outbuf;
+  return buf;
 }
 #endif /* USE_WINDOWS_SSPI */
diff --git a/lib/strerror.h b/lib/strerror.h
index 683b5b4a3..278c1082f 100644
--- a/lib/strerror.h
+++ b/lib/strerror.h
@@ -27,6 +27,9 @@
 #define STRERROR_LEN 128 /* a suitable length */
 
 const char *Curl_strerror(int err, char *buf, size_t buflen);
+#if defined(WIN32) || defined(_WIN32_WCE)
+const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen);
+#endif
 #ifdef USE_WINDOWS_SSPI
 const char *Curl_sspi_strerror(int err, char *buf, size_t buflen);
 #endif
diff --git a/lib/strtok.c b/lib/strtok.c
index 460eb87e5..be8f48128 100644
--- a/lib/strtok.c
+++ b/lib/strtok.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/strtok.h b/lib/strtok.h
index 90b831eb6..e221fa680 100644
--- a/lib/strtok.h
+++ b/lib/strtok.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/strtoofft.c b/lib/strtoofft.c
index 546a3ff75..96e382060 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/telnet.c b/lib/telnet.c
index fa51124dc..e270c2273 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -69,12 +69,12 @@
   do {                                                  \
     x->subend = x->subpointer;                          \
     CURL_SB_CLEAR(x);                                   \
-  } WHILE_FALSE
+  } while(0)
 #define CURL_SB_ACCUM(x,c)                                      \
   do {                                                          \
     if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer)))   \
       *x->subpointer++ = (c);                                   \
-  } WHILE_FALSE
+  } while(0)
 
 #define  CURL_SB_GET(x) ((*x->subpointer++)&0xff)
 #define  CURL_SB_LEN(x) (x->subend - x->subpointer)
diff --git a/lib/telnet.h b/lib/telnet.h
index 668a78a13..431427f39 100644
--- a/lib/telnet.h
+++ b/lib/telnet.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/tftp.h b/lib/tftp.h
index 1335f64bd..33348300f 100644
--- a/lib/tftp.h
+++ b/lib/tftp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/transfer.c b/lib/transfer.c
index 9996d15ce..ed197c4f1 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -484,8 +484,9 @@ CURLcode Curl_readrewind(struct connectdata *conn)
   return CURLE_OK;
 }
 
-static int data_pending(const struct connectdata *conn)
+static int data_pending(const struct Curl_easy *data)
 {
+  struct connectdata *conn = data->conn;
   /* in the case of libssh2, we can never be really sure that we have emptied
      its internal buffers so we MUST always try until we get EAGAIN back */
   return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
@@ -499,6 +500,8 @@ static int data_pending(const struct connectdata *conn)
        be called and we cannot signal the HTTP/2 stream has closed. As
        a workaround, we return nonzero here to call http2_recv. */
     ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20);
+#elif defined(ENABLE_QUIC)
+    Curl_ssl_data_pending(conn, FIRSTSOCKET) || Curl_quic_data_pending(data);
 #else
     Curl_ssl_data_pending(conn, FIRSTSOCKET);
 #endif
@@ -918,7 +921,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
       break;
     }
 
-  } while(data_pending(conn) && maxloops--);
+  } while(data_pending(data) && maxloops--);
 
   if(maxloops <= 0) {
     /* we mark it as read-again-please */
@@ -1174,7 +1177,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
     }
 
 
-  } WHILE_FALSE; /* just to break out from! */
+  } while(0); /* just to break out from! */
 
   return CURLE_OK;
 }
diff --git a/lib/url.c b/lib/url.c
index 8285474fd..4111eec3a 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -106,7 +106,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "http2.h"
 #include "file.h"
 #include "curl_ldap.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "imap.h"
 #include "url.h"
 #include "connect.h"
@@ -403,9 +403,11 @@ CURLcode Curl_close(struct Curl_easy **datap)
     Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
   }
 
+#ifndef CURL_DISABLE_DOH
   free(data->req.doh.probe[0].serverdoh.memory);
   free(data->req.doh.probe[1].serverdoh.memory);
   curl_slist_free_all(data->req.doh.headers);
+#endif
 
   /* destruct wildcard structures if it is needed */
   Curl_wildcard_dtor(&data->wildcard);
@@ -672,7 +674,7 @@ static void conn_reset_all_postponed_data(struct 
connectdata *conn)
 }
 #else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 /* Use "do-nothing" macro instead of function when workaround not used */
-#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
+#define conn_reset_all_postponed_data(c) do {} while(0)
 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 
 
@@ -1080,16 +1082,15 @@ ConnectionExists(struct Curl_easy *data,
       check = curr->ptr;
       curr = curr->next;
 
-      if(check->bits.connect_only)
-        /* connect-only connections will not be reused */
+      if(check->bits.connect_only || check->bits.close)
+        /* connect-only or to-be-closed connections will not be reused */
         continue;
 
       multiplexed = CONN_INUSE(check) &&
         (bundle->multiuse == BUNDLE_MULTIPLEX);
 
       if(canmultiplex) {
-        if(check->bits.protoconnstart && check->bits.close)
-          continue;
+        ;
       }
       else {
         if(multiplexed) {
@@ -1109,12 +1110,9 @@ ConnectionExists(struct Curl_easy *data,
           }
         }
 
-        if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
-           check->bits.close) {
-          if(!check->bits.close)
-            foundPendingCandidate = TRUE;
-          /* Don't pick a connection that hasn't connected yet or that is going
-             to get closed. */
+        if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
+          foundPendingCandidate = TRUE;
+          /* Don't pick a connection that hasn't connected yet */
           infof(data, "Connection #%ld isn't open enough, can't reuse\n",
                 check->connection_id);
           continue;
@@ -1192,8 +1190,7 @@ ConnectionExists(struct Curl_easy *data,
            already in use so we skip it */
         continue;
 
-      if(CONN_INUSE(check) && check->data &&
-         (check->data->multi != needle->data->multi))
+      if(check->data && (check->data->multi != needle->data->multi))
         /* this could be subject for multiplex use, but only if they belong to
          * the same multi handle */
         continue;
@@ -1641,6 +1638,7 @@ static struct connectdata *allocate_conn(struct Curl_easy 
*data)
      it may live on without (this specific) Curl_easy */
   conn->fclosesocket = data->set.fclosesocket;
   conn->closesocket_client = data->set.closesocket_client;
+  conn->lastused = Curl_now(); /* used now */
 
   return conn;
   error:
@@ -1987,8 +1985,11 @@ void Curl_free_request_state(struct Curl_easy *data)
 {
   Curl_safefree(data->req.protop);
   Curl_safefree(data->req.newurl);
+
+#ifndef CURL_DISABLE_DOH
   Curl_close(&data->req.doh.probe[0].easy);
   Curl_close(&data->req.doh.probe[1].easy);
+#endif
 }
 
 
@@ -3607,7 +3608,6 @@ static CURLcode create_conn(struct Curl_easy *data,
         reuse = FALSE;
 
         infof(data, "We can reuse, but we want a new connection anyway\n");
-        Curl_conncache_return_conn(conn_temp);
       }
     }
   }
diff --git a/lib/urldata.h b/lib/urldata.h
index b6f59313d..aabced282 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -124,7 +124,7 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* 
connection data */
 #include "smtp.h"
 #include "ftp.h"
 #include "file.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "http.h"
 #include "rtsp.h"
 #include "smb.h"
@@ -258,6 +258,7 @@ struct ssl_config_data {
   BIT(falsestart);
   BIT(enable_beast); /* allow this flaw for interoperability's sake*/
   BIT(no_revoke);    /* disable SSL certificate revocation checks */
+  BIT(no_partialchain); /* don't accept partial certificate chains */
 };
 
 struct ssl_general_config {
@@ -529,6 +530,24 @@ enum upgrade101 {
   UPGR101_WORKING             /* talking upgraded protocol */
 };
 
+enum doh_slots {
+  /* Explicit values for first two symbols so as to match hard-coded
+   * constants in existing code
+   */
+  DOH_PROBE_SLOT_IPADDR_V4 = 0, /* make 'V4' stand out for readability */
+  DOH_PROBE_SLOT_IPADDR_V6 = 1, /* 'V6' likewise */
+
+  /* Space here for (possibly build-specific) additional slot definitions */
+
+  /* for example */
+  /* #ifdef WANT_DOH_FOOBAR_TXT */
+  /*   DOH_PROBE_SLOT_FOOBAR_TXT, */
+  /* #endif */
+
+  /* AFTER all slot definitions, establish how many we have */
+  DOH_PROBE_SLOTS
+};
+
 struct dohresponse {
   unsigned char *memory;
   size_t size;
@@ -545,7 +564,7 @@ struct dnsprobe {
 
 struct dohdata {
   struct curl_slist *headers;
-  struct dnsprobe probe[2];
+  struct dnsprobe probe[DOH_PROBE_SLOTS];
   unsigned int pending; /* still outstanding requests */
   const char *host;
   int port;
diff --git a/lib/vauth/cram.c b/lib/vauth/cram.c
index d266d2c7c..d2a0e28b8 100644
--- a/lib/vauth/cram.c
+++ b/lib/vauth/cram.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/vauth/digest.h b/lib/vauth/digest.h
index cb544da9b..343c94e90 100644
--- a/lib/vauth/digest.h
+++ b/lib/vauth/digest.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/version.c b/lib/version.c
index 50ffc3f4e..f4d1bb60d 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -26,7 +26,7 @@
 #include "urldata.h"
 #include "vtls/vtls.h"
 #include "http2.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "quic.h"
 #include "curl_printf.h"
 
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c
index c0f9b16e3..c39dba23a 100644
--- a/lib/vquic/ngtcp2.c
+++ b/lib/vquic/ngtcp2.c
@@ -49,7 +49,7 @@
 #ifdef DEBUG_HTTP3
 #define H3BUGF(x) x
 #else
-#define H3BUGF(x) do { } WHILE_FALSE
+#define H3BUGF(x) do { } while(0)
 #endif
 
 /*
@@ -174,8 +174,19 @@ static int quic_set_encryption_secrets(SSL *ssl,
          tx_secret, secretlen, NGTCP2_CRYPTO_SIDE_CLIENT) != 0)
     return 0;
 
-  if(level == NGTCP2_CRYPTO_LEVEL_APP && init_ngh3_conn(qs) != CURLE_OK)
-    return 0;
+  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+    if(init_ngh3_conn(qs) != CURLE_OK)
+      return 0;
+
+    /* malloc an area big enough for both secrets */
+    qs->rx_secret = malloc(secretlen * 2);
+    if(!qs->rx_secret)
+      return 0;
+    memcpy(qs->rx_secret, rx_secret, secretlen);
+    memcpy(&qs->rx_secret[secretlen], tx_secret, secretlen);
+    qs->tx_secret = &qs->rx_secret[secretlen];
+    qs->rx_secretlen = secretlen;
+  }
 
   return 1;
 }
@@ -188,11 +199,12 @@ static int quic_add_handshake_data(SSL *ssl, 
OSSL_ENCRYPTION_LEVEL ossl_level,
   ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level);
   int rv;
 
-  crypto_data = &qs->client_crypto_data[level];
+  crypto_data = &qs->crypto_data[level];
   if(crypto_data->buf == NULL) {
     crypto_data->buf = malloc(4096);
+    if(!crypto_data->buf)
+      return 0;
     crypto_data->alloclen = 4096;
-    /* TODO Explode if malloc failed */
   }
 
   /* TODO Just pretend that handshake does not grow more than 4KiB for
@@ -203,8 +215,8 @@ static int quic_add_handshake_data(SSL *ssl, 
OSSL_ENCRYPTION_LEVEL ossl_level,
   crypto_data->len += len;
 
   rv = ngtcp2_conn_submit_crypto_data(
-      qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len),
-      len);
+    qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len),
+    len);
   if(rv) {
     H3BUGF(fprintf(stderr, "write_client_handshake failed\n"));
   }
@@ -244,8 +256,9 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
   SSL_CTX_set_default_verify_paths(ssl_ctx);
 
   if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) {
-    failf(data, "SSL_CTX_set_ciphersuites: %s",
-          ERR_error_string(ERR_get_error(), NULL));
+    char error_buffer[256];
+    ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
+    failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
     return NULL;
   }
 
@@ -305,7 +318,7 @@ 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)
+       quic, qs->ssl, NGTCP2_CRYPTO_LEVEL_INITIAL, NULL, 0) != 0)
     return NGTCP2_ERR_CALLBACK_FAILURE;
 
   return 0;
@@ -336,6 +349,16 @@ static int cb_handshake_completed(ngtcp2_conn *tconn, void 
*user_data)
   return 0;
 }
 
+static void extend_stream_window(ngtcp2_conn *tconn,
+                                 struct HTTP *stream)
+{
+  size_t thismuch = stream->unacked_window;
+  ngtcp2_conn_extend_max_stream_offset(tconn, stream->stream3_id, thismuch);
+  ngtcp2_conn_extend_max_offset(tconn, thismuch);
+  stream->unacked_window = 0;
+}
+
+
 static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
                                int fin, uint64_t offset,
                                const uint8_t *buf, size_t buflen,
@@ -346,9 +369,6 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t 
stream_id,
   (void)offset;
   (void)stream_user_data;
 
-  infof(qs->conn->data, "Received %ld bytes data on stream %u\n",
-        buflen, stream_id);
-
   nconsumed =
     nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin);
   if(nconsumed < 0) {
@@ -357,6 +377,9 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t 
stream_id,
     return NGTCP2_ERR_CALLBACK_FAILURE;
   }
 
+  /* number of bytes inside buflen which consists of framing overhead
+   * including QPACK HEADERS. In other words, it does not consume payload of
+   * DATA frame. */
   ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed);
   ngtcp2_conn_extend_max_offset(tconn, nconsumed);
 
@@ -493,6 +516,25 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, 
ngtcp2_cid *cid,
   return 0;
 }
 
+static int cb_update_key(ngtcp2_conn *tconn, uint8_t *rx_key,
+                         uint8_t *rx_iv, uint8_t *tx_key,
+                         uint8_t *tx_iv, void *user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  uint8_t rx_secret[64];
+  uint8_t tx_secret[64];
+
+  if(ngtcp2_crypto_update_key(tconn, rx_secret, tx_secret,
+                              rx_key, rx_iv, tx_key, tx_iv, qs->rx_secret,
+                              qs->tx_secret, qs->rx_secretlen) != 0)
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+
+  /* store the updated secrets */
+  memcpy(qs->rx_secret, rx_secret, qs->rx_secretlen);
+  memcpy(qs->tx_secret, tx_secret, qs->rx_secretlen);
+  return 0;
+}
+
 static ngtcp2_conn_callbacks ng_callbacks = {
   cb_initial,
   NULL, /* recv_client_initial */
@@ -514,7 +556,7 @@ static ngtcp2_conn_callbacks ng_callbacks = {
   NULL, /* rand  */
   cb_get_new_connection_id,
   NULL, /* remove_connection_id */
-  NULL, /* update_key */
+  cb_update_key, /* update_key */
   NULL, /* path_validation */
   NULL, /* select_preferred_addr */
   cb_stream_reset,
@@ -656,8 +698,17 @@ static int ng_perform_getsock(const struct connectdata 
*conn,
 static CURLcode ng_disconnect(struct connectdata *conn,
                               bool dead_connection)
 {
-  (void)conn;
+  int i;
+  struct quicsocket *qs = &conn->hequic[0];
   (void)dead_connection;
+  free(qs->rx_secret);
+  if(qs->ssl)
+    SSL_free(qs->ssl);
+  for(i = 0; i < 3; i++)
+    free(qs->crypto_data[i].buf);
+  nghttp3_conn_del(qs->h3conn);
+  ngtcp2_conn_del(qs->qconn);
+  SSL_CTX_free(qs->sslctx);
   return CURLE_OK;
 }
 
@@ -704,42 +755,121 @@ static int cb_h3_stream_close(nghttp3_conn *conn, 
int64_t stream_id,
 
   stream->closed = TRUE;
   Curl_expire(data, 0, EXPIRE_QUIC);
+  /* make sure that ngh3_stream_recv is called again to complete the transfer
+     even if there are no more packets to be received from the server. */
+  data->state.drain = 1;
   return 0;
 }
 
-static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
-                           const uint8_t *buf, size_t buflen,
-                           void *user_data, void *stream_user_data)
-{
-  struct quicsocket *qs = user_data;
-  size_t ncopy;
-  struct Curl_easy *data = stream_user_data;
-  struct HTTP *stream = data->req.protop;
-  (void)conn;
-  H3BUGF(infof(data, "cb_h3_recv_data CALLED with %d bytes\n", buflen));
+/* Minimum size of the overflow buffer */
+#define OVERFLOWSIZE 1024
 
-  /* TODO: this needs to be handled properly */
-  DEBUGASSERT(buflen <= stream->len);
+/*
+ * 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;
+}
 
-  ncopy = CURLMIN(stream->len, buflen);
-  memcpy(stream->mem, buf, ncopy);
-  stream->len -= ncopy;
-  stream->memlen += ncopy;
+/*
+ * 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)
+{
+  CURLcode result = CURLE_OK;
+  const char *buf = mem;
+  size_t ncopy = memlen;
+  /* 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;
+    stream->mem += len;
+    buf += len;
+    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 */
-  fprintf(stderr, "!! Copies %zd bytes to %p (total %zd)\n",
-          ncopy, stream->mem, stream->memlen);
   {
     size_t i;
-    for(i = 0; i < ncopy; i++) {
+    for(i = 0; i < memlen; i++) {
       fprintf(stderr, "!! data[%d]: %02x '%c'\n", i, buf[i], buf[i]);
     }
   }
 #endif
-  stream->mem += ncopy;
+  return result;
+}
 
-  ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, buflen);
-  ngtcp2_conn_extend_max_offset(qs->qconn, buflen);
+static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
+                           const uint8_t *buf, size_t buflen,
+                           void *user_data, void *stream_user_data)
+{
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  CURLcode result = CURLE_OK;
+  (void)conn;
 
+  result = write_data(data, stream, buf, buflen);
+  if(result) {
+    return -1;
+  }
+  stream->unacked_window += buflen;
+  (void)stream_id;
+  (void)user_data;
   return 0;
 }
 
@@ -750,10 +880,10 @@ static int cb_h3_deferred_consume(nghttp3_conn *conn, 
int64_t stream_id,
   struct quicsocket *qs = user_data;
   (void)conn;
   (void)stream_user_data;
+  (void)stream_id;
 
   ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed);
   ngtcp2_conn_extend_max_offset(qs->qconn, consumed);
-
   return 0;
 }
 
@@ -789,15 +919,17 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t 
stream_id,
 {
   struct Curl_easy *data = stream_user_data;
   struct HTTP *stream = data->req.protop;
+  CURLcode result = CURLE_OK;
   (void)conn;
   (void)stream_id;
   (void)user_data;
 
-  if(stream->memlen >= 2) {
-    memcpy(stream->mem, "\r\n", 2);
-    stream->len -= 2;
-    stream->memlen += 2;
-    stream->mem += 2;
+  /* add a CRLF only if we've received some headers */
+  if(stream->firstheader) {
+    result = write_data(data, stream, "\r\n", 2);
+    if(result) {
+      return -1;
+    }
   }
   return 0;
 }
@@ -811,7 +943,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t 
stream_id,
   nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
   struct Curl_easy *data = stream_user_data;
   struct HTTP *stream = data->req.protop;
-  size_t ncopy;
+  CURLcode result = CURLE_OK;
   (void)conn;
   (void)stream_id;
   (void)token;
@@ -820,20 +952,37 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t 
stream_id,
 
   if(h3name.len == sizeof(":status") - 1 &&
      !memcmp(":status", h3name.base, h3name.len)) {
+    char line[14]; /* status line is always 13 characters long */
+    size_t ncopy;
     int status = decode_status_code(h3val.base, h3val.len);
     DEBUGASSERT(status != -1);
-    msnprintf(stream->mem, stream->len, "HTTP/3 %03d \r\n", status);
+    ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status);
+    result = write_data(data, stream, line, ncopy);
+    if(result) {
+      return -1;
+    }
   }
   else {
     /* store as a HTTP1-style header */
-    msnprintf(stream->mem, stream->len, "%.*s: %.*s\n",
-              h3name.len, h3name.base, h3val.len, h3val.base);
+    result = write_data(data, stream, h3name.base, h3name.len);
+    if(result) {
+      return -1;
+    }
+    result = write_data(data, stream, ": ", 2);
+    if(result) {
+      return -1;
+    }
+    result = write_data(data, stream, h3val.base, h3val.len);
+    if(result) {
+      return -1;
+    }
+    result = write_data(data, stream, "\r\n", 2);
+    if(result) {
+      return -1;
+    }
   }
 
-  ncopy = strlen(stream->mem);
-  stream->len -= ncopy;
-  stream->memlen += ncopy;
-  stream->mem += ncopy;
+  stream->firstheader = TRUE;
   return 0;
 }
 
@@ -933,6 +1082,21 @@ static int init_ngh3_conn(struct quicsocket *qs)
 static Curl_recv ngh3_stream_recv;
 static Curl_send ngh3_stream_send;
 
+static size_t drain_overflow_buffer(struct HTTP *stream)
+{
+  size_t ncopy = CURLMIN(stream->overflow_buflen, stream->len);
+  if(ncopy > 0) {
+    memcpy(stream->mem, stream->overflow_buf, 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);
+  }
+  return ncopy;
+}
+
 /* incoming data frames on the h3 stream */
 static ssize_t ngh3_stream_recv(struct connectdata *conn,
                                 int sockindex,
@@ -952,6 +1116,10 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
   }
   /* else, there's data in the buffer already */
 
+  /* if there's data in the overflow buffer from a previous call, copy as much
+     as possible to the receive buffer before receiving more */
+  drain_overflow_buffer(stream);
+
   if(ng_process_ingress(conn, sockfd, qs)) {
     *curlcode = CURLE_RECV_ERROR;
     return -1;
@@ -969,8 +1137,13 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
     stream->memlen = 0;
     stream->mem = buf;
     stream->len = buffersize;
-    H3BUGF(infof(conn->data, "!! ngh3_stream_recv returns %zd bytes at %p\n",
-                 memlen, buf));
+    /* extend the stream window with the data we're consuming and send out
+       any additional packets to tell the server that we can receive more */
+    extend_stream_window(qs->qconn, stream);
+    if(ng_flush_egress(conn, sockfd, qs)) {
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
     return memlen;
   }
 
@@ -1590,4 +1763,32 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn)
 
   return CURLE_OK;
 }
+
+/*
+ * Called from http.c:Curl_http_done when a request completes.
+ */
+void Curl_quic_done(struct Curl_easy *data, bool premature)
+{
+  (void)premature;
+  if(data->conn->handler == &Curl_handler_http3) {
+    /* only for HTTP/3 transfers */
+    struct HTTP *stream = data->req.protop;
+    Curl_safefree(stream->overflow_buf);
+  }
+}
+
+/*
+ * Called from transfer.c:data_pending to know if we should keep looping
+ * to receive more data from the connection.
+ */
+bool Curl_quic_data_pending(const struct Curl_easy *data)
+{
+  /* We may have received more data than we're able to hold in the receive
+     buffer and allocated an overflow buffer. Since it's possible that
+     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;
+}
+
 #endif
diff --git a/lib/vquic/ngtcp2.h b/lib/vquic/ngtcp2.h
index 5570fc7e7..82b8d41e3 100644
--- a/lib/vquic/ngtcp2.h
+++ b/lib/vquic/ngtcp2.h
@@ -46,7 +46,10 @@ struct quicsocket {
   ngtcp2_settings settings;
   SSL_CTX *sslctx;
   SSL *ssl;
-  struct quic_handshake client_crypto_data[3];
+  uint8_t *rx_secret; /* malloced */
+  uint8_t *tx_secret; /* points into the above buffer */
+  size_t rx_secretlen;
+  struct quic_handshake crypto_data[3];
   /* the last TLS alert description generated by the local endpoint */
   uint8_t tls_alert;
   struct sockaddr_storage local_addr;
diff --git a/lib/vquic/quiche.c b/lib/vquic/quiche.c
index 0ee360d07..e2f43237f 100644
--- a/lib/vquic/quiche.c
+++ b/lib/vquic/quiche.c
@@ -45,7 +45,7 @@
 #ifdef DEBUG_HTTP3
 #define H3BUGF(x) x
 #else
-#define H3BUGF(x) do { } WHILE_FALSE
+#define H3BUGF(x) do { } while(0)
 #endif
 
 #define QUIC_MAX_STREAMS (256*1024)
@@ -379,6 +379,9 @@ static int cb_each_header(uint8_t *name, size_t name_len,
               headers->destlen, "HTTP/3 %.*s\n",
               (int) value_len, value);
   }
+  else if(!headers->nlen) {
+    return CURLE_HTTP3;
+  }
   else {
     msnprintf(headers->dest,
               headers->destlen, "%.*s: %.*s\n",
@@ -433,7 +436,9 @@ static ssize_t h3_stream_recv(struct connectdata *conn,
     case QUICHE_H3_EVENT_HEADERS:
       rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers);
       if(rc) {
-        /* what do we do about this? */
+        *curlcode = rc;
+        failf(data, "Error in HTTP/3 response header");
+        break;
       }
       recvd = headers.nlen;
       break;
@@ -780,4 +785,23 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn)
   return CURLE_OK;
 }
 
+/*
+ * Called from http.c:Curl_http_done when a request completes.
+ */
+void Curl_quic_done(struct Curl_easy *data, bool premature)
+{
+  (void)data;
+  (void)premature;
+}
+
+/*
+ * Called from transfer.c:data_pending to know if we should keep looping
+ * to receive more data from the connection.
+ */
+bool Curl_quic_data_pending(const struct Curl_easy *data)
+{
+  (void)data;
+  return FALSE;
+}
+
 #endif
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index 6bd2ade80..c030362a2 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -97,9 +97,13 @@
 
 /* A recent macro provided by libssh. Or make our own. */
 #ifndef SSH_STRING_FREE_CHAR
-/* !checksrc! disable ASSIGNWITHINCONDITION 1 */
-#define SSH_STRING_FREE_CHAR(x) \
-    do { if((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0)
+#define SSH_STRING_FREE_CHAR(x)                 \
+  do {                                          \
+    if(x) {                                     \
+      ssh_string_free_char(x);                  \
+      x = NULL;                                 \
+    }                                           \
+  } while(0)
 #endif
 
 /* Local functions: */
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index 2429d5f55..27026b7a7 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -466,61 +466,95 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
       struct curl_khkey *knownkeyp = NULL;
       struct curl_khkey foundkey;
 
-      keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
-        LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
-
+      switch(keytype) {
+      case LIBSSH2_HOSTKEY_TYPE_RSA:
+        keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
+        break;
+      case LIBSSH2_HOSTKEY_TYPE_DSS:
+        keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+        break;
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
+      case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
+        break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
+      case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
+        break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
+      case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
+        break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
+      case LIBSSH2_HOSTKEY_TYPE_ED25519:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
+        break;
+#endif
+      default:
+        infof(data, "unsupported key type, can't check knownhosts!\n");
+        keybit = 0;
+        break;
+      }
+      if(!keybit)
+        /* no check means failure! */
+        rc = CURLKHSTAT_REJECT;
+      else {
 #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
-      keycheck = libssh2_knownhost_checkp(sshc->kh,
-                                          conn->host.name,
-                                          (conn->remote_port != PORT_SSH)?
-                                          conn->remote_port:-1,
-                                          remotekey, keylen,
-                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
-                                          keybit,
-                                          &host);
+        keycheck = libssh2_knownhost_checkp(sshc->kh,
+                                            conn->host.name,
+                                            (conn->remote_port != PORT_SSH)?
+                                            conn->remote_port:-1,
+                                            remotekey, keylen,
+                                            LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                            LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                            keybit,
+                                            &host);
 #else
-      keycheck = libssh2_knownhost_check(sshc->kh,
-                                         conn->host.name,
-                                         remotekey, keylen,
-                                         LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                         LIBSSH2_KNOWNHOST_KEYENC_RAW|
-                                         keybit,
-                                         &host);
+        keycheck = libssh2_knownhost_check(sshc->kh,
+                                           conn->host.name,
+                                           remotekey, keylen,
+                                           LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                           LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                           keybit,
+                                           &host);
 #endif
 
-      infof(data, "SSH host check: %d, key: %s\n", keycheck,
-            (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
-            host->key:"<none>");
+        infof(data, "SSH host check: %d, key: %s\n", keycheck,
+              (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
+              host->key:"<none>");
+
+        /* setup 'knownkey' */
+        if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
+          knownkey.key = host->key;
+          knownkey.len = 0;
+          knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+            CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+          knownkeyp = &knownkey;
+        }
 
-      /* setup 'knownkey' */
-      if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
-        knownkey.key = host->key;
-        knownkey.len = 0;
-        knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+        /* setup 'foundkey' */
+        foundkey.key = remotekey;
+        foundkey.len = keylen;
+        foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
           CURLKHTYPE_RSA : CURLKHTYPE_DSS;
-        knownkeyp = &knownkey;
-      }
 
-      /* setup 'foundkey' */
-      foundkey.key = remotekey;
-      foundkey.len = keylen;
-      foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
-        CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+        /*
+         * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
+         * curl_khmatch enum are ever modified, we need to introduce a
+         * translation table here!
+         */
+        keymatch = (enum curl_khmatch)keycheck;
 
-      /*
-       * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
-       * curl_khmatch enum are ever modified, we need to introduce a
-       * translation table here!
-       */
-      keymatch = (enum curl_khmatch)keycheck;
-
-      /* Ask the callback how to behave */
-      Curl_set_in_callback(data, true);
-      rc = func(data, knownkeyp, /* from the knownhosts file */
-                &foundkey, /* from the remote host */
-                keymatch, data->set.ssh_keyfunc_userp);
-      Curl_set_in_callback(data, false);
+        /* Ask the callback how to behave */
+        Curl_set_in_callback(data, true);
+        rc = func(data, knownkeyp, /* from the knownhosts file */
+                  &foundkey, /* from the remote host */
+                  keymatch, data->set.ssh_keyfunc_userp);
+        Curl_set_in_callback(data, false);
+      }
     }
     else
       /* no remotekey means failure! */
diff --git a/lib/ssh.h b/lib/vssh/ssh.h
similarity index 100%
rename from lib/ssh.h
rename to lib/vssh/ssh.h
diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c
new file mode 100644
index 000000000..51694c48d
--- /dev/null
+++ b/lib/vtls/bearssl.c
@@ -0,0 +1,874 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, Michael Forney, <address@hidden>
+ *
+ * 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 USE_BEARSSL
+
+#include <bearssl.h>
+
+#include "bearssl.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "connect.h"
+#include "select.h"
+#include "multiif.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+
+struct x509_context {
+  const br_x509_class *vtable;
+  br_x509_minimal_context minimal;
+  bool verifyhost;
+  bool verifypeer;
+};
+
+struct ssl_backend_data {
+  br_ssl_client_context ctx;
+  struct x509_context x509;
+  unsigned char buf[BR_SSL_BUFSIZE_BIDI];
+  br_x509_trust_anchor *anchors;
+  size_t anchors_len;
+  const char *protocols[2];
+  /* SSL client context is active */
+  bool active;
+};
+
+#define BACKEND connssl->backend
+
+struct cafile_parser {
+  CURLcode err;
+  bool in_cert;
+  br_x509_decoder_context xc;
+  /* array of trust anchors loaded from CAfile */
+  br_x509_trust_anchor *anchors;
+  size_t anchors_len;
+  /* buffer for DN data */
+  unsigned char dn[1024];
+  size_t dn_len;
+};
+
+static void append_dn(void *ctx, const void *buf, size_t len)
+{
+  struct cafile_parser *ca = ctx;
+
+  if(ca->err != CURLE_OK || !ca->in_cert)
+    return;
+  if(sizeof(ca->dn) - ca->dn_len < len) {
+    ca->err = CURLE_FAILED_INIT;
+    return;
+  }
+  memcpy(ca->dn + ca->dn_len, buf, len);
+  ca->dn_len += len;
+}
+
+static void x509_push(void *ctx, const void *buf, size_t len)
+{
+  struct cafile_parser *ca = ctx;
+
+  if(ca->in_cert)
+    br_x509_decoder_push(&ca->xc, buf, len);
+}
+
+static CURLcode load_cafile(const char *path, br_x509_trust_anchor **anchors,
+                            size_t *anchors_len)
+{
+  struct cafile_parser ca;
+  br_pem_decoder_context pc;
+  br_x509_trust_anchor *ta;
+  size_t ta_size;
+  br_x509_trust_anchor *new_anchors;
+  size_t new_anchors_len;
+  br_x509_pkey *pkey;
+  FILE *fp;
+  unsigned char buf[BUFSIZ], *p;
+  const char *name;
+  size_t n, i, pushed;
+
+  fp = fopen(path, "rb");
+  if(!fp)
+    return CURLE_SSL_CACERT_BADFILE;
+
+  ca.err = CURLE_OK;
+  ca.in_cert = FALSE;
+  ca.anchors = NULL;
+  ca.anchors_len = 0;
+  br_pem_decoder_init(&pc);
+  br_pem_decoder_setdest(&pc, x509_push, &ca);
+  for(;;) {
+    n = fread(buf, 1, sizeof(buf), fp);
+    if(n == 0)
+      break;
+    p = buf;
+    while(n) {
+      pushed = br_pem_decoder_push(&pc, p, n);
+      if(ca.err)
+        goto fail;
+      p += pushed;
+      n -= pushed;
+
+      switch(br_pem_decoder_event(&pc)) {
+      case 0:
+        break;
+      case BR_PEM_BEGIN_OBJ:
+        name = br_pem_decoder_name(&pc);
+        if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE"))
+          break;
+        br_x509_decoder_init(&ca.xc, append_dn, &ca);
+        if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) {
+          ca.err = CURLE_OUT_OF_MEMORY;
+          goto fail;
+        }
+        new_anchors_len = ca.anchors_len + 1;
+        new_anchors = realloc(ca.anchors,
+                              new_anchors_len * sizeof(ca.anchors[0]));
+        if(!new_anchors) {
+          ca.err = CURLE_OUT_OF_MEMORY;
+          goto fail;
+        }
+        ca.anchors = new_anchors;
+        ca.anchors_len = new_anchors_len;
+        ca.in_cert = TRUE;
+        ca.dn_len = 0;
+        ta = &ca.anchors[ca.anchors_len - 1];
+        ta->dn.data = NULL;
+        break;
+      case BR_PEM_END_OBJ:
+        if(!ca.in_cert)
+          break;
+        ca.in_cert = FALSE;
+        if(br_x509_decoder_last_error(&ca.xc)) {
+          ca.err = CURLE_SSL_CACERT_BADFILE;
+          goto fail;
+        }
+        ta->flags = 0;
+        if(br_x509_decoder_isCA(&ca.xc))
+          ta->flags |= BR_X509_TA_CA;
+        pkey = br_x509_decoder_get_pkey(&ca.xc);
+        if(!pkey) {
+          ca.err = CURLE_SSL_CACERT_BADFILE;
+          goto fail;
+        }
+        ta->pkey = *pkey;
+
+        /* calculate space needed for trust anchor data */
+        ta_size = ca.dn_len;
+        switch(pkey->key_type) {
+        case BR_KEYTYPE_RSA:
+          ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen;
+          break;
+        case BR_KEYTYPE_EC:
+          ta_size += pkey->key.ec.qlen;
+          break;
+        default:
+          ca.err = CURLE_FAILED_INIT;
+          goto fail;
+        }
+
+        /* fill in trust anchor DN and public key data */
+        ta->dn.data = malloc(ta_size);
+        if(!ta->dn.data) {
+          ca.err = CURLE_OUT_OF_MEMORY;
+          goto fail;
+        }
+        memcpy(ta->dn.data, ca.dn, ca.dn_len);
+        ta->dn.len = ca.dn_len;
+        switch(pkey->key_type) {
+        case BR_KEYTYPE_RSA:
+          ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len;
+          memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen);
+          ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen;
+          memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen);
+          break;
+        case BR_KEYTYPE_EC:
+          ta->pkey.key.ec.q = ta->dn.data + ta->dn.len;
+          memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen);
+          break;
+        }
+        break;
+      default:
+        ca.err = CURLE_SSL_CACERT_BADFILE;
+        goto fail;
+      }
+    }
+  }
+  if(ferror(fp))
+    ca.err = CURLE_READ_ERROR;
+
+fail:
+  fclose(fp);
+  if(ca.err == CURLE_OK) {
+    *anchors = ca.anchors;
+    *anchors_len = ca.anchors_len;
+  }
+  else {
+    for(i = 0; i < ca.anchors_len; ++i)
+      free(ca.anchors[i].dn.data);
+    free(ca.anchors);
+  }
+
+  return ca.err;
+}
+
+static void x509_start_chain(const br_x509_class **ctx,
+                             const char *server_name)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  if(!x509->verifyhost)
+    server_name = NULL;
+  x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name);
+}
+
+static void x509_start_cert(const br_x509_class **ctx, uint32_t length)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  x509->minimal.vtable->start_cert(&x509->minimal.vtable, length);
+}
+
+static void x509_append(const br_x509_class **ctx, const unsigned char *buf,
+                        size_t len)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  x509->minimal.vtable->append(&x509->minimal.vtable, buf, len);
+}
+
+static void x509_end_cert(const br_x509_class **ctx)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  x509->minimal.vtable->end_cert(&x509->minimal.vtable);
+}
+
+static unsigned x509_end_chain(const br_x509_class **ctx)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+  unsigned err;
+
+  err = x509->minimal.vtable->end_chain(&x509->minimal.vtable);
+  if(err && !x509->verifypeer) {
+    /* ignore any X.509 errors */
+    err = BR_ERR_OK;
+  }
+
+  return err;
+}
+
+static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx,
+                                         unsigned *usages)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages);
+}
+
+static const br_x509_class x509_vtable = {
+  sizeof(struct x509_context),
+  x509_start_chain,
+  x509_start_cert,
+  x509_append,
+  x509_end_cert,
+  x509_end_chain,
+  x509_get_pkey
+};
+
+static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const bool verifyhost = SSL_CONN_CONFIG(verifyhost);
+  CURLcode ret;
+  unsigned version_min, version_max;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_SSLv2:
+    failf(data, "BearSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_SSLv3:
+    failf(data, "BearSSL does not support SSLv3");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_TLSv1_0:
+    version_min = BR_TLS10;
+    version_max = BR_TLS10;
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    version_min = BR_TLS11;
+    version_max = BR_TLS11;
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    version_min = BR_TLS12;
+    version_max = BR_TLS12;
+    break;
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    version_min = BR_TLS10;
+    version_max = BR_TLS12;
+    break;
+  default:
+    failf(data, "BearSSL: unknown CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  if(ssl_cafile) {
+    ret = load_cafile(ssl_cafile, &BACKEND->anchors, &BACKEND->anchors_len);
+    if(ret != CURLE_OK) {
+      if(verifypeer) {
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n", ssl_cafile);
+        return ret;
+      }
+      infof(data, "error setting certificate verify locations,"
+            " continuing anyway:\n");
+    }
+  }
+
+  /* initialize SSL context */
+  br_ssl_client_init_full(&BACKEND->ctx, &BACKEND->x509.minimal,
+                          BACKEND->anchors, BACKEND->anchors_len);
+  br_ssl_engine_set_versions(&BACKEND->ctx.eng, version_min, version_max);
+  br_ssl_engine_set_buffer(&BACKEND->ctx.eng, BACKEND->buf,
+                           sizeof(BACKEND->buf), 1);
+
+  /* initialize X.509 context */
+  BACKEND->x509.vtable = &x509_vtable;
+  BACKEND->x509.verifypeer = verifypeer;
+  BACKEND->x509.verifyhost = verifyhost;
+  br_ssl_engine_set_x509(&BACKEND->ctx.eng, &BACKEND->x509.vtable);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *session;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) {
+      br_ssl_engine_set_session_parameters(&BACKEND->ctx.eng, session);
+      infof(data, "BearSSL: re-using session ID\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  if(conn->bits.tls_enable_alpn) {
+    int cur = 0;
+
+    /* NOTE: when adding more protocols here, increase the size of the
+     * protocols array in `struct ssl_backend_data`.
+     */
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+       (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+      BACKEND->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    BACKEND->protocols[cur++] = ALPN_HTTP_1_1;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    br_ssl_engine_set_protocol_names(&BACKEND->ctx.eng,
+                                     BACKEND->protocols, cur);
+  }
+
+  if((1 == Curl_inet_pton(AF_INET, hostname, &addr))
+#ifdef ENABLE_IPV6
+      || (1 == Curl_inet_pton(AF_INET6, hostname, &addr))
+#endif
+     ) {
+    if(verifyhost) {
+      failf(data, "BearSSL: "
+            "host verification of IP address is not supported");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    hostname = NULL;
+  }
+
+  if(!br_ssl_client_reset(&BACKEND->ctx, hostname, 0))
+    return CURLE_FAILED_INIT;
+  BACKEND->active = TRUE;
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode bearssl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  unsigned state;
+  unsigned char *buf;
+  size_t len;
+  ssize_t ret;
+  int err;
+
+  for(;;) {
+    state = br_ssl_engine_current_state(&BACKEND->ctx.eng);
+    if(state & BR_SSL_CLOSED) {
+      err = br_ssl_engine_last_error(&BACKEND->ctx.eng);
+      switch(err) {
+      case BR_ERR_X509_EXPIRED:
+        failf(data, "SSL: X.509 verification: "
+              "certificate is expired or not yet valid");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      case BR_ERR_X509_BAD_SERVER_NAME:
+        failf(data, "SSL: X.509 verification: "
+              "expected server name was not found in the chain");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      case BR_ERR_X509_NOT_TRUSTED:
+        failf(data, "SSL: X.509 verification: "
+              "chain could not be linked to a trust anchor");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      /* X.509 errors are documented to have the range 32..63 */
+      if(err >= 32 && err < 64)
+        return CURLE_PEER_FAILED_VERIFICATION;
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    if(state & (BR_SSL_SENDAPP | BR_SSL_RECVAPP)) {
+      connssl->connecting_state = ssl_connect_3;
+      return CURLE_OK;
+    }
+    if(state & BR_SSL_SENDREC) {
+      buf = br_ssl_engine_sendrec_buf(&BACKEND->ctx.eng, &len);
+      ret = swrite(sockfd, buf, len);
+      if(ret == -1) {
+        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+          connssl->connecting_state = ssl_connect_2_writing;
+          return CURLE_OK;
+        }
+        return CURLE_SEND_ERROR;
+      }
+      br_ssl_engine_sendrec_ack(&BACKEND->ctx.eng, ret);
+    }
+    else if(state & BR_SSL_RECVREC) {
+      buf = br_ssl_engine_recvrec_buf(&BACKEND->ctx.eng, &len);
+      ret = sread(sockfd, buf, len);
+      if(ret == -1) {
+        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+          connssl->connecting_state = ssl_connect_2_reading;
+          return CURLE_OK;
+        }
+        return CURLE_READ_ERROR;
+      }
+      if(ret == 0)
+        return CURLE_SSL_CONNECT_ERROR;
+      br_ssl_engine_recvrec_ack(&BACKEND->ctx.eng, ret);
+    }
+  }
+}
+
+static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode ret;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(conn->bits.tls_enable_alpn) {
+    const char *protocol;
+
+    protocol = br_ssl_engine_get_selected_protocol(&BACKEND->ctx.eng);
+    if(protocol) {
+      infof(data, "ALPN, server accepted to use %s\n", protocol);
+
+#ifdef USE_NGHTTP2
+      if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID))
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      else
+#endif
+      if(!strcmp(protocol, ALPN_HTTP_1_1))
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      else
+        infof(data, "ALPN, unrecognized protocol %s\n", protocol);
+      Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+                          BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    bool incache;
+    void *oldsession;
+    br_ssl_session_parameters *session;
+
+    session = malloc(sizeof(*session));
+    if(!session)
+      return CURLE_OUT_OF_MEMORY;
+    br_ssl_engine_get_session_parameters(&BACKEND->ctx.eng, session);
+    Curl_ssl_sessionid_lock(conn);
+    incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex));
+    if(incache)
+      Curl_ssl_delsessionid(conn, oldsession);
+    ret = Curl_ssl_addsessionid(conn, session, 0, sockindex);
+    Curl_ssl_sessionid_unlock(conn);
+    if(ret) {
+      free(session);
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static ssize_t bearssl_send(struct connectdata *conn, int sockindex,
+                            const void *buf, size_t len, CURLcode *err)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned state;
+  unsigned char *rec, *app;
+  size_t reclen, applen;
+  ssize_t ret;
+
+  applen = 0;
+  for(;;) {
+    state = br_ssl_engine_current_state(&BACKEND->ctx.eng);
+    if(state & BR_SSL_SENDREC) {
+      rec = br_ssl_engine_sendrec_buf(&BACKEND->ctx.eng, &reclen);
+      ret = swrite(conn->sock[sockindex], rec, reclen);
+      if(ret == -1) {
+        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)
+          *err = CURLE_AGAIN;
+        else
+          *err = CURLE_SEND_ERROR;
+        return -1;
+      }
+      br_ssl_engine_sendrec_ack(&BACKEND->ctx.eng, ret);
+    }
+    else if(state & BR_SSL_SENDAPP && applen == 0) {
+      app = br_ssl_engine_sendapp_buf(&BACKEND->ctx.eng, &applen);
+      if(applen > len)
+        applen = len;
+      memcpy(app, buf, applen);
+      br_ssl_engine_sendapp_ack(&BACKEND->ctx.eng, applen);
+      br_ssl_engine_flush(&BACKEND->ctx.eng, 0);
+    }
+    else if(state & BR_SSL_CLOSED || applen == 0) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+    else
+      break;
+  }
+
+  return applen;
+}
+
+static ssize_t bearssl_recv(struct connectdata *conn, int sockindex,
+                            char *buf, size_t len, CURLcode *err)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned state;
+  unsigned char *rec, *app;
+  size_t reclen, applen;
+  ssize_t ret;
+
+  for(;;) {
+    state = br_ssl_engine_current_state(&BACKEND->ctx.eng);
+    if(state & BR_SSL_RECVREC) {
+      rec = br_ssl_engine_recvrec_buf(&BACKEND->ctx.eng, &reclen);
+      ret = sread(conn->sock[sockindex], rec, reclen);
+      if(ret == -1 && (SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)) {
+        *err = CURLE_AGAIN;
+        return -1;
+      }
+      if(ret <= 0) {
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+      br_ssl_engine_recvrec_ack(&BACKEND->ctx.eng, ret);
+    }
+    else if(state & BR_SSL_RECVAPP) {
+      app = br_ssl_engine_recvapp_buf(&BACKEND->ctx.eng, &applen);
+      if(applen > len)
+        applen = len;
+      memcpy(buf, app, applen);
+      br_ssl_engine_recvapp_ack(&BACKEND->ctx.eng, applen);
+      break;
+    }
+    else {
+      *err = CURLE_RECV_ERROR;
+      return -1;
+    }
+  }
+
+  return applen;
+}
+
+static CURLcode bearssl_connect_common(struct connectdata *conn,
+                                       int sockindex,
+                                       bool nonblocking,
+                                       bool *done)
+{
+  CURLcode ret;
+  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 */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    ret = bearssl_connect_step1(conn, sockindex);
+    if(ret)
+      return ret;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(ssl_connect_2_reading == connssl->connecting_state ||
+       ssl_connect_2_writing == connssl->connecting_state) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      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);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    ret = bearssl_connect_step2(conn, sockindex);
+    if(ret || (nonblocking &&
+               (ssl_connect_2 == connssl->connecting_state ||
+                ssl_connect_2_reading == connssl->connecting_state ||
+                ssl_connect_2_writing == connssl->connecting_state)))
+      return ret;
+  }
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    ret = bearssl_connect_step3(conn, sockindex);
+    if(ret)
+      return ret;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = bearssl_recv;
+    conn->send[sockindex] = bearssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static size_t Curl_bearssl_version(char *buffer, size_t size)
+{
+  return msnprintf(buffer, size, "BearSSL");
+}
+
+static bool Curl_bearssl_data_pending(const struct connectdata *conn,
+                                      int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+
+  return br_ssl_engine_current_state(&BACKEND->ctx.eng) & BR_SSL_RECVAPP;
+}
+
+static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM,
+                                    unsigned char *entropy, size_t length)
+{
+  static br_hmac_drbg_context ctx;
+  static bool seeded = FALSE;
+
+  if(!seeded) {
+    br_prng_seeder seeder;
+
+    br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0);
+    seeder = br_prng_seeder_system(NULL);
+    if(!seeder || !seeder(&ctx.vtable))
+      return CURLE_FAILED_INIT;
+    seeded = TRUE;
+  }
+  br_hmac_drbg_generate(&ctx, entropy, length);
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_bearssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode ret;
+  bool done = FALSE;
+
+  ret = bearssl_connect_common(conn, sockindex, FALSE, &done);
+  if(ret)
+    return ret;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_bearssl_connect_nonblocking(struct connectdata *conn,
+                                                 int sockindex, bool *done)
+{
+  return bearssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl,
+                                        CURLINFO info UNUSED_PARAM)
+{
+  return &BACKEND->ctx;
+}
+
+static void Curl_bearssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *buf;
+  size_t len, i;
+  ssize_t ret;
+
+  if(BACKEND->active) {
+    br_ssl_engine_close(&BACKEND->ctx.eng);
+    while(br_ssl_engine_current_state(&BACKEND->ctx.eng) & BR_SSL_SENDREC) {
+      buf = br_ssl_engine_sendrec_buf(&BACKEND->ctx.eng, &len);
+      ret = swrite(conn->sock[sockindex], buf, len);
+      if(ret < 0)
+        break;
+      br_ssl_engine_sendrec_ack(&BACKEND->ctx.eng, ret);
+    }
+  }
+  for(i = 0; i < BACKEND->anchors_len; ++i)
+    free(BACKEND->anchors[i].dn.data);
+  free(BACKEND->anchors);
+}
+
+static void Curl_bearssl_session_free(void *ptr)
+{
+  free(ptr);
+}
+
+static CURLcode Curl_bearssl_md5sum(unsigned char *input,
+                                    size_t inputlen,
+                                    unsigned char *md5sum,
+                                    size_t md5len UNUSED_PARAM)
+{
+  br_md5_context ctx;
+
+  br_md5_init(&ctx);
+  br_md5_update(&ctx, input, inputlen);
+  br_md5_out(&ctx, md5sum);
+  return CURLE_OK;
+}
+
+static CURLcode Curl_bearssl_sha256sum(const unsigned char *input,
+                                       size_t inputlen,
+                                       unsigned char *sha256sum,
+                                       size_t sha256len UNUSED_PARAM)
+{
+  br_sha256_context ctx;
+
+  br_sha256_init(&ctx);
+  br_sha256_update(&ctx, input, inputlen);
+  br_sha256_out(&ctx, sha256sum);
+  return CURLE_OK;
+}
+
+const struct Curl_ssl Curl_ssl_bearssl = {
+  { CURLSSLBACKEND_BEARSSL, "bearssl" },
+
+  0,
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_none_init,
+  Curl_none_cleanup,
+  Curl_bearssl_version,
+  Curl_none_check_cxn,
+  Curl_none_shutdown,
+  Curl_bearssl_data_pending,
+  Curl_bearssl_random,
+  Curl_none_cert_status_request,
+  Curl_bearssl_connect,
+  Curl_bearssl_connect_nonblocking,
+  Curl_bearssl_get_internals,
+  Curl_bearssl_close,
+  Curl_none_close_all,
+  Curl_bearssl_session_free,
+  Curl_none_set_engine,
+  Curl_none_set_engine_default,
+  Curl_none_engines_list,
+  Curl_none_false_start,
+  Curl_bearssl_md5sum,
+  Curl_bearssl_sha256sum
+};
+
+#endif /* USE_BEARSSL */
diff --git a/lib/curl_range.h b/lib/vtls/bearssl.h
similarity index 79%
copy from lib/curl_range.h
copy to lib/vtls/bearssl.h
index 2350df992..5f94922b9 100644
--- a/lib/curl_range.h
+++ b/lib/vtls/bearssl.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_RANGE_H
-#define HEADER_CURL_RANGE_H
+#ifndef HEADER_CURL_BEARSSL_H
+#define HEADER_CURL_BEARSSL_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2019, Michael Forney, <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,8 +23,10 @@
  ***************************************************************************/
 
 #include "curl_setup.h"
-#include "urldata.h"
 
-CURLcode Curl_range(struct connectdata *conn);
+#ifdef USE_BEARSSL
 
-#endif /* HEADER_CURL_RANGE_H */
+extern const struct Curl_ssl Curl_ssl_bearssl;
+
+#endif /* USE_BEARSSL */
+#endif /* HEADER_CURL_BEARSSL_H */
diff --git a/lib/vtls/gskit.h b/lib/vtls/gskit.h
index 466ee4d9d..b06b5e17d 100644
--- a/lib/vtls/gskit.h
+++ b/lib/vtls/gskit.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/lib/vtls/mbedtls.h b/lib/vtls/mbedtls.h
index 4a938605b..0cc64b399 100644
--- a/lib/vtls/mbedtls.h
+++ b/lib/vtls/mbedtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <address@hidden>, et al.
  * Copyright (C) 2010, Hoi-Ho Chan, <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index a375f00da..ef51b0d91 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -113,7 +113,7 @@ typedef struct {
   ptr->type = (_type);                                      \
   ptr->pValue = (_val);                                     \
   ptr->ulValueLen = (_len);                                 \
-} WHILE_FALSE
+} while(0)
 
 #define CERT_NewTempCertificate __CERT_NewTempCertificate
 
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 760758d23..726ff6e7c 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -142,10 +142,6 @@
 #endif
 #endif
 
-#ifdef LIBRESSL_VERSION_NUMBER
-#define OpenSSL_version_num() LIBRESSL_VERSION_NUMBER
-#endif
-
 #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
     !(defined(LIBRESSL_VERSION_NUMBER) && \
       LIBRESSL_VERSION_NUMBER < 0x20700000L)
@@ -392,11 +388,20 @@ static const char *SSL_ERROR_to_str(int err)
  */
 static char *ossl_strerror(unsigned long error, char *buf, size_t size)
 {
+  if(size)
+    *buf = '\0';
+
 #ifdef OPENSSL_IS_BORINGSSL
   ERR_error_string_n((uint32_t)error, buf, size);
 #else
   ERR_error_string_n(error, buf, size);
 #endif
+
+  if(size > 1 && !*buf) {
+    strncpy(buf, (error ? "Unknown error" : "No error"), size);
+    buf[size - 1] = '\0';
+  }
+
   return buf;
 }
 
@@ -2768,19 +2773,29 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
     infof(data, "  CRLfile: %s\n", ssl_crlfile);
   }
 
-  /* 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.
-     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(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.
+       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)
     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)) {
+      /* 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. */
+      X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+                           X509_V_FLAG_PARTIAL_CHAIN);
+    }
+#endif
+  }
 
   /* SSL always tries to verify the peer, this only says whether it should
    * fail to connect if the verification fails, or if it should continue
@@ -2806,8 +2821,10 @@ static CURLcode ossl_connect_step1(struct connectdata 
*conn, int sockindex)
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
+    Curl_set_in_callback(data, true);
     result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
                                       data->set.ssl.fsslctxp);
+    Curl_set_in_callback(data, false);
     if(result) {
       failf(data, "error signaled by ssl ctx callback");
       return result;
@@ -2988,8 +3005,13 @@ static CURLcode ossl_connect_step2(struct connectdata 
*conn, int sockindex)
         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;
+        char extramsg[80]="";
+        int sockerr = SOCKERRNO;
+        if(sockerr && detail == SSL_ERROR_SYSCALL)
+          Curl_strerror(sockerr, extramsg, sizeof(extramsg));
         failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ",
-              SSL_ERROR_to_str(detail), hostname, port);
+              extramsg[0] ? extramsg : SSL_ERROR_to_str(detail),
+              hostname, port);
         return result;
       }
 
@@ -3065,7 +3087,7 @@ do {                              \
   Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
   if(1 != BIO_reset(mem))                                        \
     break;                                                       \
-} WHILE_FALSE
+} while(0)
 
 static void pubkey_show(struct Curl_easy *data,
                         BIO *mem,
@@ -3097,7 +3119,7 @@ do {                              \
   if(_type->_name) { \
     pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
   } \
-} WHILE_FALSE
+} while(0)
 #endif
 
 static int X509V3_ext(struct Curl_easy *data,
@@ -3826,10 +3848,22 @@ static ssize_t ossl_send(struct connectdata *conn,
       *curlcode = CURLE_AGAIN;
       return -1;
     case SSL_ERROR_SYSCALL:
-      Curl_strerror(SOCKERRNO, error_buffer, sizeof(error_buffer));
-      failf(conn->data, OSSL_PACKAGE " SSL_write: %s", error_buffer);
-      *curlcode = CURLE_SEND_ERROR;
-      return -1;
+      {
+        int sockerr = SOCKERRNO;
+        sslerror = ERR_get_error();
+        if(sslerror)
+          ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
+        else if(sockerr)
+          Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
+        else {
+          strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
+          error_buffer[sizeof(error_buffer) - 1] = '\0';
+        }
+        failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+              error_buffer, sockerr);
+        *curlcode = CURLE_SEND_ERROR;
+        return -1;
+      }
     case SSL_ERROR_SSL:
       /*  A failure in the SSL library occurred, usually a protocol error.
           The OpenSSL error queue contains more information on the error. */
@@ -3894,11 +3928,6 @@ static ssize_t ossl_recv(struct connectdata *conn, /* 
connection data */
       /* there's data pending, re-invoke SSL_read() */
       *curlcode = CURLE_AGAIN;
       return -1;
-    case SSL_ERROR_SYSCALL:
-      Curl_strerror(SOCKERRNO, error_buffer, sizeof(error_buffer));
-      failf(conn->data, OSSL_PACKAGE " SSL_read: %s", error_buffer);
-      *curlcode = CURLE_RECV_ERROR;
-      return -1;
     default:
       /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
          value/errno" */
@@ -3907,14 +3936,44 @@ static ssize_t ossl_recv(struct connectdata *conn, /* 
connection data */
       if((nread < 0) || sslerror) {
         /* If the return code was negative or there actually is an error in the
            queue */
+        int sockerr = SOCKERRNO;
+        if(sslerror)
+          ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
+        else if(sockerr && err == SSL_ERROR_SYSCALL)
+          Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
+        else {
+          strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
+          error_buffer[sizeof(error_buffer) - 1] = '\0';
+        }
         failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d",
-              (sslerror ?
-               ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) :
-               SSL_ERROR_to_str(err)),
-              SOCKERRNO);
+              error_buffer, sockerr);
         *curlcode = CURLE_RECV_ERROR;
         return -1;
       }
+      /* For debug builds be a little stricter and error on any
+         SSL_ERROR_SYSCALL. For example a server may have closed the connection
+         abruptly without a close_notify alert. For compatibility with older
+         peers we don't do this by default. #4624
+
+         We can use this to gauge how many users may be affected, and
+         if it goes ok eventually transition to allow in dev and release with
+         the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */
+#ifdef DEBUGBUILD
+      if(err == SSL_ERROR_SYSCALL) {
+        int sockerr = SOCKERRNO;
+        if(sockerr)
+          Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
+        else {
+          msnprintf(error_buffer, sizeof(error_buffer),
+                    "Connection closed abruptly");
+        }
+        failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d"
+              " (Fatal because this is a curl debug build)",
+              error_buffer, sockerr);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1;
+      }
+#endif
     }
   }
   return nread;
@@ -3922,13 +3981,35 @@ static ssize_t ossl_recv(struct connectdata *conn, /* 
connection data */
 
 static size_t Curl_ossl_version(char *buffer, size_t size)
 {
-#ifdef OPENSSL_IS_BORINGSSL
+#ifdef LIBRESSL_VERSION_NUMBER
+#if LIBRESSL_VERSION_NUMBER < 0x2070100fL
+  return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
+                   OSSL_PACKAGE,
+                   (LIBRESSL_VERSION_NUMBER>>28)&0xf,
+                   (LIBRESSL_VERSION_NUMBER>>20)&0xff,
+                   (LIBRESSL_VERSION_NUMBER>>12)&0xff);
+#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */
+  char *p;
+  int count;
+  const char *ver = OpenSSL_version(OPENSSL_VERSION);
+  const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */
+  if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) {
+    ver += sizeof(expected) - 1;
+  }
+  count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver);
+  for(p = buffer; *p; ++p) {
+    if(ISSPACE(*p))
+      *p = '_';
+  }
+  return count;
+#endif
+#elif defined(OPENSSL_IS_BORINGSSL)
   return msnprintf(buffer, size, OSSL_PACKAGE);
 #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING)
   return msnprintf(buffer, size, "%s/%s",
                    OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING));
 #else
-  /* not BoringSSL and not using OpenSSL_version */
+  /* not LibreSSL, BoringSSL and not using OpenSSL_version */
 
   char sub[3];
   unsigned long ssleay_value;
diff --git a/lib/vtls/polarssl.h b/lib/vtls/polarssl.h
index 23c3636ee..f36f24f8d 100644
--- a/lib/vtls/polarssl.h
+++ b/lib/vtls/polarssl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <address@hidden>, et al.
  * Copyright (C) 2010, Hoi-Ho Chan, <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
diff --git a/lib/vtls/polarssl_threadlock.c b/lib/vtls/polarssl_threadlock.c
index 27c94b11e..4e269c8e6 100644
--- a/lib/vtls/polarssl_threadlock.c
+++ b/lib/vtls/polarssl_threadlock.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2013-2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2013 - 2019, Daniel Stenberg, <address@hidden>, et al.
  * Copyright (C) 2010, 2011, Hoi-Ho Chan, <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
diff --git a/lib/vtls/polarssl_threadlock.h b/lib/vtls/polarssl_threadlock.h
index 122647528..c1900bfe8 100644
--- a/lib/vtls/polarssl_threadlock.h
+++ b/lib/vtls/polarssl_threadlock.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2013-2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2013 - 2019, Daniel Stenberg, <address@hidden>, et al.
  * Copyright (C) 2010, Hoi-Ho Chan, <address@hidden>
  *
  * This software is licensed as described in the file COPYING, which
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index bbd2fe921..5ab093b38 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -554,10 +554,6 @@ schannel_connect_step1(struct connectdata *conn, int 
sockindex)
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
-      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
-        SP_PROT_TLS1_1_CLIENT |
-        SP_PROT_TLS1_2_CLIENT;
-      break;
     case CURL_SSLVERSION_TLSv1_0:
     case CURL_SSLVERSION_TLSv1_1:
     case CURL_SSLVERSION_TLSv1_2:
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index 1bdf50a55..3a668adc7 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -99,7 +99,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
     char buffer[STRERROR_LEN];
     failf(data,
           "schannel: invalid path name for CA file '%s': %s",
-          ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+          ca_file,
+          Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
     result = CURLE_SSL_CACERT_BADFILE;
     goto cleanup;
   }
@@ -120,7 +121,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
     char buffer[STRERROR_LEN];
     failf(data,
           "schannel: failed to open CA file '%s': %s",
-          ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+          ca_file,
+          Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
     result = CURLE_SSL_CACERT_BADFILE;
     goto cleanup;
   }
@@ -129,7 +131,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
     char buffer[STRERROR_LEN];
     failf(data,
           "schannel: failed to determine size of CA file '%s': %s",
-          ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+          ca_file,
+          Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
     result = CURLE_SSL_CACERT_BADFILE;
     goto cleanup;
   }
@@ -159,7 +162,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
       char buffer[STRERROR_LEN];
       failf(data,
             "schannel: failed to read from CA file '%s': %s",
-            ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+            ca_file,
+            Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
       result = CURLE_SSL_CACERT_BADFILE;
       goto cleanup;
     }
@@ -223,7 +227,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
                 "schannel: failed to extract certificate from CA file "
                 "'%s': %s",
                 ca_file,
-                Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+                Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
           result = CURLE_SSL_CACERT_BADFILE;
           more_certs = 0;
         }
@@ -252,7 +256,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
                     "schannel: failed to add certificate from CA file '%s' "
                     "to certificate store: %s",
                     ca_file,
-                    Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+                    Curl_winapi_strerror(GetLastError(), buffer,
+                                         sizeof(buffer)));
               result = CURLE_SSL_CACERT_BADFILE;
               more_certs = 0;
             }
@@ -460,7 +465,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, 
int sockindex)
       if(!trust_store) {
         char buffer[STRERROR_LEN];
         failf(data, "schannel: failed to create certificate store: %s",
-              Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+              Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
         result = CURLE_SSL_CACERT_BADFILE;
       }
       else {
@@ -489,7 +494,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, 
int sockindex)
         char buffer[STRERROR_LEN];
         failf(data,
               "schannel: failed to create certificate chain engine: %s",
-              Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+              Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
         result = CURLE_SSL_CACERT_BADFILE;
       }
     }
@@ -512,7 +517,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, 
int sockindex)
                                 &pChainContext)) {
       char buffer[STRERROR_LEN];
       failf(data, "schannel: CertGetCertificateChain failed: %s",
-            Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+            Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
       pChainContext = NULL;
       result = CURLE_PEER_FAILED_VERIFICATION;
     }
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index e6d756225..c493b1516 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -517,7 +517,7 @@ void Curl_ssl_close_all(struct Curl_easy *data)
 
 #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
   defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \
-  defined(USE_MBEDTLS) || defined(USE_WOLFSSL)
+  defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL)
 int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
@@ -1189,6 +1189,8 @@ const struct Curl_ssl *Curl_ssl =
   &Curl_ssl_schannel;
 #elif defined(USE_MESALINK)
   &Curl_ssl_mesalink;
+#elif defined(USE_BEARSSL)
+  &Curl_ssl_bearssl;
 #else
 #error "Missing struct Curl_ssl for selected SSL backend"
 #endif
@@ -1223,6 +1225,9 @@ static const struct Curl_ssl *available_backends[] = {
 #endif
 #if defined(USE_MESALINK)
   &Curl_ssl_mesalink,
+#endif
+#if defined(USE_BEARSSL)
+  &Curl_ssl_bearssl,
 #endif
   NULL
 };
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index 61d8416c2..976cc4360 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -108,6 +108,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t 
inputlen,
 #include "sectransp.h"      /* SecureTransport (Darwin) version */
 #include "mbedtls.h"        /* mbedTLS versions */
 #include "mesalink.h"       /* MesaLink versions */
+#include "bearssl.h"        /* BearSSL versions */
 
 #ifndef MAX_PINNED_PUBKEY_SIZE
 #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in
index 8be6c8986..3f32b358d 100644
--- a/packages/OS400/curl.inc.in
+++ b/packages/OS400/curl.inc.in
@@ -760,6 +760,8 @@
      d                 c                   X'0001'
      d CURLSSLOPT_NO_REVOKE...
      d                 c                   X'0002'
+     d CURLSSLOPT_NO_PARTIALCHAIN...
+     d                 c                   X'0004'
       *
      d CURL_HET_DEFAULT...
      d                 c                   200
@@ -1804,7 +1806,11 @@
      d                 c                   6
      d  CURLM_ADDED_ALREADY...
      d                 c                   7
-     d  CURLM_LAST     c                   8
+     d  CURLM_RECURSIVE_API_CALL...
+     d                 c                   8
+     d  CURLM_WAKEUP_FAILURE...
+     d                 c                   9
+     d  CURLM_LAST     c                   10
       *
      d CURLMSG         s             10i 0 based(######ptr######)              
 Enum
      d  CURLMSG_NONE   c                   0
diff --git a/packages/vms/config_h.com b/packages/vms/config_h.com
index 967eb40de..9bfb40b95 100644
--- a/packages/vms/config_h.com
+++ b/packages/vms/config_h.com
@@ -803,28 +803,6 @@ $      write tf "#endif"
 $          goto cfgh_in_loop1
 $      endif
 $!
-$      if key2 .eqs. "HAVE_ENGINE_LOAD_BUILTIN_ENGINES"
-$      then
-$          if f$search("''ssl_header_dir'engine.h") .nes. ""
-$          then
-$              search_key = key2 - "HAVE_"
-$              define/user sys$output nl:
-$              define/user sys$error nl:
-$              search/output=nl: 'ssl_header_dir'engine.h 'search_key'
-$              if '$severity' .eq. 1
-$              then
-$                  write tf "#ifndef ''key2'"
-$                  write tf "#define ''key2' 1"
-$                  write tf "#endif"
-$              else
-$                  write tf "/* #undef ''key2' */"
-$              endif
-$          else
-$              write tf "/* #undef ''key2' */"
-$          endif
-$          goto cfgh_in_loop1
-$      endif
-$!
 $      if key2b .eqs. "RAND" .and. key2c .nes. "" .and. key2d .eqs. ""
 $      then
 $          if (key2c .eqs. "EGD") .or. -
diff --git a/packages/vms/generate_config_vms_h_curl.com 
b/packages/vms/generate_config_vms_h_curl.com
index 62870da5e..809aaaf98 100644
--- a/packages/vms/generate_config_vms_h_curl.com
+++ b/packages/vms/generate_config_vms_h_curl.com
@@ -325,8 +325,8 @@ $! configure defaults to USE_*, a real configure on VMS 
chooses different.
 $write cvh "#ifdef USE_ARES"
 $write cvh "#undef USE_ARES"
 $write cvh "#endif"
-$write cvh "#ifdef USE_CYASSL"
-$write cvh "#undef USE_CYASSL"
+$write cvh "#ifdef USE_WOLFSSL"
+$write cvh "#undef USE_WOLFSSL"
 $write cvh "#endif"
 $write cvh "#ifdef USE_GNUTLS"
 $write cvh "#undef USE_GNUTLS"
diff --git a/scripts/contributors.sh b/scripts/contributors.sh
index d37c1199e..a826595c9 100755
--- a/scripts/contributors.sh
+++ b/scripts/contributors.sh
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2013-2018, Daniel Stenberg, <address@hidden>, et al.
+# Copyright (C) 2013-2019, Daniel Stenberg, <address@hidden>, 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 @@ fi
 # sort all unique names
 # awk them into RELEASE-NOTES format
 (
-git log --use-mailmap $start..HEAD | \
+git log --pretty=full --use-mailmap $start..HEAD | \
 egrep -ai '(^Author|^Commit|by):' | \
 cut -d: -f2- | \
 cut '-d(' -f1 | \
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 06b2e3a5b..35fcfbb80 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -53,7 +53,7 @@ source_group("curl header files" FILES ${GNURL_HFILES})
 include_directories(
   ${GNURL_SOURCE_DIR}/lib        # To be able to reach "curl_setup_once.h"
   ${GNURL_BINARY_DIR}/lib        # To be able to reach "curl_config.h"
-  ${GNURL_BINARY_DIR}/include    # To be able to reach "curl/curl.h"
+  ${GNURL_BINARY_DIR}/include    # To be able to reach "gnurl/curl.h"
   # This is needed as tool_hugehelp.c is generated in the binary dir
   ${GNURL_SOURCE_DIR}/src        # To be able to reach "tool_hugehelp.h"
   )
diff --git a/src/slist_wc.c b/src/slist_wc.c
index 5233b1b3b..da25632d1 100644
--- a/src/slist_wc.c
+++ b/src/slist_wc.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/slist_wc.h b/src/slist_wc.h
index 9bd6993db..54f871bfe 100644
--- a/src/slist_wc.h
+++ b/src/slist_wc.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_binmode.c b/src/tool_binmode.c
index f70015641..b88a0fd26 100644
--- a/src/tool_binmode.c
+++ b/src/tool_binmode.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_binmode.h b/src/tool_binmode.h
index 07b7ffedf..1ff0f76a8 100644
--- a/src/tool_binmode.h
+++ b/src/tool_binmode.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_bname.c b/src/tool_bname.c
index 761192fe9..6014c6bd8 100644
--- a/src/tool_bname.c
+++ b/src/tool_bname.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_bname.h b/src/tool_bname.h
index 66e7c1733..dfde5897c 100644
--- a/src/tool_bname.h
+++ b/src/tool_bname.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_cb_dbg.h b/src/tool_cb_dbg.h
index 433e74616..8883bb162 100644
--- a/src/tool_cb_dbg.h
+++ b/src/tool_cb_dbg.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index b0880f186..77224adba 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -59,6 +59,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, 
void *userdata)
   struct HdrCbData *hdrcbdata = &per->hdrcbdata;
   struct OutStruct *outs = &per->outs;
   struct OutStruct *heads = &per->heads;
+  struct OutStruct *etag_save = &per->etag_save;
   const char *str = ptr;
   const size_t cb = size * nmemb;
   const char *end = (char *)ptr + cb;
@@ -95,6 +96,59 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, 
void *userdata)
     (void)fflush(heads->stream);
   }
 
+  /*
+   * Write etag to file when --etag-save option is given.
+   * etag string that we want is enveloped in double quotes
+   */
+  if(etag_save->config->etag_save_file && etag_save->stream) {
+    /* match only header that start with etag (case insensitive) */
+    if(curl_strnequal(str, "etag:", 5)) {
+      char *etag_h = NULL;
+      char *first = NULL;
+      char *last = NULL;
+      size_t etag_length = 0;
+
+      etag_h = ptr;
+      /* point to first occurence of double quote */
+      first = memchr(etag_h, '\"', cb);
+
+      /*
+       * if server side messed with the etag header and doesn't include
+       * double quotes around the etag, kindly exit with a warning
+       */
+
+      if(!first) {
+        warnf(
+          etag_save->config->global,
+          "\nReceived header etag is missing double quote/s\n");
+        return 1;
+      }
+      else {
+        /* discard first double quote */
+        first++;
+      }
+
+      /* point to last occurence of double quote */
+      last = memchr(first, '\"', cb);
+
+      if(!last) {
+        warnf(
+          etag_save->config->global,
+          "\nReceived header etag is missing double quote/s\n");
+        return 1;
+      }
+
+      /* get length of desired etag */
+      etag_length = (size_t)last - (size_t)first;
+
+      fwrite(first, size, etag_length, etag_save->stream);
+      /* terminate with new line */
+      fputc('\n', etag_save->stream);
+    }
+
+    (void)fflush(etag_save->stream);
+  }
+
   /*
    * This callback sets the filename where output shall be written when
    * curl options --remote-name (-O) and --remote-header-name (-J) have
diff --git a/src/tool_cb_hdr.h b/src/tool_cb_hdr.h
index cf544dfcb..ec5772f55 100644
--- a/src/tool_cb_hdr.h
+++ b/src/tool_cb_hdr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -43,6 +43,7 @@ struct HdrCbData {
   struct OperationConfig *config;
   struct OutStruct *outs;
   struct OutStruct *heads;
+  struct OutStruct *etag_save;
   bool honor_cd_filename;
 };
 
diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c
index a18827c8b..505ae751f 100644
--- a/src/tool_cb_prg.c
+++ b/src/tool_cb_prg.c
@@ -32,6 +32,7 @@
 #include "tool_cfgable.h"
 #include "tool_cb_prg.h"
 #include "tool_util.h"
+#include "tool_operate.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
@@ -121,7 +122,10 @@ int tool_progress_cb(void *clientp,
      and this new edition inherits some of his concepts. */
 
   struct timeval now = tvnow();
-  struct ProgressData *bar = (struct ProgressData *)clientp;
+  struct per_transfer *per = clientp;
+  struct OutStruct *outs = &per->outs;
+  struct OperationConfig *config = outs->config;
+  struct ProgressData *bar = &per->progressbar;
   curl_off_t total;
   curl_off_t point;
 
@@ -191,6 +195,11 @@ int tool_progress_cb(void *clientp,
   bar->prev = point;
   bar->prevtime = now;
 
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(per->curl, CURLPAUSE_CONT);
+  }
+
   return 0;
 }
 
diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c
index 8a33c847b..03ed4a467 100644
--- a/src/tool_cb_rea.c
+++ b/src/tool_cb_rea.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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,6 +27,7 @@
 
 #include "tool_cfgable.h"
 #include "tool_cb_rea.h"
+#include "tool_operate.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
@@ -52,3 +53,28 @@ size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, 
void *userdata)
   in->config->readbusy = FALSE;
   return (size_t)rc;
 }
+
+/*
+** callback for CURLOPT_XFERINFOFUNCTION used to unpause busy reads
+*/
+
+int tool_readbusy_cb(void *clientp,
+                     curl_off_t dltotal, curl_off_t dlnow,
+                     curl_off_t ultotal, curl_off_t ulnow)
+{
+  struct per_transfer *per = clientp;
+  struct OutStruct *outs = &per->outs;
+  struct OperationConfig *config = outs->config;
+
+  (void)dltotal;  /* unused */
+  (void)dlnow;  /* unused */
+  (void)ultotal;  /* unused */
+  (void)ulnow;  /* unused */
+
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(per->curl, CURLPAUSE_CONT);
+  }
+
+  return per->noprogress? 0 : CURL_PROGRESSFUNC_CONTINUE;
+}
diff --git a/src/tool_cb_rea.h b/src/tool_cb_rea.h
index 475f0b1c3..5f7e483a3 100644
--- a/src/tool_cb_rea.h
+++ b/src/tool_cb_rea.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,4 +29,12 @@
 
 size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, void *userdata);
 
+/*
+** callback for CURLOPT_XFERINFOFUNCTION used to unpause busy reads
+*/
+
+int tool_readbusy_cb(void *clientp,
+                     curl_off_t dltotal, curl_off_t dlnow,
+                     curl_off_t ultotal, curl_off_t ulnow);
+
 #endif /* HEADER_CURL_TOOL_CB_REA_H */
diff --git a/src/tool_cb_see.c b/src/tool_cb_see.c
index 891dc458a..99be273d1 100644
--- a/src/tool_cb_see.c
+++ b/src/tool_cb_see.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_cb_see.h b/src/tool_cb_see.h
index ff8de0e9a..fed8bbf8d 100644
--- a/src/tool_cb_see.h
+++ b/src/tool_cb_see.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_cfgable.c b/src/tool_cfgable.c
index efa8c50b2..f802a5a31 100644
--- a/src/tool_cfgable.c
+++ b/src/tool_cfgable.c
@@ -128,6 +128,8 @@ static void free_config_fields(struct OperationConfig 
*config)
   Curl_safefree(config->pubkey);
   Curl_safefree(config->hostpubmd5);
   Curl_safefree(config->engine);
+  Curl_safefree(config->etag_save_file);
+  Curl_safefree(config->etag_compare_file);
   Curl_safefree(config->request_target);
   Curl_safefree(config->customrequest);
   Curl_safefree(config->krblevel);
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 7232c35e3..32e811eaa 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -156,6 +156,8 @@ struct OperationConfig {
   char *pubkey;
   char *hostpubmd5;
   char *engine;
+  char *etag_save_file;
+  char *etag_compare_file;
   bool crlf;
   char *customrequest;
   char *krblevel;
@@ -300,6 +302,7 @@ struct GlobalConfig {
 #endif
   bool parallel;
   long parallel_max;
+  bool parallel_connect;
   struct OperationConfig *first;
   struct OperationConfig *current;
   struct OperationConfig *last;   /* Always last in the struct */
diff --git a/src/tool_convert.h b/src/tool_convert.h
index 27b4ce90f..6d78ecf9d 100644
--- a/src/tool_convert.h
+++ b/src/tool_convert.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_dirhie.h b/src/tool_dirhie.h
index 011a5774f..96fae9ebf 100644
--- a/src/tool_dirhie.h
+++ b/src/tool_dirhie.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_doswin.c b/src/tool_doswin.c
index 779a3cb8f..a64a81633 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -38,33 +38,6 @@
 
 #include "memdebug.h" /* keep this as LAST include */
 
-/*
- * Macros ALWAYS_TRUE and ALWAYS_FALSE are used to avoid compiler warnings.
- */
-
-#define ALWAYS_TRUE   (1)
-#define ALWAYS_FALSE  (0)
-
-#if defined(_MSC_VER) && !defined(__POCC__)
-#  undef ALWAYS_TRUE
-#  undef ALWAYS_FALSE
-#  if (_MSC_VER < 1500)
-#    define ALWAYS_TRUE   (0, 1)
-#    define ALWAYS_FALSE  (1, 0)
-#  else
-#    define ALWAYS_TRUE \
-__pragma(warning(push)) \
-__pragma(warning(disable:4127)) \
-(1) \
-__pragma(warning(pop))
-#    define ALWAYS_FALSE \
-__pragma(warning(push)) \
-__pragma(warning(disable:4127)) \
-(0) \
-__pragma(warning(pop))
-#  endif
-#endif
-
 #ifdef WIN32
 #  undef  PATH_MAX
 #  define PATH_MAX MAX_PATH
@@ -79,9 +52,9 @@ __pragma(warning(pop))
 #endif
 
 #ifdef WIN32
-#  define _use_lfn(f) ALWAYS_TRUE   /* long file names always available */
+#  define _use_lfn(f) (1)   /* long file names always available */
 #elif !defined(__DJGPP__) || (__DJGPP__ < 2)  /* DJGPP 2.0 has _use_lfn() */
-#  define _use_lfn(f) ALWAYS_FALSE  /* long file names never available */
+#  define _use_lfn(f) (0)  /* long file names never available */
 #elif defined(__DJGPP__)
 #  include <fcntl.h>                /* _use_lfn(f) prototype */
 #endif
diff --git a/src/tool_doswin.h b/src/tool_doswin.h
index 415fac27e..457637665 100644
--- a/src/tool_doswin.h
+++ b/src/tool_doswin.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_easysrc.c b/src/tool_easysrc.c
index fc6600261..e8f514fc3 100644
--- a/src/tool_easysrc.c
+++ b/src/tool_easysrc.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -123,7 +123,7 @@ CURLcode easysrc_addf(struct slist_wc **plist, const char 
*fmt, ...)
   return ret;
 }
 
-#define CHKRET(v) do {CURLcode ret = (v); if(ret) return ret;} WHILE_FALSE
+#define CHKRET(v) do {CURLcode ret = (v); if(ret) return ret;} while(0)
 
 CURLcode easysrc_init(void)
 {
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 3882cb97e..a7bcdafac 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -58,7 +58,7 @@
     if(!(*(str)))          \
       return PARAM_NO_MEM; \
   } \
-} WHILE_FALSE
+} while(0)
 
 struct LongShort {
   const char *letter; /* short name option */
@@ -268,6 +268,8 @@ static const struct LongShort aliases[]= {
   {"E9", "proxy-tlsv1",              ARG_NONE},
   {"EA", "socks5-basic",             ARG_BOOL},
   {"EB", "socks5-gssapi",            ARG_BOOL},
+  {"EC", "etag-save",                ARG_FILENAME},
+  {"ED", "etag-compare",             ARG_FILENAME},
   {"f",  "fail",                     ARG_BOOL},
   {"fa", "fail-early",               ARG_BOOL},
   {"fb", "styled-output",            ARG_BOOL},
@@ -321,6 +323,7 @@ static const struct LongShort aliases[]= {
   {"z",  "time-cond",                ARG_STRING},
   {"Z",  "parallel",                 ARG_BOOL},
   {"Zb", "parallel-max",             ARG_STRING},
+  {"Zc", "parallel-immediate",       ARG_BOOL},
   {"#",  "progress-bar",             ARG_BOOL},
   {"#m", "progress-meter",           ARG_BOOL},
   {":",  "next",                     ARG_NONE},
@@ -1696,6 +1699,14 @@ ParameterError getparameter(const char *flag, /* f or 
-long-flag */
           config->socks5_auth &= ~CURLAUTH_GSSAPI;
         break;
 
+      case 'C':
+        GetStr(&config->etag_save_file, nextarg);
+        break;
+
+      case 'D':
+        GetStr(&config->etag_compare_file, nextarg);
+        break;
+
       default: /* unknown flag */
         return PARAM_OPTION_UNKNOWN;
       }
@@ -2154,6 +2165,9 @@ ParameterError getparameter(const char *flag, /* f or 
-long-flag */
            (global->parallel_max < 1))
           global->parallel_max = PARALLEL_DEFAULT;
         break;
+      case 'c':   /* --parallel-connect */
+        global->parallel_connect = toggle;
+        break;
       }
       break;
     case 'z': /* time condition coming up */
diff --git a/src/tool_help.c b/src/tool_help.c
index 022956676..8d3f34547 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -131,6 +131,10 @@ static const struct helptxt helptext[] = {
    "EGD socket path for random data"},
   {"    --engine <name>",
    "Crypto engine to use"},
+  {"    --etag-save <file>",
+   "Get an ETag from response header and save it to a FILE"},
+  {"    --etag-compare <file>",
+   "Get an ETag from a file and send a conditional request"},
   {"    --expect100-timeout <seconds>",
    "How long to wait for 100-continue"},
   {"-f, --fail",
@@ -279,6 +283,8 @@ static const struct helptxt helptext[] = {
    "Write to file instead of stdout"},
   {"-Z, --parallel",
    "Perform transfers in parallel"},
+  {"    --parallel-immediate",
+   "Do not wait for multiplexing (with --parallel)"},
   {"    --parallel-max",
    "Maximum concurrency for parallel transfers"},
   {"    --pass <phrase>",
diff --git a/src/tool_helpers.h b/src/tool_helpers.h
index 33483ebc3..67d28be2a 100644
--- a/src/tool_helpers.h
+++ b/src/tool_helpers.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_homedir.c b/src/tool_homedir.c
index 483553d59..6bc69551e 100644
--- a/src/tool_homedir.c
+++ b/src/tool_homedir.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_homedir.h b/src/tool_homedir.h
index 98d94b8e5..1f9d54a63 100644
--- a/src/tool_homedir.h
+++ b/src/tool_homedir.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_hugehelp.h b/src/tool_hugehelp.h
index 16520b6ee..9f9396903 100644
--- a/src/tool_hugehelp.h
+++ b/src/tool_hugehelp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_libinfo.c b/src/tool_libinfo.c
index 19ec65ac6..de7ec4d18 100644
--- a/src/tool_libinfo.c
+++ b/src/tool_libinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_libinfo.h b/src/tool_libinfo.h
index b3a9b9cdd..9563cc3ed 100644
--- a/src/tool_libinfo.h
+++ b/src/tool_libinfo.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_main.c b/src/tool_main.c
index 4803adbb3..06923c332 100644
--- a/src/tool_main.c
+++ b/src/tool_main.c
@@ -166,17 +166,17 @@ static CURLcode main_init(struct GlobalConfig *config)
         config->first->global = config;
       }
       else {
-        helpf(stderr, "error retrieving curl library information\n");
+        errorf(config, "error retrieving curl library information\n");
         free(config->first);
       }
     }
     else {
-      helpf(stderr, "error initializing curl library\n");
+      errorf(config, "error initializing curl library\n");
       free(config->first);
     }
   }
   else {
-    helpf(stderr, "error initializing curl\n");
+    errorf(config, "error initializing curl\n");
     result = CURLE_FAILED_INIT;
   }
 
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index 889da4bff..6d62f2d93 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -119,7 +119,7 @@ struct win32_crypto_hash {
     *(str) = strdup((val)); \
   if(!(val)) \
     return PARAM_NO_MEM; \
-} WHILE_FALSE
+} while(0)
 
 #if defined(USE_OPENSSL)
 /* Functions are already defined */
diff --git a/src/tool_msgs.c b/src/tool_msgs.c
index f5e1df25f..48877b30d 100644
--- a/src/tool_msgs.c
+++ b/src/tool_msgs.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,6 +32,7 @@
 
 #define WARN_PREFIX "Warning: "
 #define NOTE_PREFIX "Note: "
+#define ERROR_PREFIX "curl: "
 
 static void voutf(struct GlobalConfig *config,
                   const char *prefix,
@@ -104,9 +105,9 @@ void warnf(struct GlobalConfig *config, const char *fmt, 
...)
   va_end(ap);
 }
 /*
- * Emit help formatted message on given stream.
+ * Emit help formatted message on given stream. This is for errors with or
+ * related to command line arguments.
  */
-
 void helpf(FILE *errors, const char *fmt, ...)
 {
   if(fmt) {
@@ -122,3 +123,17 @@ void helpf(FILE *errors, const char *fmt, ...)
 #endif
           "for more information\n");
 }
+
+/*
+ * Emit error message on error stream if not muted. When errors are not tied
+ * to command line arguments, use helpf() for such errors.
+ */
+void errorf(struct GlobalConfig *config, const char *fmt, ...)
+{
+  if(!config->mute) {
+    va_list ap;
+    va_start(ap, fmt);
+    voutf(config, ERROR_PREFIX, fmt, ap);
+    va_end(ap);
+  }
+}
diff --git a/src/tool_msgs.h b/src/tool_msgs.h
index d1cc7f8d5..2c4afd180 100644
--- a/src/tool_msgs.h
+++ b/src/tool_msgs.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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,7 +25,7 @@
 
 void warnf(struct GlobalConfig *config, const char *fmt, ...);
 void notef(struct GlobalConfig *config, const char *fmt, ...);
-
 void helpf(FILE *errors, const char *fmt, ...);
+void errorf(struct GlobalConfig *config, const char *fmt, ...);
 
 #endif /* HEADER_CURL_TOOL_MSGS_H */
diff --git a/src/tool_operate.c b/src/tool_operate.c
index e83ad4195..e35c781f9 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -644,6 +644,12 @@ static CURLcode post_per_transfer(struct GlobalConfig 
*global,
   if(per->heads.alloc_filename)
     Curl_safefree(per->heads.filename);
 
+  if(per->etag_save.fopened && per->etag_save.stream)
+    fclose(per->etag_save.stream);
+
+  if(per->etag_save.alloc_filename)
+    Curl_safefree(per->etag_save.filename);
+
   curl_easy_cleanup(per->curl);
   if(outs->alloc_filename)
     free(outs->filename);
@@ -700,7 +706,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
         httpgetfields = state->httpgetfields = strdup(config->postfields);
         Curl_safefree(config->postfields);
         if(!httpgetfields) {
-          helpf(global->errors, "out of memory\n");
+          errorf(global, "out of memory\n");
           result = CURLE_OUT_OF_MEMORY;
         }
         else if(SetHTTPrequest(config,
@@ -762,7 +768,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
     if(urlnode->outfile && !state->outfiles) {
       state->outfiles = strdup(urlnode->outfile);
       if(!state->outfiles) {
-        helpf(global->errors, "out of memory\n");
+        errorf(global, "out of memory\n");
         result = CURLE_OUT_OF_MEMORY;
         break;
       }
@@ -790,12 +796,12 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           if(inglob) {
             result = glob_next_url(&state->uploadfile, inglob);
             if(result == CURLE_OUT_OF_MEMORY)
-              helpf(global->errors, "out of memory\n");
+              errorf(global, "out of memory\n");
           }
           else if(!state->up) {
             state->uploadfile = strdup(infiles);
             if(!state->uploadfile) {
-              helpf(global->errors, "out of memory\n");
+              errorf(global, "out of memory\n");
               result = CURLE_OUT_OF_MEMORY;
             }
           }
@@ -829,17 +835,12 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
       separator = ((!state->outfiles ||
                     !strcmp(state->outfiles, "-")) && urlnum > 1);
 
-      /* Here's looping around each globbed URL */
-
-      if(state->li >= urlnum) {
-        state->li = 0;
-        state->up++;
-      }
       if(state->up < state->infilenum) {
         struct per_transfer *per;
         struct OutStruct *outs;
         struct InStruct *input;
         struct OutStruct *heads;
+        struct OutStruct *etag_save;
         struct HdrCbData *hdrcbdata = NULL;
         CURL *curl = curl_easy_init();
         result = add_per_transfer(&per);
@@ -888,6 +889,75 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           }
         }
 
+        /* --etag-save */
+        etag_save = &per->etag_save;
+        etag_save->stream = stdout;
+        etag_save->config = config;
+        if(config->etag_save_file) {
+          /* open file for output: */
+          if(strcmp(config->etag_save_file, "-")) {
+            FILE *newfile = fopen(config->etag_save_file, "wb");
+            if(!newfile) {
+              warnf(
+                config->global,
+                "Failed to open %s\n", config->etag_save_file);
+
+              result = CURLE_WRITE_ERROR;
+              break;
+            }
+            else {
+              etag_save->filename = config->etag_save_file;
+              etag_save->s_isreg = TRUE;
+              etag_save->fopened = TRUE;
+              etag_save->stream = newfile;
+            }
+          }
+          else {
+            /* always use binary mode for protocol header output */
+            set_binmode(etag_save->stream);
+          }
+        }
+
+        /* --etag-compare */
+        if(config->etag_compare_file) {
+          char *etag_from_file = NULL;
+          char *header = NULL;
+
+          /* open file for reading: */
+          FILE *file = fopen(config->etag_compare_file, FOPEN_READTEXT);
+          if(!file) {
+            errorf(config->global,
+                   "Failed to open %s\n", config->etag_compare_file);
+            result = CURLE_READ_ERROR;
+            break;
+          }
+
+          if((PARAM_OK == file2string(&etag_from_file, file)) &&
+             etag_from_file) {
+            header = aprintf("If-None-Match: \"%s\"", etag_from_file);
+            Curl_safefree(etag_from_file);
+          }
+          else
+            header = aprintf("If-None-Match: \"\"");
+
+          if(!header) {
+            if(file)
+              fclose(file);
+            errorf(config->global,
+                   "Failed to allocate memory for custom etag header\n");
+            result = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+
+          /* add Etag from file to list of custom headers */
+          add2list(&config->headers, header);
+
+          Curl_safefree(header);
+
+          if(file) {
+            fclose(file);
+          }
+        }
 
         hdrcbdata = &per->hdrcbdata;
 
@@ -959,7 +1029,7 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
             if(result)
               break;
             if(!*per->outfile && !config->content_disposition) {
-              helpf(global->errors, "Remote file name has no length!\n");
+              errorf(global, "Remote file name has no length!\n");
               result = CURLE_WRITE_ERROR;
               break;
             }
@@ -1016,7 +1086,7 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
             FILE *file = fopen(per->outfile, "ab");
 #endif
             if(!file) {
-              helpf(global->errors, "Can't open '%s'!\n", per->outfile);
+              errorf(global, "Can't open '%s'!\n", per->outfile);
               result = CURLE_WRITE_ERROR;
               break;
             }
@@ -1086,11 +1156,11 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
            isatty(fileno(outs->stream)))
           /* we send the output to a tty, therefore we switch off the progress
              meter */
-          global->noprogress = global->isatty = TRUE;
+          per->noprogress = global->noprogress = global->isatty = TRUE;
         else {
           /* progress meter is per download, so restore config
              values */
-          global->noprogress = orig_noprogress;
+          per->noprogress = global->noprogress = orig_noprogress;
           global->isatty = orig_isatty;
         }
 
@@ -1521,7 +1591,7 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           if(!config->insecure_ok) {
             char *home;
             char *file;
-            result = CURLE_OUT_OF_MEMORY;
+            result = CURLE_FAILED_INIT;
             home = homedir();
             if(home) {
               file = aprintf("%s/.ssh/known_hosts", home);
@@ -1535,6 +1605,9 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
               }
               Curl_safefree(home);
             }
+            else {
+              errorf(global, "Failed to figure out user's home dir!");
+            }
             if(result)
               break;
           }
@@ -1579,7 +1652,14 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           /* we want the alternative style, then we have to implement it
              ourselves! */
           my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
-          my_setopt(curl, CURLOPT_XFERINFODATA, &per->progressbar);
+          my_setopt(curl, CURLOPT_XFERINFODATA, per);
+        }
+        else if(per->uploadfile && !strcmp(per->uploadfile, ".")) {
+          /* when reading from stdin in non-blocking mode, we use the progress
+             function to unpause a busy read */
+          my_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+          my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_readbusy_cb);
+          my_setopt(curl, CURLOPT_XFERINFODATA, per);
         }
 
         /* new in libcurl 7.24.0: */
@@ -1768,6 +1848,7 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
 
         hdrcbdata->outs = outs;
         hdrcbdata->heads = heads;
+        hdrcbdata->etag_save = etag_save;
         hdrcbdata->global = global;
         hdrcbdata->config = config;
 
@@ -1908,6 +1989,15 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
         per->retrystart = tvnow();
 
         state->li++;
+        /* Here's looping around each globbed URL */
+        if(state->li >= urlnum) {
+          state->li = 0;
+          state->urlnum = 0; /* forced reglob of URLs */
+          glob_cleanup(state->urls);
+          state->urls = NULL;
+          state->up++;
+          Curl_safefree(state->uploadfile); /* clear it to get the next */
+        }
       }
       else {
         /* Free this URL node data without destroying the
@@ -1973,6 +2063,10 @@ static CURLcode add_parallel_transfers(struct 
GlobalConfig *global,
     if(result)
       break;
 
+    /* parallel connect means that we don't set PIPEWAIT since pipewait
+       will make libcurl prefer multiplexing */
+    (void)curl_easy_setopt(per->curl, CURLOPT_PIPEWAIT,
+                           global->parallel_connect ? 0L : 1L);
     (void)curl_easy_setopt(per->curl, CURLOPT_PRIVATE, per);
     (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb);
     (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per);
@@ -2193,7 +2287,7 @@ static CURLcode transfer_per_config(struct GlobalConfig 
*global,
         config->cacert = strdup(env);
         if(!config->cacert) {
           curl_free(env);
-          helpf(global->errors, "out of memory\n");
+          errorf(global, "out of memory\n");
           return CURLE_OUT_OF_MEMORY;
         }
       }
@@ -2214,7 +2308,7 @@ static CURLcode transfer_per_config(struct GlobalConfig 
*global,
             config->cacert = strdup(env);
             if(!config->cacert) {
               curl_free(env);
-              helpf(global->errors, "out of memory\n");
+              errorf(global, "out of memory\n");
               return CURLE_OUT_OF_MEMORY;
             }
           }
@@ -2403,7 +2497,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, 
argv_item_t argv[])
 #endif
       }
       else
-        helpf(global->errors, "out of memory\n");
+        errorf(global, "out of memory\n");
     }
   }
 
diff --git a/src/tool_operate.h b/src/tool_operate.h
index 60257fc60..39227c0f3 100644
--- a/src/tool_operate.h
+++ b/src/tool_operate.h
@@ -44,9 +44,11 @@ struct per_transfer {
   char *outfile;
   bool infdopen; /* TRUE if infd needs closing */
   int infd;
+  bool noprogress;
   struct ProgressData progressbar;
   struct OutStruct outs;
   struct OutStruct heads;
+  struct OutStruct etag_save;
   struct InStruct input;
   struct HdrCbData hdrcbdata;
   char errorbuffer[CURL_ERROR_SIZE];
diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c
index 543bf4302..8a9b7c9e8 100644
--- a/src/tool_operhlp.c
+++ b/src/tool_operhlp.c
@@ -115,16 +115,17 @@ char *add_file_name_to_url(char *url, const char 
*filename)
         urlbuffer = aprintf("%s/%s", url, encfile);
 
       curl_free(encfile);
-      Curl_safefree(url);
 
-      if(!urlbuffer)
-        return NULL;
+      if(!urlbuffer) {
+        url = NULL;
+        goto end;
+      }
 
+      Curl_safefree(url);
       url = urlbuffer; /* use our new URL instead! */
     }
-    else
-      Curl_safefree(url);
   }
+  end:
   curl_easy_cleanup(curl);
   return url;
 }
diff --git a/src/tool_panykey.c b/src/tool_panykey.c
index b0e556307..7c519028a 100644
--- a/src/tool_panykey.c
+++ b/src/tool_panykey.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_panykey.h b/src/tool_panykey.h
index 6371a88a7..e5c6f3930 100644
--- a/src/tool_panykey.h
+++ b/src/tool_panykey.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_paramhlp.c b/src/tool_paramhlp.c
index af47516b6..b7a8efbd2 100644
--- a/src/tool_paramhlp.c
+++ b/src/tool_paramhlp.c
@@ -606,7 +606,7 @@ CURLcode get_args(struct OperationConfig *config, const 
size_t i)
   if(!config->useragent) {
     config->useragent = my_useragent();
     if(!config->useragent) {
-      helpf(config->global->errors, "out of memory\n");
+      errorf(config->global, "out of memory\n");
       result = CURLE_OUT_OF_MEMORY;
     }
   }
diff --git a/src/tool_parsecfg.h b/src/tool_parsecfg.h
index 340626190..49919a7f2 100644
--- a/src/tool_parsecfg.h
+++ b/src/tool_parsecfg.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_progress.c b/src/tool_progress.c
index a2667f38e..ac4f58f41 100644
--- a/src/tool_progress.c
+++ b/src/tool_progress.c
@@ -95,10 +95,18 @@ int xferinfo_cb(void *clientp,
                 curl_off_t ulnow)
 {
   struct per_transfer *per = clientp;
+  struct OutStruct *outs = &per->outs;
+  struct OperationConfig *config = outs->config;
   per->dltotal = dltotal;
   per->dlnow = dlnow;
   per->ultotal = ultotal;
   per->ulnow = ulnow;
+
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(per->curl, CURLPAUSE_CONT);
+  }
+
   return 0;
 }
 
diff --git a/src/tool_sdecls.h b/src/tool_sdecls.h
index ebec9eebb..562fef852 100644
--- a/src/tool_sdecls.h
+++ b/src/tool_sdecls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_setopt.c b/src/tool_setopt.c
index 4c98d9057..9b308bf4a 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -124,6 +124,7 @@ const NameValue setopt_nv_CURLUSESSL[] = {
 const NameValueUnsigned setopt_nv_CURLSSLOPT[] = {
   NV(CURLSSLOPT_ALLOW_BEAST),
   NV(CURLSSLOPT_NO_REVOKE),
+  NV(CURLSSLOPT_NO_PARTIALCHAIN),
   NVEND,
 };
 
@@ -181,18 +182,18 @@ static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
   ret = easysrc_add args; \
   if(ret) \
     goto nomem; \
-} WHILE_FALSE
+} while(0)
 #define ADDF(args) do { \
   ret = easysrc_addf args; \
   if(ret) \
     goto nomem; \
-} WHILE_FALSE
+} while(0)
 #define NULL_CHECK(p) do { \
   if(!p) { \
     ret = CURLE_OUT_OF_MEMORY; \
     goto nomem; \
   } \
-} WHILE_FALSE
+} while(0)
 
 #define DECL0(s) ADD((&easysrc_decl, s))
 #define DECL1(f,a) ADDF((&easysrc_decl, f,a))
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
index 63401337f..48e9e818d 100644
--- a/src/tool_setopt.h
+++ b/src/tool_setopt.h
@@ -35,7 +35,7 @@
       if(result)                                \
         break;                                  \
     }                                           \
-  } WHILE_FALSE
+  } while(0)
 
 /* allow removed features to simulate success: */
 bool tool_setopt_skip(CURLoption tag);
diff --git a/src/tool_setup.h b/src/tool_setup.h
index d3abd5611..51da5b62e 100644
--- a/src/tool_setup.h
+++ b/src/tool_setup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_sleep.c b/src/tool_sleep.c
index edb5aedc0..67a54435f 100644
--- a/src/tool_sleep.c
+++ b/src/tool_sleep.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_sleep.h b/src/tool_sleep.h
index 3aaab52d7..59be6aa33 100644
--- a/src/tool_sleep.h
+++ b/src/tool_sleep.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_strdup.h b/src/tool_strdup.h
index f84b202e0..e30e40310 100644
--- a/src/tool_strdup.h
+++ b/src/tool_strdup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_urlglob.h b/src/tool_urlglob.h
index 55ac34611..82326c0a0 100644
--- a/src/tool_urlglob.h
+++ b/src/tool_urlglob.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_util.c b/src/tool_util.c
index 9990a4634..04d73e4e3 100644
--- a/src/tool_util.c
+++ b/src/tool_util.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_util.h b/src/tool_util.h
index 5339c1167..8e4a3f4a6 100644
--- a/src/tool_util.h
+++ b/src/tool_util.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_version.h b/src/tool_version.h
index b18a852ea..dff9d273e 100644
--- a/src/tool_version.h
+++ b/src/tool_version.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_vms.c b/src/tool_vms.c
index 54871a65e..7fa0dd62b 100644
--- a/src/tool_vms.c
+++ b/src/tool_vms.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_vms.h b/src/tool_vms.h
index 96c86f1ce..135936986 100644
--- a/src/tool_vms.h
+++ b/src/tool_vms.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_writeout.h b/src/tool_writeout.h
index 8d3f645ff..ee8990f77 100644
--- a/src/tool_writeout.h
+++ b/src/tool_writeout.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/src/tool_xattr.h b/src/tool_xattr.h
index 56bd9e4a0..0339b9b97 100644
--- a/src/tool_xattr.h
+++ b/src/tool_xattr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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/tests/Makefile.am b/tests/Makefile.am
index 3a3a921bb..5d877d7ec 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -24,6 +24,7 @@ MANDISTPAGES = runtests.1.dist testcurl.1.dist
 
 # the path to the impacket python lib used for SMB tests
 IMP = python_dependencies/impacket
+
 SMB_1 = $(IMP)/__init__.py $(IMP)/nmb.py $(IMP)/nt_errors.py
 SMB_2 = $(IMP)/ntlm.py $(IMP)/smb.py $(IMP)/smb3.py $(IMP)/smb3structs.py
 SMB_3 = $(IMP)/smbserver.py $(IMP)/spnego.py $(IMP)/structure.py
@@ -37,7 +38,7 @@ ED_4 = serverhelp.pm tftpserver.pl rtspserver.pl 
directories.pm symbol-scan.pl
 ED_5 = mem-include-scan.pl valgrind.supp extern-scan.pl
 ED_6 = manpage-scan.pl nroff-scan.pl http2-server.pl dictserver.py.in
 ED_7 = negtelnetserver.py.in $(SMBDEPS) objnames-test08.sh objnames-test10.sh
-ED_8 = objnames.inc disable-scan.pl
+ED_8 = objnames.inc disable-scan.pl error-codes.pl CMakeLists.txt
 
 EXTRA_DIST = $(ED_1) $(ED_2) $(ED_3) $(ED_4) $(ED_5) $(ED_6) $(ED_7) $(ED_8)
 
diff --git a/tests/data/DISABLED b/tests/data/DISABLED
index 61bdf1351..f0d6f8c7f 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -28,3 +28,5 @@
 1901
 1902
 2033
+# Unused in gnurl
+test1173
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 846eb4046..29a66ee8d 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -57,15 +57,16 @@ test298 test299 test300 test301 test302 test303 test304 
test305 test306 \
 test307 test308 test309 test310 test311 test312 test313 test314 test315 \
 test316 test317 test318 test319 test320 test321 test322 test323 test324 \
 test325 test326 test327 test328 test329 test330 test331 test332 test333 \
-test334 test335 test336 test337 test338 \
-test340 \
-\
+test334 test335 test336 test337 test338 test339 test340 test341 test342 \
+test343 \
 test350 test351 test352 test353 test354 test355 test356 \
 test393 test394 test395 \
 \
 test400 test401 test402 test403 test404 test405 test406 test407 test408 \
 test409 \
 \
+test490 test491 test492 \
+\
 test500 test501 test502 test503 test504 test505 test506 test507 test508 \
 test509 test510 test511 test512 test513 test514 test515 test516 test517 \
 test518 test519 test520 test521 test522 test523 test524 test525 test526 \
@@ -131,7 +132,7 @@ test1136 test1137 test1138                   test1141 
test1142 test1143 \
 test1144 test1145 test1146 test1147 test1148 test1149 test1150 test1151 \
 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 \
 test1160 test1161 test1162 test1163 test1164 test1165 test1166 \
-test1170 test1171 test1172 test1174 \
+test1170 test1171 test1172 test1173 test1174 test1175 \
 \
 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
 test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
@@ -177,7 +178,7 @@ test1525 test1526 test1527 test1528 test1529 test1530 
test1531 test1532 \
 test1533 test1534 test1535 test1536 test1537 test1538 \
 test1540 test1541 \
 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
-test1558 test1559 test1560 test1561 test1562 test1563 \
+test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
 \
 test1590 test1591 test1592 test1593 test1594 test1595 test1596 \
 \
diff --git a/tests/data/test1135 b/tests/data/test1135
index eca6860fb..37a55427f 100644
--- a/tests/data/test1135
+++ b/tests/data/test1135
@@ -92,6 +92,7 @@ CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM 
*multi_handle,
 CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
 CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
 CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
+CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
 CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
 CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
 CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
diff --git a/tests/data/test1139.skip b/tests/data/test1173
similarity index 61%
copy from tests/data/test1139.skip
copy to tests/data/test1173
index 470682e11..dd09f81d8 100644
--- a/tests/data/test1139.skip
+++ b/tests/data/test1173
@@ -2,7 +2,6 @@
 <info>
 <keywords>
 source analysis
-symbols-in-versions
 documentation
 --manual
 </keywords>
@@ -16,11 +15,11 @@ none
 </server>
 
  <name>
-Verify that all libgnurl options have man pages
+Basic man page syntax check
  </name>
 
 <command type="perl">
-%SRCDIR/manpage-scan.pl %SRCDIR/.. %PWD/..
+%SRCDIR/manpage-syntax.pl %SRCDIR/../docs/*.1  %SRCDIR/../docs/libcurl/*.3 
%SRCDIR/../docs/libcurl/opts/*.3
 </command>
 </client>
 
diff --git a/tests/data/test1119 b/tests/data/test1175
similarity index 66%
copy from tests/data/test1119
copy to tests/data/test1175
index 7406521c4..61f068915 100644
--- a/tests/data/test1119
+++ b/tests/data/test1175
@@ -14,11 +14,11 @@ none
 </server>
 
  <name>
-Verify that symbols-in-versions and headers are in sync
+Verify that symbols-in-versions and libcurl-errors.3 are in sync
  </name>
 
 <command type="perl">
-%SRCDIR/symbol-scan.pl %SRCDIR/.. ../include/gnurl
+%SRCDIR/error-codes.pl %SRCDIR
 </command>
 </client>
 
diff --git a/tests/data/test1538 b/tests/data/test1538
index 9374debb7..3b22ebc27 100644
--- a/tests/data/test1538
+++ b/tests/data/test1538
@@ -127,7 +127,8 @@ e91: SSL server certificate status verification FAILED
 e92: Stream error in the HTTP/2 framing layer
 e93: API function called from within callback
 e94: An authentication function returned an error
-e95: Unknown error
+e95: HTTP/3 error
+e96: Unknown error
 m-1: Please call curl_multi_perform() soon
 m0: No error
 m1: Invalid multi handle
@@ -138,7 +139,8 @@ m5: Invalid socket argument
 m6: Unknown option
 m7: The easy handle is already added to a multi handle
 m8: API function called from within callback
-m9: Unknown error
+m9: Wakeup is unavailable or failed
+m10: Unknown error
 s0: No error
 s1: Unknown share option
 s2: Share currently in use
diff --git a/tests/data/test1554 b/tests/data/test1554
index be48e02eb..06f189724 100644
--- a/tests/data/test1554
+++ b/tests/data/test1554
@@ -38,6 +38,8 @@ run 1: foobar and so on fun!
 <- Mutex unlock
 -> Mutex lock
 <- Mutex unlock
+-> Mutex lock
+<- Mutex unlock
 run 1: foobar and so on fun!
 -> Mutex lock
 <- Mutex unlock
@@ -47,6 +49,8 @@ run 1: foobar and so on fun!
 <- Mutex unlock
 -> Mutex lock
 <- Mutex unlock
+-> Mutex lock
+<- Mutex unlock
 run 1: foobar and so on fun!
 -> Mutex lock
 <- Mutex unlock
@@ -54,6 +58,8 @@ run 1: foobar and so on fun!
 <- Mutex unlock
 -> Mutex lock
 <- Mutex unlock
+-> Mutex lock
+<- Mutex unlock
 </datacheck>
 </reply>
 
diff --git a/tests/data/test1558 b/tests/data/test1558
index 8436c0685..f1538c2a8 100644
--- a/tests/data/test1558
+++ b/tests/data/test1558
@@ -23,12 +23,8 @@ lib1558
 <name>
 CURLINFO_PROTOCOL for file:// transfer
 </name>
-<setenv>
-# force MSYS2 to not convert the file: URL
-MSYS2_ARG_CONV_EXCL=file:
-</setenv>
 <command>
-file:%FILE_PWD/log/data1558
+file://%FILE_PWD/log/data1558
 </command>
 <file name="log/data1558">
 hello
diff --git a/tests/data/test1560 b/tests/data/test1560
index a0e603bfc..0a132a1c1 100644
--- a/tests/data/test1560
+++ b/tests/data/test1560
@@ -22,6 +22,7 @@ imap
 ldap
 dict
 ftp
+ipv6
 </features>
  <name>
 URL API
diff --git a/tests/data/test1323 b/tests/data/test1564
similarity index 75%
copy from tests/data/test1323
copy to tests/data/test1564
index c5e598cc4..279665bd1 100644
--- a/tests/data/test1323
+++ b/tests/data/test1564
@@ -1,31 +1,30 @@
 <testcase>
 <info>
 <keywords>
-unittest
-curlx_tvdiff
+multi
+wakeup
 </keywords>
 </info>
 
-#
 # Server-side
 <reply>
 </reply>
 
-#
 # Client-side
 <client>
 <server>
 none
 </server>
-<name>
-curlx_tvdiff
-</name>
 <tool>
-unit1323
+lib1564
 </tool>
+<name>
+wakeup before poll with no easy handles
+</name>
+<command>
+</command>
 </client>
 
-#
 # Verify data after the test has been "shot"
 <verify>
 </verify>
diff --git a/tests/data/test1541 b/tests/data/test1565
similarity index 68%
copy from tests/data/test1541
copy to tests/data/test1565
index e18bb47df..f554e0f34 100644
--- a/tests/data/test1541
+++ b/tests/data/test1565
@@ -3,13 +3,20 @@
 <keywords>
 HTTP
 HTTP GET
+multi
 multi-threaded
-connection-sharing
+wakeup
 </keywords>
 </info>
 
 # Server-side
 <reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Content-Length: 3
+
+OK
+</data>
 </reply>
 
 # Client-side
@@ -18,12 +25,12 @@ connection-sharing
 http
 </server>
 <tool>
-lib1541
+lib1565
 </tool>
- <name>
-connection sharing using 67 parallel threads for 7 seconds
- </name>
- <command>
+<name>
+wakeup from another thread
+</name>
+<command>
 http://%HOSTIP:%HTTPPORT/1
 </command>
 </client>
diff --git a/tests/data/test1650 b/tests/data/test1650
index 13ca023e0..7a02a6dac 100644
--- a/tests/data/test1650
+++ b/tests/data/test1650
@@ -14,7 +14,7 @@ none
 </server>
 <features>
 unittest
-http/2
+DoH
 </features>
  <name>
 DOH
diff --git a/tests/data/test1655 b/tests/data/test1655
index 0c10bedf4..2e73f55d9 100644
--- a/tests/data/test1655
+++ b/tests/data/test1655
@@ -14,6 +14,7 @@ none
 </server>
 <features>
 unittest
+DoH
 </features>
  <name>
 unit test for doh_encode
diff --git a/tests/data/test2100 b/tests/data/test2100
index 0414b58d8..6dce69b64 100644
Binary files a/tests/data/test2100 and b/tests/data/test2100 differ
diff --git a/tests/data/test1416 b/tests/data/test339
similarity index 71%
copy from tests/data/test1416
copy to tests/data/test339
index 546575e5d..cd6e49892 100644
--- a/tests/data/test1416
+++ b/tests/data/test339
@@ -3,27 +3,29 @@
 <keywords>
 HTTP
 HTTP GET
-chunked Transfer-Encoding
 </keywords>
 </info>
 #
 # Server-side
 <reply>
 <data nocheck="yes">
-HTTP/1.1 200 funky chunky!
-Server: fakeit/0.9 fakeitbad/1.0
-Transfer-Encoding: chunked
-Connection: mooo
-
-12345678123456789
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-30
-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-21;heresatest=moooo
-cccccccccccccccccccccccccccccccc
-
-0
+HTTP/1.1 200 funky chunky!
+Server: fakeit/0.9 fakeitbad/1.0
+Transfer-Encoding: chunked
+Trailer: chunky-trailer
+Connection: mooo
+ETag: "asdf"
 
+40
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+30
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+21;heresatest=moooo
+cccccccccccccccccccccccccccccccc
+
+0
+chunky-trailer: header data
+
 </data>
 </reply>
 
@@ -33,11 +35,11 @@ cccccccccccccccccccccccccccccccc
 <server>
 http
 </server>
- <name>
-HTTP GET with chunked Transfer-Encoding overflowed chunked size
- </name>
- <command>
-http://%HOSTIP:%HTTPPORT/1416
+<name>
+Check if --etag-save saved correct etag to a file
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/339 --etag-save log/etag339
 </command>
 </client>
 
@@ -48,16 +50,14 @@ http://%HOSTIP:%HTTPPORT/1416
 ^User-Agent:.*
 </strip>
 <protocol>
-GET /1416 HTTP/1.1
+GET /339 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
 
 </protocol>
-
-# 56 = CURLE_RECV_ERROR
-<errorcode>
-56
-</errorcode>
+<file name="log/etag339">
+asdf
+</file>
 </verify>
 
 </testcase>
diff --git a/tests/data/test1416 b/tests/data/test341
similarity index 68%
copy from tests/data/test1416
copy to tests/data/test341
index 546575e5d..5e952ad98 100644
--- a/tests/data/test1416
+++ b/tests/data/test341
@@ -3,27 +3,29 @@
 <keywords>
 HTTP
 HTTP GET
-chunked Transfer-Encoding
 </keywords>
 </info>
 #
 # Server-side
 <reply>
 <data nocheck="yes">
-HTTP/1.1 200 funky chunky!
-Server: fakeit/0.9 fakeitbad/1.0
-Transfer-Encoding: chunked
-Connection: mooo
-
-12345678123456789
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-30
-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-21;heresatest=moooo
-cccccccccccccccccccccccccccccccc
-
-0
+HTTP/1.1 200 funky chunky!
+Server: fakeit/0.9 fakeitbad/1.0
+Transfer-Encoding: chunked
+Trailer: chunky-trailer
+Connection: mooo
+ETag: "asdf"
 
+40
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+30
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+21;heresatest=moooo
+cccccccccccccccccccccccccccccccc
+
+0
+chunky-trailer: header data
+
 </data>
 </reply>
 
@@ -33,11 +35,11 @@ cccccccccccccccccccccccccccccccc
 <server>
 http
 </server>
- <name>
-HTTP GET with chunked Transfer-Encoding overflowed chunked size
- </name>
- <command>
-http://%HOSTIP:%HTTPPORT/1416
+<name>
+Try to open a non existing file with --etag-compare should return an error
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/341 --etag-compare log/etag341
 </command>
 </client>
 
@@ -47,16 +49,8 @@ http://%HOSTIP:%HTTPPORT/1416
 <strip>
 ^User-Agent:.*
 </strip>
-<protocol>
-GET /1416 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-</protocol>
-
-# 56 = CURLE_RECV_ERROR
 <errorcode>
-56
+26
 </errorcode>
 </verify>
 
diff --git a/tests/data/test1298 b/tests/data/test342
similarity index 69%
copy from tests/data/test1298
copy to tests/data/test342
index 061a4e1e0..95297ba50 100644
--- a/tests/data/test1298
+++ b/tests/data/test342
@@ -3,7 +3,6 @@
 <keywords>
 HTTP
 HTTP GET
---request-target
 </keywords>
 </info>
 
@@ -11,7 +10,7 @@ HTTP GET
 # Server-side
 <reply>
 <data>
-HTTP/1.1 200 OK
+HTTP/1.1 304 OK
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
 Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
@@ -31,11 +30,14 @@ Funny-head: yesyes
 <server>
 http
 </server>
- <name>
-HTTP GET special path with --request-target
- </name>
- <command>
---request-target "XXX" "http://%HOSTIP:%HTTPPORT/"; -H "Testno: 1298"
+<name>
+Check if --etag-compare set correct etag in header
+</name>
+<file name="log/etag342">
+21025-dc7-39462498
+</file>
+<command>
+http://%HOSTIP:%HTTPPORT/342 --etag-compare log/etag342
 </command>
 </client>
 
@@ -46,10 +48,10 @@ HTTP GET special path with --request-target
 ^User-Agent:.*
 </strip>
 <protocol>
-GET XXX HTTP/1.1
+GET /342 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
-Testno: 1298
+If-None-Match: "21025-dc7-39462498"
 
 </protocol>
 </verify>
diff --git a/tests/data/test1298 b/tests/data/test343
similarity index 62%
copy from tests/data/test1298
copy to tests/data/test343
index 061a4e1e0..e55a181d8 100644
--- a/tests/data/test1298
+++ b/tests/data/test343
@@ -3,7 +3,6 @@
 <keywords>
 HTTP
 HTTP GET
---request-target
 </keywords>
 </info>
 
@@ -15,7 +14,7 @@ HTTP/1.1 200 OK
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
 Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
-ETag: "21025-dc7-39462498"
+ETag: "21025-dc7-11111"
 Accept-Ranges: bytes
 Content-Length: 0
 Connection: close
@@ -31,11 +30,14 @@ Funny-head: yesyes
 <server>
 http
 </server>
- <name>
-HTTP GET special path with --request-target
- </name>
- <command>
---request-target "XXX" "http://%HOSTIP:%HTTPPORT/"; -H "Testno: 1298"
+<name>
+Both --etag-compare and --etag-save to save new Etag
+</name>
+<file name="log/etag343">
+21025-dc7-39462498
+</file>
+<command>
+http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 --etag-save log/out343
 </command>
 </client>
 
@@ -46,11 +48,14 @@ HTTP GET special path with --request-target
 ^User-Agent:.*
 </strip>
 <protocol>
-GET XXX HTTP/1.1
+GET /343 HTTP/1.1
 Host: %HOSTIP:%HTTPPORT
 Accept: */*
-Testno: 1298
+If-None-Match: "21025-dc7-39462498"
 
 </protocol>
+<file name="log/out343">
+21025-dc7-11111
+</file>
 </verify>
 </testcase>
diff --git a/tests/data/test199 b/tests/data/test490
similarity index 65%
copy from tests/data/test199
copy to tests/data/test490
index 72675b535..a3383a9d1 100644
--- a/tests/data/test199
+++ b/tests/data/test490
@@ -2,10 +2,10 @@
 <info>
 <keywords>
 HTTP
-HTTP GET
-globbing
+HTTP PUT
 </keywords>
 </info>
+
 #
 # Server-side
 <reply>
@@ -32,11 +32,14 @@ Funny-head: yesyes
 http
 </server>
  <name>
-HTTP with -d, -G and {}
+Two globbed HTTP PUTs
  </name>
  <command>
--d "foo=moo&moo=poo" "http://%HOSTIP:%HTTPPORT/{199,199}"; -G
+http://%HOSTIP:%HTTPPORT/490 -T '{log/in490,log/in490}'
 </command>
+<file name="log/in490">
+surprise!
+</file>
 </client>
 
 #
@@ -46,14 +49,20 @@ HTTP with -d, -G and {}
 ^User-Agent:.*
 </strip>
 <protocol>
-GET /199?foo=moo&moo=poo HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
+PUT /490 HTTP/1.1
+Host: 127.0.0.1:8990
 Accept: */*
+Content-Length: 10
+Expect: 100-continue
 
-GET /199?foo=moo&moo=poo HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
+surprise!
+PUT /490 HTTP/1.1
+Host: 127.0.0.1:8990
 Accept: */*
+Content-Length: 10
+Expect: 100-continue
 
+surprise!
 </protocol>
 </verify>
 </testcase>
diff --git a/tests/data/test293 b/tests/data/test491
similarity index 69%
copy from tests/data/test293
copy to tests/data/test491
index d75fc9a3c..b49c06ce7 100644
--- a/tests/data/test293
+++ b/tests/data/test491
@@ -2,16 +2,14 @@
 <info>
 <keywords>
 HTTP
-HTTP GET
---max-filesize
-FAILURE
+HTTP PUT
 </keywords>
 </info>
 
 #
 # Server-side
 <reply>
-<data nocheck="yes">
+<data>
 HTTP/1.1 200 OK
 Date: Thu, 09 Nov 2010 14:49:00 GMT
 Server: test-server/fake
@@ -34,27 +32,33 @@ Funny-head: yesyes
 http
 </server>
  <name>
-HTTP GET with maximum filesize exceeded
+Two globbed HTTP PUTs, the second upload file is missing
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/293 --max-filesize 2
+http://%HOSTIP:%HTTPPORT/491 -T '{log/in491,log/bad491}'
 </command>
+<file name="log/in491">
+surprise!
+</file>
 </client>
 
 #
 # Verify data after the test has been "shot"
 <verify>
-<errorcode>
-63
-</errorcode>
 <strip>
 ^User-Agent:.*
 </strip>
 <protocol>
-GET /293 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
+PUT /491 HTTP/1.1
+Host: 127.0.0.1:8990
 Accept: */*
+Content-Length: 10
+Expect: 100-continue
 
+surprise!
 </protocol>
+<errorcode>
+26
+</errorcode>
 </verify>
 </testcase>
diff --git a/tests/data/test492 b/tests/data/test492
new file mode 100644
index 000000000..12edd8bc0
--- /dev/null
+++ b/tests/data/test492
@@ -0,0 +1,89 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP PUT
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+Two globbed HTTP PUTs to two globbed URLs
+ </name>
+ <command>
+'http://%HOSTIP:%HTTPPORT/{one,two}/' -T '{log/first492,log/second492}' -H 
"Testno: 492"
+</command>
+<file name="log/first492">
+first 492 contents
+</file>
+<file1 name="log/second492">
+second 492 contents
+</file1>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+PUT /one/first492 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Testno: 492
+Content-Length: 19
+Expect: 100-continue
+
+first 492 contents
+PUT /two/first492 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Testno: 492
+Content-Length: 19
+Expect: 100-continue
+
+first 492 contents
+PUT /one/second492 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Testno: 492
+Content-Length: 20
+Expect: 100-continue
+
+second 492 contents
+PUT /two/second492 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Testno: 492
+Content-Length: 20
+Expect: 100-continue
+
+second 492 contents
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/disable-scan.pl b/tests/disable-scan.pl
index e57fdc697..45373ca40 100755
--- a/tests/disable-scan.pl
+++ b/tests/disable-scan.pl
@@ -29,9 +29,12 @@ use warnings;
 my %disable;
 # the DISABLE options that are used in C files
 my %file;
+# the DISABLE options that are documented
+my %docs;
 
 # we may get the dir root pointed out
 my $root=$ARGV[0] || ".";
+my $DOCS="CURL-DISABLE.md";
 
 sub scan_configure {
     open S, "<$root/configure.ac";
@@ -73,8 +76,22 @@ sub scan_sources {
     scan_dir("$root/lib/vauth");
 }
 
+sub scan_docs {
+    open F, "<$root/docs/$DOCS";
+    my $line = 0;
+    while(<F>) {
+        $line++;
+        if(/^## (CURL_DISABLE_[A-Z_]+)/g) {
+            my ($sym)=($1);
+            $docs{$sym} = $line;
+        }
+    }
+    close F;
+}
+
 scan_configure();
 scan_sources();
+scan_docs();
 
 
 my $error = 0;
@@ -84,6 +101,10 @@ for my $s (sort keys %disable) {
         printf "Present in configure.ac, not used by code: %s\n", $s;
         $error++;
     }
+    if(!$docs{$s}) {
+        printf "Present in configure.ac, not documented in $DOCS: %s\n", $s;
+        $error++;
+    }
 }
 
 # Check the code symbols for use in configure
@@ -92,6 +113,22 @@ for my $s (sort keys %file) {
         printf "Not set by configure: %s (%s)\n", $s, $file{$s};
         $error++;
     }
+    if(!$docs{$s}) {
+        printf "Used in code, not documented in $DOCS: %s\n", $s;
+        $error++;
+    }
+}
+
+# Check the documented symbols
+for my $s (sort keys %docs) {
+    if(!$disable{$s}) {
+        printf "Documented but not in configure: %s\n", $s;
+        $error++;
+    }
+    if(!$file{$s}) {
+        printf "Documented, but not used by code: %s\n", $s;
+        $error++;
+    }
 }
 
 exit $error;
diff --git a/tests/error-codes.pl b/tests/error-codes.pl
new file mode 100644
index 000000000..0d555f667
--- /dev/null
+++ b/tests/error-codes.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2010-2019, Daniel Stenberg, <address@hidden>, 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.
+#
+###########################################################################
+#
+#
+
+use strict;
+use warnings;
+
+# we may get the dir root pointed out
+my $root=$ARGV[0] || ".";
+
+my %error; # from the include file
+my %docs; # from libcurl-errors.3
+
+sub getdocserrors {
+    open(F, "<$root/docs/libcurl/libcurl-errors.3");
+    while(<F>) {
+        if($_ =~ /^.IP \"(CURL[EM]_[^ \t\"]*)/) {
+            my ($symbol) = ($1);
+            if($symbol =~ /OBSOLETE/) {
+                ;
+            }
+            else {
+                $docs{$symbol}=1;
+            }
+        }
+    }
+    close(F);
+}
+
+sub getincludeerrors {
+    open(F, "<$root/docs/libcurl/symbols-in-versions");
+    while(<F>) {
+        if($_ =~ /^(CURL[EM]_[^ \t]*)[ \t]*([0-9.]+)[ \t]*(.*)/) {
+            my ($symbol, $added, $rest) = ($1,$2,$3);
+            if($rest =~ /^([0-9.]+)/) {
+                # removed!
+            }
+            else {
+                $error{$symbol}=$added;
+            }
+        }
+    }
+    close(F);
+}
+
+getincludeerrors();
+getdocserrors();
+
+for(sort keys %error) {
+    if($error{$_} && !$docs{$_}) {
+        print "$_ is not in libcurl-errors.3\n";
+    }
+}
+
+for(sort keys %docs) {
+    if($docs{$_} && !$error{$_}) {
+        print "$_ is not in symbols-in-versions\n";
+    }
+}
diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl
index d401be24c..ac02722e9 100755
--- a/tests/ftpserver.pl
+++ b/tests/ftpserver.pl
@@ -68,6 +68,10 @@ use serverhelp qw(
     datasockf_logfilename
     );
 
+use sshhelp qw(
+    exe_ext
+    );
+
 #**********************************************************************
 # global vars...
 #
@@ -411,7 +415,7 @@ sub sysread_or_die {
 }
 
 sub startsf {
-    my $mainsockfcmd = "./server/sockfilt " .
+    my $mainsockfcmd = "./server/sockfilt".exe_ext('SRV')." " .
         "--ipv$ipvnum --port $port " .
         "--pidfile \"$mainsockf_pidfile\" " .
         "--logfile \"$mainsockf_logfile\"";
@@ -2401,7 +2405,7 @@ sub PASV_ftp {
     logmsg "DATA sockfilt for passive data channel starting...\n";
 
     # We fire up a new sockfilt to do the data transfer for us.
-    my $datasockfcmd = "./server/sockfilt " .
+    my $datasockfcmd = "./server/sockfilt".exe_ext('SRV')." " .
         "--ipv$ipvnum $bindonly --port 0 " .
         "--pidfile \"$datasockf_pidfile\" " .
         "--logfile \"$datasockf_logfile\"";
@@ -2620,7 +2624,7 @@ sub PORT_ftp {
     logmsg "DATA sockfilt for active data channel starting...\n";
 
     # We fire up a new sockfilt to do the data transfer for us.
-    my $datasockfcmd = "./server/sockfilt " .
+    my $datasockfcmd = "./server/sockfilt".exe_ext('SRV')." " .
         "--ipv$ipvnum --connect $port --addr \"$addr\" " .
         "--pidfile \"$datasockf_pidfile\" " .
         "--logfile \"$datasockf_logfile\"";
diff --git a/tests/httpserver.pl b/tests/httpserver.pl
index 7f6c86a8a..8b789a9b9 100755
--- a/tests/httpserver.pl
+++ b/tests/httpserver.pl
@@ -34,6 +34,10 @@ use serverhelp qw(
     server_logfilename
     );
 
+use sshhelp qw(
+    exe_ext
+    );
+
 my $verbose = 0;     # set to 1 for debugging
 my $port = 8990;     # just a default
 my $unix_socket;     # location to place a listening Unix socket
@@ -133,7 +137,7 @@ if($ipvnum eq 'unix') {
 $flags .= "--srcdir \"$srcdir\"";
 
 if($verbose) {
-    print STDERR "RUN: server/sws $flags\n";
+    print STDERR "RUN: server/sws".exe_ext('SRV')." $flags\n";
 }
 
-exec("server/sws $flags");
+exec("server/sws".exe_ext('SRV')." $flags");
diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt
index e1ba60844..1dcebb1a2 100644
--- a/tests/libtest/CMakeLists.txt
+++ b/tests/libtest/CMakeLists.txt
@@ -1,9 +1,5 @@
 set(TARGET_LABEL_PREFIX "Test ")
 
-if(MSVC)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127")
-endif()
-
 function(setup_test TEST_NAME)          # ARGN are the files in the test
   add_executable( ${TEST_NAME} ${ARGN} )
   string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME)
@@ -11,7 +7,7 @@ function(setup_test TEST_NAME)          # ARGN are the files 
in the test
   include_directories(
     ${GNURL_SOURCE_DIR}/lib          # To be able to reach "curl_setup_once.h"
     ${GNURL_BINARY_DIR}/lib          # To be able to reach "curl_config.h"
-    ${GNURL_BINARY_DIR}/include      # To be able to reach "curl/curl.h"
+    ${GNURL_BINARY_DIR}/include      # To be able to reach "gnurl/curl.h"
     ${GNURL_SOURCE_DIR}/tests/libtest # To be able to build generated tests
     )
   if(USE_ARES)
diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am
index 3d113c7ed..0b0c67775 100644
--- a/tests/libtest/Makefile.am
+++ b/tests/libtest/Makefile.am
@@ -130,7 +130,7 @@ CS_1 =
 CS_ = $(CS_0)
 
 checksrc:
-       $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+       $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.[ch]
 
 if CURLDEBUG
 # for debug builds, we scan the sources on all regular make invokes
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 9ba72d7de..374a66747 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -31,7 +31,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect     
           \
  lib1534 lib1535 lib1536 lib1537 lib1538 \
  lib1540 lib1541 \
  lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
- lib1558 lib1559 lib1560 \
+ lib1558 lib1559 lib1560 lib1564 lib1565 \
  lib1591 lib1592 lib1593 lib1594 lib1596 \
  lib1900 lib1905 lib1906 lib1907 \
  lib2033
@@ -536,6 +536,14 @@ lib1559_LDADD = $(TESTUTIL_LIBS)
 lib1560_SOURCES = lib1560.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
 lib1560_LDADD = $(TESTUTIL_LIBS)
 
+lib1564_SOURCES = lib1564.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1564_LDADD = $(TESTUTIL_LIBS)
+lib1564_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib1565_SOURCES = lib1565.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1565_LDADD = $(TESTUTIL_LIBS)
+lib1565_CPPFLAGS = $(AM_CPPFLAGS)
+
 lib1591_SOURCES = lib1591.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
 lib1591_LDADD = $(TESTUTIL_LIBS)
 lib1591_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1591
diff --git a/tests/libtest/lib1557.c b/tests/libtest/lib1557.c
index bd0f20a85..d7132ad04 100644
--- a/tests/libtest/lib1557.c
+++ b/tests/libtest/lib1557.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -49,13 +49,13 @@ int test(char *URL)
   multi_perform(curlm, &running_handles);
 
   multi_remove_handle(curlm, curl2);
-  curl_easy_cleanup(curl2);
 
   /* If curl2 is still in the connect-pending list, this will crash */
   multi_remove_handle(curlm, curl1);
-  curl_easy_cleanup(curl1);
 
 test_cleanup:
+  curl_easy_cleanup(curl1);
+  curl_easy_cleanup(curl2);
   curl_multi_cleanup(curlm);
   curl_global_cleanup();
   return res;
diff --git a/tests/libtest/lib1559.c b/tests/libtest/lib1559.c
index 2aa3615e0..e1b417548 100644
--- a/tests/libtest/lib1559.c
+++ b/tests/libtest/lib1559.c
@@ -34,6 +34,9 @@ int test(char *URL)
   CURLU *u;
   (void)URL;
 
+  if(!longurl)
+    return 1;
+
   memset(longurl, 'a', EXCESSIVE);
   longurl[EXCESSIVE-1] = 0;
 
@@ -62,15 +65,8 @@ int test(char *URL)
     curl_url_cleanup(u);
   }
 
-  free(longurl);
-
-  curl_easy_cleanup(curl);
-  curl_global_cleanup();
-
-  return 0;
-
 test_cleanup:
-
+  free(longurl);
   curl_easy_cleanup(curl);
   curl_global_cleanup();
 
diff --git a/tests/libtest/lib1564.c b/tests/libtest/lib1564.c
new file mode 100644
index 000000000..225c8c6d7
--- /dev/null
+++ b/tests/libtest/lib1564.c
@@ -0,0 +1,142 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+#define WAKEUP_NUM 1234567
+
+int test(char *URL)
+{
+  CURLM *multi = NULL;
+  int numfds;
+  int i;
+  int res = 0;
+  struct timeval time_before_wait, time_after_wait;
+
+  (void)URL;
+
+  start_test_timing();
+
+  global_init(CURL_GLOBAL_ALL);
+
+  multi_init(multi);
+
+  /* no wakeup */
+
+  time_before_wait = tutil_tvnow();
+  multi_poll(multi, NULL, 0, 1000, &numfds);
+  time_after_wait = tutil_tvnow();
+
+  if(tutil_tvdiff(time_after_wait, time_before_wait) < 500) {
+    fprintf(stderr, "%s:%d curl_multi_poll returned too early\n",
+            __FILE__, __LINE__);
+    res = TEST_ERR_MAJOR_BAD;
+    goto test_cleanup;
+  }
+
+  abort_on_test_timeout();
+
+  /* try a single wakeup */
+
+  multi_wakeup(multi);
+
+  time_before_wait = tutil_tvnow();
+  multi_poll(multi, NULL, 0, 1000, &numfds);
+  time_after_wait = tutil_tvnow();
+
+  if(tutil_tvdiff(time_after_wait, time_before_wait) > 500) {
+    fprintf(stderr, "%s:%d curl_multi_poll returned too late\n",
+            __FILE__, __LINE__);
+    res = TEST_ERR_MAJOR_BAD;
+    goto test_cleanup;
+  }
+
+  abort_on_test_timeout();
+
+  /* previous wakeup should not wake up this */
+
+  time_before_wait = tutil_tvnow();
+  multi_poll(multi, NULL, 0, 1000, &numfds);
+  time_after_wait = tutil_tvnow();
+
+  if(tutil_tvdiff(time_after_wait, time_before_wait) < 500) {
+    fprintf(stderr, "%s:%d curl_multi_poll returned too early\n",
+            __FILE__, __LINE__);
+    res = TEST_ERR_MAJOR_BAD;
+    goto test_cleanup;
+  }
+
+  abort_on_test_timeout();
+
+  /* try lots of wakeup */
+
+  for(i = 0; i < WAKEUP_NUM; ++i)
+    multi_wakeup(multi);
+
+  time_before_wait = tutil_tvnow();
+  multi_poll(multi, NULL, 0, 1000, &numfds);
+  time_after_wait = tutil_tvnow();
+
+  if(tutil_tvdiff(time_after_wait, time_before_wait) > 500) {
+    fprintf(stderr, "%s:%d curl_multi_poll returned too late\n",
+            __FILE__, __LINE__);
+    res = TEST_ERR_MAJOR_BAD;
+    goto test_cleanup;
+  }
+
+  abort_on_test_timeout();
+
+#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32__) \
+    && !defined(__CYGWIN__)
+  /* Even lots of previous wakeups should not wake up this.
+
+     On Windows (particularly when using MinGW), the socketpair
+     used for curl_multi_wakeup() is really asynchronous,
+     meaning when it's called a lot, it can take some time
+     before all of the data can be read. Sometimes it can wake
+     up more than one curl_multi_poll() call. */
+
+  time_before_wait = tutil_tvnow();
+  multi_poll(multi, NULL, 0, 1000, &numfds);
+  time_after_wait = tutil_tvnow();
+
+  if(tutil_tvdiff(time_after_wait, time_before_wait) < 500) {
+    fprintf(stderr, "%s:%d curl_multi_poll returned too early\n",
+            __FILE__, __LINE__);
+    res = TEST_ERR_MAJOR_BAD;
+    goto test_cleanup;
+  }
+
+  abort_on_test_timeout();
+#endif
+
+test_cleanup:
+
+  curl_multi_cleanup(multi);
+  curl_global_cleanup();
+
+  return res;
+}
diff --git a/tests/libtest/lib1565.c b/tests/libtest/lib1565.c
new file mode 100644
index 000000000..b2fa40aaa
--- /dev/null
+++ b/tests/libtest/lib1565.c
@@ -0,0 +1,204 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#include <unistd.h>
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+#define CONN_NUM 3
+#define TIME_BETWEEN_START_SECS 2
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+static CURL *pending_handles[CONN_NUM];
+static int pending_num = 0;
+static int test_failure = 0;
+
+static CURLM *multi = NULL;
+static const char *url;
+
+static void *run_thread(void *ptr)
+{
+  CURL *easy = NULL;
+  int res = 0;
+  int i;
+
+  (void)ptr;
+
+  for(i = 0; i < CONN_NUM; i++) {
+    sleep(TIME_BETWEEN_START_SECS);
+
+    easy_init(easy);
+
+    easy_setopt(easy, CURLOPT_URL, url);
+    easy_setopt(easy, CURLOPT_VERBOSE, 0L);
+
+    pthread_mutex_lock(&lock);
+
+    if(test_failure) {
+      pthread_mutex_unlock(&lock);
+      goto test_cleanup;
+    }
+
+    pending_handles[pending_num] = easy;
+    pending_num++;
+    easy = NULL;
+
+    pthread_mutex_unlock(&lock);
+
+    multi_wakeup(multi);
+  }
+
+test_cleanup:
+
+  curl_easy_cleanup(easy);
+
+  pthread_mutex_lock(&lock);
+
+  if(!test_failure)
+    test_failure = res;
+
+  pthread_mutex_unlock(&lock);
+
+  return NULL;
+}
+
+int test(char *URL)
+{
+  int still_running;
+  int num;
+  int i;
+  int res = 0;
+  CURL *started_handles[CONN_NUM];
+  int started_num = 0;
+  int finished_num = 0;
+  pthread_t tid = 0;
+  struct CURLMsg *message;
+
+  start_test_timing();
+
+  global_init(CURL_GLOBAL_ALL);
+
+  multi_init(multi);
+
+  url = URL;
+
+  res = pthread_create(&tid, NULL, run_thread, NULL);
+  if(0 != res) {
+    fprintf(stderr, "%s:%d Couldn't create thread, errno %d\n",
+            __FILE__, __LINE__, res);
+    goto test_cleanup;
+  }
+
+  while(1) {
+    multi_perform(multi, &still_running);
+
+    abort_on_test_timeout();
+
+    while((message = curl_multi_info_read(multi, &num)) != NULL) {
+      if(message->msg == CURLMSG_DONE) {
+        res = message->data.result;
+        if(res)
+          goto test_cleanup;
+        multi_remove_handle(multi, message->easy_handle);
+        finished_num++;
+      }
+      else {
+        fprintf(stderr, "%s:%d Got an unexpected message from curl: %i\n",
+              __FILE__, __LINE__, (int)message->msg);
+        res = TEST_ERR_MAJOR_BAD;
+        goto test_cleanup;
+      }
+
+      abort_on_test_timeout();
+    }
+
+    if(CONN_NUM == finished_num)
+      break;
+
+    multi_poll(multi, NULL, 0, TEST_HANG_TIMEOUT, &num);
+
+    abort_on_test_timeout();
+
+    pthread_mutex_lock(&lock);
+
+    while(pending_num > 0) {
+      res_multi_add_handle(multi, pending_handles[pending_num - 1]);
+      if(res) {
+        pthread_mutex_unlock(&lock);
+        goto test_cleanup;
+      }
+
+      started_handles[started_num] = pending_handles[pending_num - 1];
+      started_num++;
+      pending_num--;
+    }
+
+    pthread_mutex_unlock(&lock);
+
+    abort_on_test_timeout();
+  }
+
+  if(CONN_NUM != started_num) {
+    fprintf(stderr, "%s:%d Not all connections started: %d of %d\n",
+            __FILE__, __LINE__, started_num, CONN_NUM);
+    goto test_cleanup;
+  }
+
+  if(CONN_NUM != finished_num) {
+    fprintf(stderr, "%s:%d Not all connections finished: %d of %d\n",
+            __FILE__, __LINE__, started_num, CONN_NUM);
+    goto test_cleanup;
+  }
+
+test_cleanup:
+
+  pthread_mutex_lock(&lock);
+  if(!test_failure)
+    test_failure = res;
+  pthread_mutex_unlock(&lock);
+
+  if(0 != tid)
+    pthread_join(tid, NULL);
+
+  curl_multi_cleanup(multi);
+  for(i = 0; i < pending_num; i++)
+    curl_easy_cleanup(pending_handles[i]);
+  for(i = 0; i < started_num; i++)
+    curl_easy_cleanup(started_handles[i]);
+  curl_global_cleanup();
+
+  return test_failure;
+}
+
+#else /* without pthread, this test doesn't work */
+int test(char *URL)
+{
+  (void)URL;
+  return 0;
+}
+#endif
diff --git a/tests/libtest/lib1591.c b/tests/libtest/lib1591.c
index f0c6b4cb7..cc1c5b228 100644
--- a/tests/libtest/lib1591.c
+++ b/tests/libtest/lib1591.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -50,12 +50,25 @@ static size_t read_callback(void *ptr, size_t size, size_t 
nmemb, void *stream)
   return amount;
 }
 
+/*
+ * carefully not leak memory on OOM
+ */
 static int trailers_callback(struct curl_slist **list, void *userdata)
 {
+  struct curl_slist *nlist = NULL;
+  struct curl_slist *nlist2 = NULL;
   (void)userdata;
-  *list = curl_slist_append(*list, "my-super-awesome-trailer: trail1");
-  *list = curl_slist_append(*list, "my-other-awesome-trailer: trail2");
-  return CURL_TRAILERFUNC_OK;
+  nlist = curl_slist_append(*list, "my-super-awesome-trailer: trail1");
+  if(nlist)
+    nlist2 = curl_slist_append(nlist, "my-other-awesome-trailer: trail2");
+  if(nlist2) {
+    *list = nlist2;
+    return CURL_TRAILERFUNC_OK;
+  }
+  else {
+    curl_slist_free_all(nlist);
+    return CURL_TRAILERFUNC_ABORT;
+  }
 }
 
 int test(char *URL)
diff --git a/tests/libtest/test.h b/tests/libtest/test.h
index 90735d272..ff143c985 100644
--- a/tests/libtest/test.h
+++ b/tests/libtest/test.h
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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,7 +20,7 @@
  *
  ***************************************************************************/
 
-/* !checksrc! disable ASSIGNWITHINCONDITION all */
+/* !checksrc! disable ASSIGNWITHINCONDITION 14 */
 
 /* Now include the curl_setup.h file from libcurl's private libdir (the source
    version, but that might include "curl_config.h" from the build dir so we
@@ -131,7 +131,7 @@ extern int unitfail;
     fprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \
     res = TEST_ERR_EASY_INIT;                                     \
   }                                                               \
-} WHILE_FALSE
+} while(0)
 
 #define res_easy_init(A) \
   exe_easy_init((A), (__FILE__), (__LINE__))
@@ -140,7 +140,7 @@ extern int unitfail;
   exe_easy_init((A), (Y), (Z));   \
   if(res)                         \
     goto test_cleanup;            \
-} WHILE_FALSE
+} while(0)
 
 #define easy_init(A) \
   chk_easy_init((A), (__FILE__), (__LINE__))
@@ -152,7 +152,7 @@ extern int unitfail;
     fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \
     res = TEST_ERR_MULTI_INIT;                                     \
   }                                                                \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_init(A) \
   exe_multi_init((A), (__FILE__), (__LINE__))
@@ -161,7 +161,7 @@ extern int unitfail;
   exe_multi_init((A), (Y), (Z));   \
   if(res)                          \
     goto test_cleanup;             \
-} WHILE_FALSE
+} while(0)
 
 #define multi_init(A) \
   chk_multi_init((A), (__FILE__), (__LINE__))
@@ -176,7 +176,7 @@ extern int unitfail;
             (Y), (Z), (int)ec, curl_easy_strerror(ec));    \
     res = (int)ec;                                         \
   }                                                        \
-} WHILE_FALSE
+} while(0)
 
 #define res_easy_setopt(A, B, C) \
   exe_easy_setopt((A), (B), (C), (__FILE__), (__LINE__))
@@ -185,7 +185,7 @@ extern int unitfail;
   exe_easy_setopt((A), (B), (C), (Y), (Z)); \
   if(res)                                   \
     goto test_cleanup;                      \
-} WHILE_FALSE
+} while(0)
 
 #define easy_setopt(A, B, C) \
   chk_easy_setopt((A), (B), (C), (__FILE__), (__LINE__))
@@ -200,7 +200,7 @@ extern int unitfail;
             (Y), (Z), (int)ec, curl_multi_strerror(ec));    \
     res = (int)ec;                                          \
   }                                                         \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_setopt(A,B,C) \
   exe_multi_setopt((A), (B), (C), (__FILE__), (__LINE__))
@@ -209,7 +209,7 @@ extern int unitfail;
   exe_multi_setopt((A), (B), (C), (Y), (Z)); \
   if(res)                                    \
     goto test_cleanup;                       \
-} WHILE_FALSE
+} while(0)
 
 #define multi_setopt(A,B,C) \
   chk_multi_setopt((A), (B), (C), (__FILE__), (__LINE__))
@@ -224,7 +224,7 @@ extern int unitfail;
             (Y), (Z), (int)ec, curl_multi_strerror(ec));     \
     res = (int)ec;                                           \
   }                                                          \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_add_handle(A, B) \
   exe_multi_add_handle((A), (B), (__FILE__), (__LINE__))
@@ -233,7 +233,7 @@ extern int unitfail;
   exe_multi_add_handle((A), (B), (Y), (Z));   \
   if(res)                                     \
     goto test_cleanup;                        \
-} WHILE_FALSE
+} while(0)
 
 #define multi_add_handle(A, B) \
   chk_multi_add_handle((A), (B), (__FILE__), (__LINE__))
@@ -248,7 +248,7 @@ extern int unitfail;
             (Y), (Z), (int)ec, curl_multi_strerror(ec));        \
     res = (int)ec;                                              \
   }                                                             \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_remove_handle(A, B) \
   exe_multi_remove_handle((A), (B), (__FILE__), (__LINE__))
@@ -257,7 +257,7 @@ extern int unitfail;
   exe_multi_remove_handle((A), (B), (Y), (Z));   \
   if(res)                                        \
     goto test_cleanup;                           \
-} WHILE_FALSE
+} while(0)
 
 
 #define multi_remove_handle(A, B) \
@@ -279,7 +279,7 @@ extern int unitfail;
             (Y), (Z), (int)*((B)));                              \
     res = TEST_ERR_NUM_HANDLES;                                  \
   }                                                              \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_perform(A, B) \
   exe_multi_perform((A), (B), (__FILE__), (__LINE__))
@@ -288,7 +288,7 @@ extern int unitfail;
   exe_multi_perform((A), (B), (Y), (Z));   \
   if(res)                                  \
     goto test_cleanup;                     \
-} WHILE_FALSE
+} while(0)
 
 #define multi_perform(A,B) \
   chk_multi_perform((A), (B), (__FILE__), (__LINE__))
@@ -309,7 +309,7 @@ extern int unitfail;
             (Y), (Z), (int)*((E)));                                  \
     res = TEST_ERR_NUM_HANDLES;                                      \
   }                                                                  \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_fdset(A, B, C, D, E) \
   exe_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
@@ -318,7 +318,7 @@ extern int unitfail;
     exe_multi_fdset((A), (B), (C), (D), (E), (Y), (Z)); \
     if(res)                                             \
       goto test_cleanup;                                \
-  } WHILE_FALSE
+  } while(0)
 
 #define multi_fdset(A, B, C, D, E) \
   chk_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
@@ -339,7 +339,7 @@ extern int unitfail;
             (Y), (Z), (long)*((B)));                         \
     res = TEST_ERR_BAD_TIMEOUT;                              \
   }                                                          \
-} WHILE_FALSE
+} while(0)
 
 #define res_multi_timeout(A, B) \
   exe_multi_timeout((A), (B), (__FILE__), (__LINE__))
@@ -348,13 +348,67 @@ extern int unitfail;
     exe_multi_timeout((A), (B), (Y), (Z)); \
     if(res)                                \
       goto test_cleanup;                   \
-  } WHILE_FALSE
+  } while(0)
 
 #define multi_timeout(A, B) \
   chk_multi_timeout((A), (B), (__FILE__), (__LINE__))
 
 /* ---------------------------------------------------------------- */
 
+#define exe_multi_poll(A,B,C,D,E,Y,Z) do {                          \
+  CURLMcode ec;                                                     \
+  if((ec = curl_multi_poll((A), (B), (C), (D), (E))) != CURLM_OK) { \
+    fprintf(stderr, "%s:%d curl_multi_poll() failed, "              \
+            "with code %d (%s)\n",                                  \
+            (Y), (Z), (int)ec, curl_multi_strerror(ec));            \
+    res = (int)ec;                                                  \
+  }                                                                 \
+  else if(*((E)) < 0) {                                             \
+    fprintf(stderr, "%s:%d curl_multi_poll() succeeded, "           \
+            "but returned invalid numfds value (%d)\n",             \
+            (Y), (Z), (int)*((E)));                                 \
+    res = TEST_ERR_NUM_HANDLES;                                     \
+  }                                                                 \
+} while(0)
+
+#define res_multi_poll(A, B, C, D, E) \
+  exe_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
+
+#define chk_multi_poll(A, B, C, D, E, Y, Z) do {     \
+  exe_multi_poll((A), (B), (C), (D), (E), (Y), (Z)); \
+  if(res)                                            \
+    goto test_cleanup;                               \
+} while(0)
+
+#define multi_poll(A, B, C, D, E) \
+  chk_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
+
+/* ---------------------------------------------------------------- */
+
+#define exe_multi_wakeup(A,Y,Z) do {                     \
+  CURLMcode ec;                                          \
+  if((ec = curl_multi_wakeup((A))) != CURLM_OK) {        \
+    fprintf(stderr, "%s:%d curl_multi_wakeup() failed, " \
+            "with code %d (%s)\n",                       \
+            (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
+    res = (int)ec;                                       \
+  }                                                      \
+} while(0)
+
+#define res_multi_wakeup(A) \
+  exe_multi_wakeup((A), (__FILE__), (__LINE__))
+
+#define chk_multi_wakeup(A, Y, Z) do { \
+  exe_multi_wakeup((A), (Y), (Z));     \
+  if(res)                              \
+    goto test_cleanup;                 \
+} while(0)
+
+#define multi_wakeup(A) \
+  chk_multi_wakeup((A), (__FILE__), (__LINE__))
+
+/* ---------------------------------------------------------------- */
+
 #define exe_select_test(A, B, C, D, E, Y, Z) do {               \
     int ec;                                                     \
     if(select_wrapper((A), (B), (C), (D), (E)) == -1) {         \
@@ -364,7 +418,7 @@ extern int unitfail;
               (Y), (Z), ec, strerror(ec));                      \
       res = TEST_ERR_SELECT;                                    \
     }                                                           \
-  } WHILE_FALSE
+  } while(0)
 
 #define res_select_test(A, B, C, D, E) \
   exe_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
@@ -373,7 +427,7 @@ extern int unitfail;
     exe_select_test((A), (B), (C), (D), (E), (Y), (Z)); \
     if(res)                                             \
       goto test_cleanup;                                \
-  } WHILE_FALSE
+  } while(0)
 
 #define select_test(A, B, C, D, E) \
   chk_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
@@ -382,7 +436,7 @@ extern int unitfail;
 
 #define start_test_timing() do { \
   tv_test_start = tutil_tvnow(); \
-} WHILE_FALSE
+} while(0)
 
 #define exe_test_timedout(Y,Z) do {                                    \
   if(tutil_tvdiff(tutil_tvnow(), tv_test_start) > TEST_HANG_TIMEOUT) { \
@@ -390,7 +444,7 @@ extern int unitfail;
                     "that it would have run forever.\n", (Y), (Z));    \
     res = TEST_ERR_RUNS_FOREVER;                                       \
   }                                                                    \
-} WHILE_FALSE
+} while(0)
 
 #define res_test_timedout() \
   exe_test_timedout((__FILE__), (__LINE__))
@@ -399,7 +453,7 @@ extern int unitfail;
     exe_test_timedout(Y, Z);         \
     if(res)                          \
       goto test_cleanup;             \
-  } WHILE_FALSE
+  } while(0)
 
 #define abort_on_test_timeout() \
   chk_test_timedout((__FILE__), (__LINE__))
@@ -414,7 +468,7 @@ extern int unitfail;
             (Y), (Z), (int)ec, curl_easy_strerror(ec)); \
     res = (int)ec;                                      \
   }                                                     \
-} WHILE_FALSE
+} while(0)
 
 #define res_global_init(A) \
   exe_global_init((A), (__FILE__), (__LINE__))
@@ -423,7 +477,7 @@ extern int unitfail;
     exe_global_init((A), (Y), (Z));   \
     if(res)                           \
       return res;                     \
-  } WHILE_FALSE
+  } while(0)
 
 /* global_init() is different than other macros. In case of
    failure it 'return's instead of going to 'test_cleanup'. */
diff --git a/tests/runtests.1 b/tests/runtests.1
index 18ddce483..fab635233 100644
--- a/tests/runtests.1
+++ b/tests/runtests.1
@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <address@hidden>, et al.
+.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <address@hidden>, 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 @@ detected. Useful for debugging.
 .IP "-l"
 Lists all test case names.
 .IP "-n"
-Disable the check for and use of valgrind.
+Disable the check for and the use of valgrind.
 .IP "-p"
 Prints out all files in "log/" to stdout when a test case fails. Very
 practical when used in the automated and distributed tests since then the
@@ -82,8 +82,20 @@ Run the tests in a scrambled, or randomized, order instead 
of sequentially.
 Display run time statistics. (Requires Perl Time::HiRes module)
 .IP "-rf"
 Display full run time statistics. (Requires Perl Time::HiRes module)
+.IP "--repeat=[num]"
+This will repeat the given set of test numbers this many times. If no test
+numbers are given, it will repeat ALL tests this many times. It iteratively
+adds the new sequence at the end of the initially given one.
+
+If \fB-R\fP is also used, the scrambling is done after the repeats have
+extended the test sequence.
 .IP "-s"
 Shorter output. Speaks less than default.
+.IP "--shallow=[num](,seed)"
+Used together with \fB-t\fP. This limits the number of tests to fail in
+torture mode to no more than 'num' per test case. If this reduces the amount,
+the given 'seed' will be used to randomly discard entries to fail until the
+amount is 'num'.
 .IP "-t[num]"
 Selects a \fBtorture\fP test for the given tests. This makes runtests.pl first
 run the tests once and count the number of memory allocations made. It then
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 5ab234c0d..e5c10858c 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -150,7 +150,7 @@ my $SMBSPORT;            # SMBS server port
 my $NEGTELNETPORT;       # TELNET server port with negotiation
 
 my $srcdir = $ENV{'srcdir'} || '.';
-my $CURL="../src/gnurl".exe_ext(); # what curl executable to run on the tests
+my $CURL="../src/gnurl".exe_ext('TOOL'); # what curl executable to run on the 
tests
 my $VCURL=$CURL;   # what curl binary to use to verify the servers with
                    # VCURL is handy to set to the system one when the one you
                    # just built hangs or crashes and thus prevent verification
@@ -186,6 +186,7 @@ my $server_response_maxtime=13;
 my $debug_build=0;          # built debug enabled (--enable-debug)
 my $has_memory_tracking=0;  # built with memory tracking (--enable-curldebug)
 my $libtool;
+my $repeat = 0;
 
 # name of the file that the memory debugging creates:
 my $memdump="$LOGDIR/memdump";
@@ -206,6 +207,9 @@ my $valgrind_tool;
 my $gdb = checktestcmd("gdb");
 my $httptlssrv = find_httptlssrv();
 
+my $uname_release = `uname -r`;
+my $is_wsl = $uname_release =~ /Microsoft$/;
+
 my $has_ssl;        # set if libcurl is built with SSL support
 my $has_largefile;  # set if libcurl is built with large file support
 my $has_idn;        # set if libcurl is built with IDN support
@@ -318,13 +322,20 @@ my %runcert;      # cert file currently in use by an ssl 
running server
 my $torture;
 my $tortnum;
 my $tortalloc;
+my $shallow;
+my $shallowseed;
 
 #######################################################################
 # logmsg is our general message logging subroutine.
 #
 sub logmsg {
     for(@_) {
-        print "$_";
+        my $line = $_;
+        if ($is_wsl) {
+            # use \r\n for WSL shell
+            $line =~ s/\r?\n$/\r\n/g;
+        }
+        print "$line";
     }
 }
 
@@ -590,13 +601,34 @@ sub torture {
         return 0;
     }
 
-    logmsg " $count functions to make fail\n";
+    my @ttests = (1 .. $count);
+    if($shallow && ($shallow < $count)) {
+        my $discard = scalar(@ttests) - $shallow;
+        my $percent = sprintf("%.2f%%", $shallow * 100 / scalar(@ttests));;
+        logmsg " $count functions found, but only fail $shallow ($percent)\n";
+        while($discard) {
+            my $rm;
+            do {
+                # find a test to discard
+                $rm = rand(scalar(@ttests));
+            } while(!$ttests[$rm]);
+            $ttests[$rm] = undef;
+            $discard--;
+        }
+    }
+    else {
+        logmsg " $count functions to make fail\n";
+    }
 
-    for ( 1 .. $count ) {
+    for (@ttests) {
         my $limit = $_;
         my $fail;
         my $dumped_core;
 
+        if(!defined($limit)) {
+            # --shallow can undefine them
+            next;
+        }
         if($tortalloc && ($tortalloc != $limit)) {
             next;
         }
@@ -2907,7 +2939,8 @@ sub checksystem {
         # client has IPv6 support
 
         # check if the HTTP server has it!
-        my @sws = `server/sws --version`;
+        my $cmd = "server/sws".exe_ext('SRV')." --version";
+        my @sws = `$cmd`;
         if($sws[0] =~ /IPv6/) {
             # HTTP server has IPv6 support!
             $http_ipv6 = 1;
@@ -2915,7 +2948,8 @@ sub checksystem {
         }
 
         # check if the FTP server has it!
-        @sws = `server/sockfilt --version`;
+        $cmd = "server/sockfilt".exe_ext('SRV')." --version";
+        @sws = `$cmd`;
         if($sws[0] =~ /IPv6/) {
             # FTP server has IPv6 support!
             $ftp_ipv6 = 1;
@@ -2924,7 +2958,8 @@ sub checksystem {
 
     if($has_unix) {
         # client has Unix sockets support, check whether the HTTP server has it
-        my @sws = `server/sws --version`;
+        my $cmd = "server/sws".exe_ext('SRV')." --version";
+        my @sws = `$cmd`;
         $http_unix = 1 if($sws[0] =~ /unix/);
     }
 
@@ -3334,7 +3369,7 @@ sub singletest {
                 }
                 else {
                     if($var =~ /^LD_PRELOAD/) {
-                        if(exe_ext() && (exe_ext() eq '.exe')) {
+                        if(exe_ext('TOOL') && (exe_ext('TOOL') eq '.exe')) {
                             # print "Skipping LD_PRELOAD due to lack of OS 
support\n";
                             next;
                         }
@@ -3481,6 +3516,7 @@ sub singletest {
     if(@codepieces) {
         $tool = $codepieces[0];
         chomp $tool;
+        $tool .= exe_ext('TOOL');
     }
 
     # remove server output logfile
@@ -5010,6 +5046,18 @@ while(@ARGV) {
             $tortalloc = $1;
         }
     }
+    elsif($ARGV[0] =~ /--shallow=(\d+)(,|)(\d*)/) {
+        # Fail no more than this amount per tests when running
+        # torture.
+        my ($num, $seed)=($1,$3);
+        $shallow=$num;
+        $shallowseed=$seed?$seed:1234; # get a real seed later
+        srand($shallowseed); # make it predictable
+    }
+    elsif($ARGV[0] =~ /--repeat=(\d+)/) {
+        # Repeat-run the given tests this many times
+        $repeat = $1;
+    }
     elsif($ARGV[0] eq "-a") {
         # continue anyway, even if a test fail
         $anyway=1;
@@ -5058,6 +5106,7 @@ while(@ARGV) {
         print <<EOHELP
 Usage: runtests.pl [options] [test selection(s)]
   -a       continue even if a test fails
+  -am      automake style output PASS/FAIL: [number] [name]
   -bN      use base port number N for test servers (default $base)
   -c path  use this curl executable
   -d       display server debug info
@@ -5073,7 +5122,7 @@ Usage: runtests.pl [options] [test selection(s)]
   -r       run time statistics
   -rf      full run time statistics
   -s       short output
-  -am      automake style output PASS/FAIL: [number] [name]
+  --shallow=[num](,seed) make the torture tests thinner
   -t[N]    torture (simulate function failures); N means fail Nth function
   -v       verbose output
   -vc path use this curl only to verify the existing servers
@@ -5298,6 +5347,13 @@ else {
     }
     $TESTCASES = $verified;
 }
+if($repeat) {
+    my $s;
+    for(1 .. $repeat) {
+        $s .= $TESTCASES;
+    }
+    $TESTCASES = $s;
+}
 
 if($scrambleorder) {
     # scramble the order of the test cases
diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt
index 06f3a75f6..3a15284e4 100644
--- a/tests/server/CMakeLists.txt
+++ b/tests/server/CMakeLists.txt
@@ -1,7 +1,7 @@
 set(TARGET_LABEL_PREFIX "Test server ")
 
 if(MSVC)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127 /wd4306")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4306")
 endif()
 
 function(SETUP_EXECUTABLE TEST_NAME)    # ARGN are the files in the test
@@ -11,7 +11,7 @@ function(SETUP_EXECUTABLE TEST_NAME)    # ARGN are the files 
in the test
   include_directories(
     ${GNURL_SOURCE_DIR}/lib      # To be able to reach "curl_setup_once.h"
     ${GNURL_BINARY_DIR}/lib      # To be able to reach "curl_config.h"
-    ${GNURL_BINARY_DIR}/include  # To be able to reach "curl/curl.h"
+    ${GNURL_BINARY_DIR}/include  # To be able to reach "gnurl/curl.h"
     )
   if(USE_ARES)
     include_directories(${CARES_INCLUDE_DIR})
diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am
index 177e0215e..a5b98130c 100644
--- a/tests/server/Makefile.am
+++ b/tests/server/Makefile.am
@@ -62,7 +62,7 @@ CS_1 =
 CS_ = $(CS_0)
 
 checksrc:
-       $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+       $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.[ch]
 
 if CURLDEBUG
 # for debug builds, we scan the sources on all regular make invokes
diff --git a/tests/server/resolve.c b/tests/server/resolve.c
index 4cbdba6ec..993e03125 100644
--- a/tests/server/resolve.c
+++ b/tests/server/resolve.c
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
   while(argc>arg) {
     if(!strcmp("--version", argv[arg])) {
       printf("resolve IPv4%s\n",
-#ifdef ENABLE_IPV6
+#if defined(CURLRES_IPV6)
              "/IPv6"
 #else
              ""
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
     puts("Usage: resolve [option] <host>\n"
          " --version\n"
          " --ipv4"
-#ifdef ENABLE_IPV6
+#if defined(CURLRES_IPV6)
          "\n --ipv6"
 #endif
          );
@@ -107,7 +107,7 @@ int main(int argc, char *argv[])
   atexit(win32_cleanup);
 #endif
 
-#ifdef ENABLE_IPV6
+#if defined(CURLRES_IPV6)
   if(use_ipv6) {
     /* Check that the system has IPv6 enabled before checking the resolver */
     curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
diff --git a/tests/server/util.c b/tests/server/util.c
index cc53d3bf4..263f0cece 100644
--- a/tests/server/util.c
+++ b/tests/server/util.c
@@ -150,7 +150,8 @@ void win32_perror(const char *msg)
   char buf[512];
   DWORD err = SOCKERRNO;
 
-  if(!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+  if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
                      LANG_NEUTRAL, buf, sizeof(buf), NULL))
     msnprintf(buf, sizeof(buf), "Unknown error %lu (%#lx)", err, err);
   if(msg)
diff --git a/tests/sshhelp.pm b/tests/sshhelp.pm
index 47ea2324c..248be67a2 100644
--- a/tests/sshhelp.pm
+++ b/tests/sshhelp.pm
@@ -106,12 +106,12 @@ use vars qw(
 #***************************************************************************
 # Global variables initialization
 #
-$sshdexe         = 'sshd'        .exe_ext(); # base name and ext of ssh daemon
-$sshexe          = 'ssh'         .exe_ext(); # base name and ext of ssh client
-$sftpsrvexe      = 'sftp-server' .exe_ext(); # base name and ext of sftp-server
-$sftpexe         = 'sftp'        .exe_ext(); # base name and ext of sftp client
-$sshkeygenexe    = 'ssh-keygen'  .exe_ext(); # base name and ext of ssh-keygen
-$httptlssrvexe   = 'gnutls-serv' .exe_ext(); # base name and ext of gnutls-serv
+$sshdexe         = 'sshd'        .exe_ext('SSH'); # base name and ext of ssh 
daemon
+$sshexe          = 'ssh'         .exe_ext('SSH'); # base name and ext of ssh 
client
+$sftpsrvexe      = 'sftp-server' .exe_ext('SSH'); # base name and ext of 
sftp-server
+$sftpexe         = 'sftp'        .exe_ext('SSH'); # base name and ext of sftp 
client
+$sshkeygenexe    = 'ssh-keygen'  .exe_ext('SSH'); # base name and ext of 
ssh-keygen
+$httptlssrvexe   = 'gnutls-serv' .exe_ext('SSH'); # base name and ext of 
gnutls-serv
 $sshdconfig      = 'curl_sshd_config';       # ssh daemon config file
 $sshconfig       = 'curl_ssh_config';        # ssh client config file
 $sftpconfig      = 'curl_sftp_config';       # sftp client config file
@@ -180,6 +180,13 @@ $clipubkeyf      = 'curl_client_key.pub';    # client 
public key file
 # Return file extension for executable files on this operating system
 #
 sub exe_ext {
+    my ($component, @arr) = @_;
+    if ($ENV{'CURL_TEST_EXE_EXT'}) {
+        return $ENV{'CURL_TEST_EXE_EXT'};
+    }
+    if ($ENV{'CURL_TEST_EXE_EXT_'.$component}) {
+        return $ENV{'CURL_TEST_EXE_EXT_'.$component};
+    }
     if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys' ||
         $^O eq 'dos' || $^O eq 'os2') {
         return '.exe';
@@ -314,7 +321,7 @@ sub find_exe_file {
     my $fn = $_[0];
     shift;
     my @path = @_;
-    my $xext = exe_ext();
+    my $xext = exe_ext('SSH');
     foreach (@path) {
         my $file = File::Spec->catfile($_, $fn);
         if(-e $file && ! -d $file) {
diff --git a/tests/sshserver.pl b/tests/sshserver.pl
index bcb2f1b3a..197e8b872 100644
--- a/tests/sshserver.pl
+++ b/tests/sshserver.pl
@@ -371,6 +371,9 @@ if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) ||
         logmsg 'Could not generate client key';
         exit 1;
     }
+    # Make sure that permissions are restricted so openssh doesn't complain
+    system "chmod 600 $hstprvkeyf";
+    system "chmod 600 $cliprvkeyf";
 }
 
 
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index ec62d9dfc..e4e10c236 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -31,7 +31,7 @@ include_directories(
   ${GNURL_SOURCE_DIR}/tests/libtest
   ${GNURL_SOURCE_DIR}/src
   ${GNURL_BINARY_DIR}/lib          # To be able to reach "curl_config.h"
-  ${GNURL_BINARY_DIR}/include      # To be able to reach "curl/curl.h"
+  ${GNURL_BINARY_DIR}/include      # To be able to reach "gnurl/curl.h"
 )
 
 foreach(_testfile ${UT_SRC})
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index c390c57da..5055aa86b 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -70,7 +70,7 @@ CS_1 =
 CS_ = $(CS_0)
 
 checksrc:
-       $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c
+       $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.[ch]
 
 if BUILD_UNITTESTS
 noinst_PROGRAMS = $(UNITPROGS)
diff --git a/tests/unit/curlcheck.h b/tests/unit/curlcheck.h
index c358afa6e..ecc556533 100644
--- a/tests/unit/curlcheck.h
+++ b/tests/unit/curlcheck.h
@@ -52,7 +52,7 @@
     fprintf(stderr, "%s:%d test failed: '%s'\n",                       \
             __FILE__, __LINE__, msg);                                  \
     unitfail++;                                                        \
-  } WHILE_FALSE
+  } while(0)
 
 
 /* The abort macros mark the current test step as failed, and exit the test */
@@ -77,7 +77,7 @@
             __FILE__, __LINE__, msg);                         \
     unitfail++;                                               \
     goto unit_test_abort;                                     \
-  } WHILE_FALSE
+  } while(0)
 
 
 
diff --git a/tests/unit/unit1607.c b/tests/unit/unit1607.c
index a8b0331ce..e8d412080 100644
--- a/tests/unit/unit1607.c
+++ b/tests/unit/unit1607.c
@@ -99,23 +99,23 @@ static const struct testcase tests[] = {
 };
 
 UNITTEST_START
+{
   int i;
   int testnum = sizeof(tests) / sizeof(struct testcase);
+  struct Curl_multi *multi = NULL;
+  struct Curl_easy *easy = NULL;
+  struct curl_slist *list = NULL;
 
   for(i = 0; i < testnum; ++i) {
     int j;
     int addressnum = sizeof(tests[i].address) / sizeof(*tests[i].address);
     struct Curl_addrinfo *addr;
     struct Curl_dns_entry *dns;
-    struct curl_slist *list;
     void *entry_id;
     bool problem = false;
-    struct Curl_multi *multi;
-    struct Curl_easy *easy = curl_easy_init();
-    if(!easy) {
-      curl_global_cleanup();
-      return CURLE_OUT_OF_MEMORY;
-    }
+    easy = curl_easy_init();
+    if(!easy)
+      goto error;
 
     /* create a multi handle and add the easy handle to it so that the
        hostcache is setup */
@@ -124,16 +124,14 @@ UNITTEST_START
 
     list = curl_slist_append(NULL, tests[i].optval);
     if(!list)
-        goto unit_test_abort;
+      goto error;
     curl_easy_setopt(easy, CURLOPT_RESOLVE, list);
 
     Curl_loadhostpairs(easy);
 
     entry_id = (void *)aprintf("%s:%d", tests[i].host, tests[i].port);
-    if(!entry_id) {
-      curl_slist_free_all(list);
-      goto unit_test_abort;
-    }
+    if(!entry_id)
+      goto error;
     dns = Curl_hash_pick(easy->dns.hostcache, entry_id, strlen(entry_id) + 1);
     free(entry_id);
     entry_id = NULL;
@@ -202,12 +200,20 @@ UNITTEST_START
     }
 
     curl_easy_cleanup(easy);
+    easy = NULL;
     curl_multi_cleanup(multi);
+    multi = NULL;
     curl_slist_free_all(list);
+    list = NULL;
 
     if(problem) {
       unitfail++;
       continue;
     }
   }
+  error:
+  curl_easy_cleanup(easy);
+  curl_multi_cleanup(multi);
+  curl_slist_free_all(list);
+}
 UNITTEST_STOP
diff --git a/tests/unit/unit1609.c b/tests/unit/unit1609.c
index 8223a147c..ce3ddf9d8 100644
--- a/tests/unit/unit1609.c
+++ b/tests/unit/unit1609.c
@@ -100,6 +100,9 @@ UNITTEST_START
 {
   int i;
   int testnum = sizeof(tests) / sizeof(struct testcase);
+  struct Curl_multi *multi = NULL;
+  struct Curl_easy *easy = NULL;
+  struct curl_slist *list = NULL;
 
 /* important: we setup cache outside of the loop
   and also clean cache after the loop. In contrast,for example,
@@ -110,11 +113,9 @@ UNITTEST_START
     int addressnum = sizeof (tests[i].address) / sizeof (*tests[i].address);
     struct Curl_addrinfo *addr;
     struct Curl_dns_entry *dns;
-    struct curl_slist *list;
     void *entry_id;
     bool problem = false;
-    struct Curl_multi *multi;
-    struct Curl_easy *easy = curl_easy_init();
+    easy = curl_easy_init();
     if(!easy) {
       curl_global_cleanup();
       return CURLE_OUT_OF_MEMORY;
@@ -122,21 +123,23 @@ UNITTEST_START
     /* create a multi handle and add the easy handle to it so that the
        hostcache is setup */
     multi = curl_multi_init();
+    if(!multi)
+      goto error;
     curl_multi_add_handle(multi, easy);
 
     list = curl_slist_append(NULL, tests[i].optval);
     if(!list)
-        goto unit_test_abort;
+      goto error;
 
     curl_easy_setopt(easy, CURLOPT_RESOLVE, list);
 
-    Curl_loadhostpairs(easy);
+    if(Curl_loadhostpairs(easy))
+      goto error;
 
     entry_id = (void *)aprintf("%s:%d", tests[i].host, tests[i].port);
-    if(!entry_id) {
-      curl_slist_free_all(list);
-      goto unit_test_abort;
-    }
+    if(!entry_id)
+      goto error;
+
     dns = Curl_hash_pick(easy->dns.hostcache, entry_id, strlen(entry_id) + 1);
     free(entry_id);
     entry_id = NULL;
@@ -194,14 +197,22 @@ UNITTEST_START
     }
 
     curl_easy_cleanup(easy);
+    easy = NULL;
     Curl_hash_destroy(&multi->hostcache);
     curl_multi_cleanup(multi);
+    multi = NULL;
     curl_slist_free_all(list);
+    list = NULL;
 
     if(problem) {
       unitfail++;
       continue;
     }
   }
+  goto unit_test_abort;
+  error:
+  curl_easy_cleanup(easy);
+  curl_multi_cleanup(multi);
+  curl_slist_free_all(list);
 }
 UNITTEST_STOP
diff --git a/tests/unit/unit1620.c b/tests/unit/unit1620.c
index c6aa721cf..6e572c648 100644
--- a/tests/unit/unit1620.c
+++ b/tests/unit/unit1620.c
@@ -46,6 +46,8 @@ UNITTEST_START
   bool protocol_connect = FALSE;
 
   rc = Curl_open(&empty);
+  if(rc)
+    goto unit_test_abort;
   fail_unless(rc == CURLE_OK, "Curl_open() failed");
 
   rc = Curl_connect(empty, &async, &protocol_connect);
diff --git a/tests/unit/unit1650.c b/tests/unit/unit1650.c
index cd6f519f7..35ac12c81 100644
--- a/tests/unit/unit1650.c
+++ b/tests/unit/unit1650.c
@@ -33,7 +33,7 @@ static void unit_stop(void)
 
 }
 
-#ifdef USE_NGHTTP2
+#ifndef CURL_DISABLE_DOH
 #define DNS_PREAMBLE "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"
 #define LABEL_TEST "\x04\x74\x65\x73\x74"
 #define LABEL_HOST "\x04\x68\x6f\x73\x74"
@@ -283,7 +283,7 @@ UNITTEST_START
 }
 UNITTEST_STOP
 
-#else /* USE_NGHTTP2 */
+#else /* CURL_DISABLE_DOH */
 UNITTEST_START
 {
   return 1; /* nothing to do, just fail */
diff --git a/tests/unit/unit1655.c b/tests/unit/unit1655.c
index 7fea134d5..a06b23a76 100644
--- a/tests/unit/unit1655.c
+++ b/tests/unit/unit1655.c
@@ -34,45 +34,103 @@ static void unit_stop(void)
     /* done before shutting down and exiting */
 }
 
+#ifndef CURL_DISABLE_DOH
+
 UNITTEST_START
 
-/* introduce a scope and prove the corner case with write overflow,
- * so we can prove this test would detect it and that it is properly fixed
+/*
+ * Prove detection of write overflow using a short buffer and a name
+ * of maximal valid length.
+ *
+ * Prove detection of other invalid input.
  */
 do {
-  const char *bad = "this.is.a.hostname.where.each.individual.part.is.within."
-    "the.sixtythree.character.limit.but.still.long.enough.to."
-    "trigger.the.the.buffer.overflow......it.is.chosen.to.be."
-    "of.a.length.such.that.it.causes.a.two.byte.buffer......."
-    "overwrite.....making.it.longer.causes.doh.encode.to....."
-    ".return.early.so.dont.change.its.length.xxxx.xxxxxxxxxxx"
-    "..xxxxxx.....xx..........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-    "xxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx..x......xxxx"
-    "xxxx..xxxxxxxxxxxxxxxxxxx.x...xxxx.x.x.x...xxxxx";
+  const char *max =
+    /* ..|....1.........2.........3.........4.........5.........6... */
+    /* 3456789012345678901234567890123456789012345678901234567890123 */
+    "this.is.a.maximum-length.hostname."                  /* 34:  34 */
+    "with-no-label-of-greater-length-than-the-sixty-three-characters."
+                                                          /* 64:  98 */
+    "specified.in.the.RFCs."                              /* 22: 120 */
+    "and.with.a.QNAME.encoding.whose.length.is.exactly."  /* 50: 170 */
+    "the.maximum.length.allowed."                         /* 27: 197 */
+    "that.is.two-hundred.and.fifty-six."                  /* 34: 231 */
+    "including.the.last.null."                            /* 24: 255 */
+    "";
+  const char *toolong =
+    /* ..|....1.........2.........3.........4.........5.........6... */
+    /* 3456789012345678901234567890123456789012345678901234567890123 */
+    "here.is.a.hostname.which.is.just.barely.too.long."   /* 49:  49 */
+    "to.be.encoded.as.a.QNAME.of.the.maximum.allowed.length."
+                                                          /* 55: 104 */
+    "which.is.256.including.a.final.zero-length.label."   /* 49: 153 */
+    "representing.the.root.node.so.that.a.name.with."     /* 47: 200 */
+    "a.trailing.dot.may.have.up.to."                      /* 30: 230 */
+    "255.characters.never.more."                          /* 26: 256 */
+    "";
+  const char *emptylabel =
+    "this.is.an.otherwise-valid.hostname."
+    ".with.an.empty.label.";
+  const char *outsizelabel =
+    "this.is.an.otherwise-valid.hostname."
+    "with-a-label-of-greater-length-than-the-sixty-three-characters-"
+    "specified.in.the.RFCs.";
+
+  struct test {
+    const char *name;
+    const DOHcode expected_result;
+  };
 
   /* plays the role of struct dnsprobe in urldata.h */
   struct demo {
-    unsigned char dohbuffer[512];
+    unsigned char dohbuffer[255 + 16]; /* deliberately short buffer */
     unsigned char canary1;
     unsigned char canary2;
     unsigned char canary3;
   };
 
-  size_t olen = 100000;
-  struct demo victim;
-  DOHcode d;
-  victim.canary1 = 87; /* magic numbers, arbritrarily picked */
-  victim.canary2 = 35;
-  victim.canary3 = 41;
-  d = doh_encode(bad, DNS_TYPE_A, victim.dohbuffer,
-                 sizeof(victim.dohbuffer), &olen);
-  fail_unless(victim.canary1 == 87, "one byte buffer overwrite has happened");
-  fail_unless(victim.canary2 == 35, "two byte buffer overwrite has happened");
-  fail_unless(victim.canary3 == 41,
-              "three byte buffer overwrite has happened");
-  if(d == DOH_OK) {
-    fail_unless(olen <= sizeof(victim.dohbuffer), "wrote outside bounds");
-    fail_unless(olen > strlen(bad), "unrealistic low size");
+  const struct test playlist[4] = {
+    { toolong, DOH_DNS_NAME_TOO_LONG },  /* expect early failure */
+    { emptylabel, DOH_DNS_BAD_LABEL },   /* also */
+    { outsizelabel, DOH_DNS_BAD_LABEL }, /* also */
+    { max, DOH_OK }                      /* expect buffer overwrite */
+  };
+
+  for(int i = 0; i < (int)(sizeof(playlist)/sizeof(*playlist)); i++) {
+    const char *name = playlist[i].name;
+    size_t olen = 100000;
+    struct demo victim;
+    DOHcode d;
+
+    victim.canary1 = 87; /* magic numbers, arbritrarily picked */
+    victim.canary2 = 35;
+    victim.canary3 = 41;
+    d = doh_encode(name, DNS_TYPE_A, victim.dohbuffer,
+                   sizeof(struct demo), /* allow room for overflow */
+                   &olen);
+
+    fail_unless(d == playlist[i].expected_result,
+                "result returned was not as expected");
+    if(d == playlist[i].expected_result) {
+      if(name == max) {
+        fail_if(victim.canary1 == 87,
+                "demo one-byte buffer overwrite did not happen");
+      }
+      else {
+        fail_unless(victim.canary1 == 87,
+                    "one-byte buffer overwrite has happened");
+      }
+      fail_unless(victim.canary2 == 35,
+                  "two-byte buffer overwrite has happened");
+      fail_unless(victim.canary3 == 41,
+                  "three-byte buffer overwrite has happened");
+    }
+    else {
+      if(d == DOH_OK) {
+        fail_unless(olen <= sizeof(victim.dohbuffer), "wrote outside bounds");
+        fail_unless(olen > strlen(name), "unrealistic low size");
+      }
+    }
   }
 } while(0);
 
@@ -84,6 +142,7 @@ do {
   const size_t magic1 = 9765;
   size_t olen1 = magic1;
   const char *sunshine1 = "a.com";
+  const char *dotshine1 = "a.com.";
   const char *sunshine2 = "aa.com";
   size_t olen2;
   DOHcode ret2;
@@ -94,6 +153,13 @@ do {
   fail_if(olen1 == magic1, "olen has not been assigned properly");
   fail_unless(olen1 > strlen(sunshine1), "bad out length");
 
+  /* with a trailing dot, the response should have the same length */
+  olen2 = magic1;
+  ret2 = doh_encode(dotshine1, dnstype, buffer, buflen, &olen2);
+  fail_unless(ret2 == DOH_OK, "dotshine case should pass fine");
+  fail_if(olen2 == magic1, "olen has not been assigned properly");
+  fail_unless(olen1 == olen2, "olen should not grow for a trailing dot");
+
   /* add one letter, the response should be one longer */
   olen2 = magic1;
   ret2 = doh_encode(sunshine2, dnstype, buffer, buflen, &olen2);
@@ -111,3 +177,13 @@ do {
   fail_unless(olen == olen1, "bad buffer length");
 } while(0);
 UNITTEST_STOP
+
+#else /* CURL_DISABLE_DOH */
+
+UNITTEST_START
+{
+  return 1; /* nothing to do, just fail */
+}
+UNITTEST_STOP
+
+#endif

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]