From fe2500aa99137c9ce35907c118745d65a0c0c07e Mon Sep 17 00:00:00 2001
From: George Hazan <ghazan@miranda.im>
Date: Tue, 17 Sep 2019 12:36:24 +0300
Subject: libcurl updated to 7.66

---
 libs/libcurl/docs/CHANGES                 | 10998 ++++++++++++++--------------
 libs/libcurl/docs/THANKS                  |    25 +-
 libs/libcurl/include/curl/curl.h          |    35 +-
 libs/libcurl/include/curl/curlver.h       |    16 +-
 libs/libcurl/include/curl/easy.h          |     6 +-
 libs/libcurl/include/curl/mprintf.h       |     8 +-
 libs/libcurl/include/curl/multi.h         |    20 +-
 libs/libcurl/include/curl/stdcheaders.h   |     8 +-
 libs/libcurl/include/curl/system.h        |    30 +-
 libs/libcurl/include/curl/typecheck-gcc.h |   547 +-
 libs/libcurl/include/curl/urlapi.h        |     6 +-
 libs/libcurl/libcurl.vcxproj              |     3 +
 libs/libcurl/src/Makefile.am              |     8 +-
 libs/libcurl/src/Makefile.in              |   273 +-
 libs/libcurl/src/Makefile.inc             |    16 +-
 libs/libcurl/src/altsvc.c                 |    65 +-
 libs/libcurl/src/altsvc.h                 |    27 +-
 libs/libcurl/src/asyn-ares.c              |     6 +-
 libs/libcurl/src/asyn-thread.c            |   102 +-
 libs/libcurl/src/asyn.h                   |     3 +-
 libs/libcurl/src/base64.c                 |     4 +-
 libs/libcurl/src/config-os400.h           |     3 +
 libs/libcurl/src/config-plan9.h           |   217 +
 libs/libcurl/src/connect.c                |   160 +-
 libs/libcurl/src/connect.h                |     3 +
 libs/libcurl/src/cookie.c                 |    14 +-
 libs/libcurl/src/curl_config.h.in         |    27 +
 libs/libcurl/src/curl_md4.h               |    10 +-
 libs/libcurl/src/curl_ntlm_core.c         |    70 +-
 libs/libcurl/src/curl_path.c              |     2 +-
 libs/libcurl/src/curl_rtmp.c              |    14 +-
 libs/libcurl/src/curl_sasl.c              |    10 +-
 libs/libcurl/src/curl_setup.h             |    17 +-
 libs/libcurl/src/doh.h                    |     3 +-
 libs/libcurl/src/easy.c                   |    87 +-
 libs/libcurl/src/ftp.c                    |    23 +-
 libs/libcurl/src/getenv.c                 |     4 +-
 libs/libcurl/src/getinfo.c                |     8 +-
 libs/libcurl/src/hostip.c                 |     8 +-
 libs/libcurl/src/hostip.h                 |     6 +-
 libs/libcurl/src/hostip6.c                |     3 +-
 libs/libcurl/src/http.c                   |   208 +-
 libs/libcurl/src/http.h                   |    31 +-
 libs/libcurl/src/http2.c                  |    23 +-
 libs/libcurl/src/http_negotiate.c         |     4 +-
 libs/libcurl/src/imap.c                   |     8 +-
 libs/libcurl/src/libcurl.plist            |     6 +-
 libs/libcurl/src/md4.c                    |   248 +-
 libs/libcurl/src/multi.c                  |   252 +-
 libs/libcurl/src/multiif.h                |     9 +-
 libs/libcurl/src/netrc.c                  |   151 +-
 libs/libcurl/src/openldap.c               |    28 +-
 libs/libcurl/src/pingpong.c               |    13 +-
 libs/libcurl/src/pingpong.h               |     5 +-
 libs/libcurl/src/pop3.c                   |     8 +-
 libs/libcurl/src/progress.c               |    13 +-
 libs/libcurl/src/quic.h                   |    53 +
 libs/libcurl/src/rtsp.c                   |     9 +-
 libs/libcurl/src/security.c               |     6 +-
 libs/libcurl/src/select.h                 |     6 +-
 libs/libcurl/src/setopt.c                 |    37 +-
 libs/libcurl/src/smb.c                    |    12 +-
 libs/libcurl/src/smtp.c                   |    14 +-
 libs/libcurl/src/ssh-libssh.c             |  2739 -------
 libs/libcurl/src/ssh.c                    |  3337 ---------
 libs/libcurl/src/ssh.h                    |    13 +-
 libs/libcurl/src/strerror.c               |     3 +
 libs/libcurl/src/tftp.c                   |    77 +-
 libs/libcurl/src/timeval.c                |    24 +-
 libs/libcurl/src/timeval.h                |    10 +-
 libs/libcurl/src/transfer.c               |    27 +-
 libs/libcurl/src/transfer.h               |     3 +-
 libs/libcurl/src/url.c                    |   281 +-
 libs/libcurl/src/url.h                    |    13 -
 libs/libcurl/src/urlapi.c                 |    17 +-
 libs/libcurl/src/urldata.h                |    58 +-
 libs/libcurl/src/vauth/digest_sspi.c      |    15 +-
 libs/libcurl/src/vauth/krb5_gssapi.c      |    10 +-
 libs/libcurl/src/vauth/krb5_sspi.c        |    26 +-
 libs/libcurl/src/vauth/ntlm_sspi.c        |    14 +-
 libs/libcurl/src/vauth/spnego_gssapi.c    |     6 +-
 libs/libcurl/src/vauth/spnego_sspi.c      |    23 +-
 libs/libcurl/src/version.c                |    60 +-
 libs/libcurl/src/vssh/libssh.c            |  2747 +++++++
 libs/libcurl/src/vssh/libssh2.c           |  3346 +++++++++
 libs/libcurl/src/vtls/mesalink.c          |    62 +-
 libs/libcurl/src/vtls/nss.c               |    16 +-
 libs/libcurl/src/vtls/openssl.c           |   233 +-
 libs/libcurl/src/vtls/vtls.c              |    10 +-
 libs/libcurl/src/vtls/vtls.h              |     3 +-
 90 files changed, 13945 insertions(+), 13267 deletions(-)
 create mode 100644 libs/libcurl/src/config-plan9.h
 create mode 100644 libs/libcurl/src/quic.h
 delete mode 100644 libs/libcurl/src/ssh-libssh.c
 delete mode 100644 libs/libcurl/src/ssh.c
 create mode 100644 libs/libcurl/src/vssh/libssh.c
 create mode 100644 libs/libcurl/src/vssh/libssh2.c

(limited to 'libs/libcurl')

diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES
index 447b46a526..0047ab41ac 100644
--- a/libs/libcurl/docs/CHANGES
+++ b/libs/libcurl/docs/CHANGES
@@ -6,8010 +6,7620 @@
 
                                   Changelog
 
-Version 7.65.3 (19 Jul 2019)
+Version 7.66.0 (10 Sep 2019)
 
-Daniel Stenberg (19 Jul 2019)
-- RELEASE-NOTES: 7.65.3
+Daniel Stenberg (10 Sep 2019)
+- RELEASE-NOTES: curl 7.66.0
 
-- THANKS: 7.65.3 status
+- THANKS: from the 7.66.0 release
 
-- progress: make the progress meter appear again
+- curl: make sure the parallel transfers do them all
   
-  Fix regression caused by 21080e1
+  The logic could erroneously break the loop too early before all
+  transfers had been transferred.
   
-  Reported-by: Chih-Hsuan Yen
-  Fixes #4122
-  Closes #4124
+  Reported-by: Tom van der Woerdt
+  Fixes #4316
+  Closes #4317
 
-- version: bump to 7.65.3
+- urlapi: one colon is enough for the strspn() input (typo)
 
-- RELEASE-NOTES: Contributors or now 1990
+- urlapi: verify the IPv6 numerical address
+  
+  It needs to parse correctly. Otherwise it could be tricked into letting
+  through a-f using host names that libcurl would then resolve. Like
+  '[ab.be]'.
+  
+  Reported-by: Thomas Vegas
+  Closes #4315
 
-Version 7.65.2 (17 Jul 2019)
+- [Clément Notin brought this change]
 
-Daniel Stenberg (17 Jul 2019)
-- RELEASE-NOTES: 7.65.2
+  openssl: use SSL_CTX_set_<min|max>_proto_version() when available
+  
+  OpenSSL 1.1.0 adds SSL_CTX_set_<min|max>_proto_version() that we now use
+  when available.  Existing code is preserved for older versions of
+  OpenSSL.
+  
+  Closes #4304
 
-- THANKS: add contributors from 7.65.2
+- [Clément Notin brought this change]
 
-Jay Satiro (17 Jul 2019)
-- [aasivov brought this change]
+  openssl: indent, re-organize and add comments
 
-  cmake: Fix finding Brotli on case-sensitive file systems
-  
-  - Find package "Brotli" instead of "BROTLI" since the former is the
-    casing used for CMake/FindBrotli.cmake, and otherwise find_package
-    may fail on a case-sensitive file system.
-  
-  Fixes https://github.com/curl/curl/issues/4117
+- [migueljcrum brought this change]
 
-- CURLOPT_RANGE.3: Caution against using it for HTTP PUT
+  sspi: fix memory leaks
   
-  AFAICT CURLOPT_RANGE does not support ranged HTTP PUT uploads so I've
-  cautioned against using it for that purpose and included a workaround.
+  Closes #4299
+
+- travis: disable ngtcp2 builds (again)
+
+- Curl_fillreadbuffer: avoid double-free trailer buf on error
   
-  Bug: https://curl.haxx.se/mail/lib-2019-04/0075.html
-  Reported-by: Christopher Head
+  Reviewed-by: Jay Satiro
+  Reported-by: Thomas Vegas
   
-  Closes https://github.com/curl/curl/issues/3814
+  Closes #4307
 
-- [Stefano Simonelli brought this change]
+- tool_setopt: handle a libcurl build without netrc support
+  
+  Reported-by: codesniffer13 on github
+  Fixes #4302
+  Closes #4305
 
-  CURLOPT_SEEKDATA.3: fix variable name
+- security:read_data fix bad realloc()
   
-  Closes https://github.com/curl/curl/pull/4118
+  ... that could end up a double-free
+  
+  CVE-2019-5481
+  Bug: https://curl.haxx.se/docs/CVE-2019-5481.html
 
-- [georgeok brought this change]
+- [Thomas Vegas brought this change]
 
-  CIPHERS.md: Explain Schannel error SEC_E_ALGORITHM_MISMATCH
+  tftp: Alloc maximum blksize, and use default unless OACK is received
   
-  If the SSL backend is Schannel and the user specifies an Schannel CALG_
-  that is not supported by the protocol or the server then curl returns
-  CURLE_SSL_CONNECT_ERROR (35) SEC_E_ALGORITHM_MISMATCH.
+  Fixes potential buffer overflow from 'recvfrom()', should the server
+  return an OACK without blksize.
   
-  Fixes https://github.com/curl/curl/issues/3389
-  Closes https://github.com/curl/curl/pull/4106
+  Bug: https://curl.haxx.se/docs/CVE-2019-5482.html
+  CVE-2019-5482
 
-- [Daniel Gustafsson brought this change]
+- [Thomas Vegas brought this change]
 
-  nss: inspect returnvalue of token check
+  tftp: return error when packet is too small for options
+
+- KNOWN_BUGS/TODO: cleanup and remove outdated issues
+
+- RELEASE-NOTES: synced
+
+- netrc: free 'home' on error
   
-  PK11_IsPresent() checks for the token for the given slot is available,
-  and sets needlogin flags for the PK11_Authenticate() call.  Should it
-  return false, we should however treat it as an error and bail out.
+  Follow-up to f9c7ba9096ec2
   
-  Closes https://github.com/curl/curl/pull/4110
+  Coverity CID 1453474
+  
+  Closes #4291
 
-- docs: Explain behavior change in --tlsv1. options since 7.54
+- urldata: avoid 'generic', use dedicated pointers
   
-  Since 7.54 --tlsv1. options use the specified version or later, however
-  older versions of curl documented it as using just the specified version
-  which may or may not have happened depending on the TLS library.
-  Document this discrepancy to allay confusion for users familiar with the
-  old documentation that expect just the specified version.
+  For the 'proto' union within the connectdata struct.
   
-  Fixes https://github.com/curl/curl/issues/4097
-  Closes https://github.com/curl/curl/pull/4119
+  Closes #4290
 
-- libcurl: Restrict redirect schemes (follow-up)
+- cleanup: move functions out of url.c and make them static
   
-  - Allow FTPS on redirect.
+  Closes #4289
+
+- smtp: check for and bail out on too short EHLO response
   
-  - Update default allowed redirect protocols in documentation.
+  Otherwise, a three byte response would make the smtp_state_ehlo_resp()
+  function misbehave.
   
-  Follow-up to 6080ea0.
+  Credit to OSS-Fuzz
+  Bug: https://crbug.com/oss-fuzz/16918
   
-  Ref: https://github.com/curl/curl/pull/4094
+  Assisted-by: Max Dymond
   
-  Closes https://github.com/curl/curl/pull/4115
+  Closes #4287
 
-Daniel Stenberg (16 Jul 2019)
-- test1173: make it also check all libcurl option man pages
-  
-  ... and adjust those that cause errors
+- smb: init *msg to NULL in smb_send_and_recv()
   
-  Closes #4116
-
-- curl: only accept COLUMNS less than 10000
+  ... it might otherwise return OK from this function leaving that pointer
+  uninitialized.
   
-  ... as larger values would rather indicate something silly (and could
-  potentially cause buffer problems).
+  Bug: https://crbug.com/oss-fuzz/16907
   
-  Reported-by: pendrek at hackerone
-  Closes #4114
+  Closes #4286
 
-- dist: add manpage-syntax.pl
+- ROADMAP: updated after recent user poll
   
-  follow-up to 7fb66c403
+  In rough prio order
 
-- test1173: detect some basic man page format mistakes
+- THANKS: remove duplicate
+
+- Curl_addr2string: take an addrlen argument too
   
-  Triggered by PR #4111
+  This allows the function to figure out if a unix domain socket has a
+  file name or not associated with it! When a socket is created with
+  socketpair(), as done in the fuzzer testing, the path struct member is
+  uninitialized and must not be accessed.
   
-  Closes #4113
+  Bug: https://crbug.com/oss-fuzz/16699
+  
+  Closes #4283
 
-Jay Satiro (15 Jul 2019)
-- [Bjarni Ingi Gislason brought this change]
+- [Rolf Eike Beer brought this change]
 
-  docs: Fix missing lines caused by undefined macros
+  CMake: remove needless newlines at end of gss variables
+
+- [Rolf Eike Beer brought this change]
+
+  CI: remove duplicate configure flag for LGTM.com
+
+- [Rolf Eike Beer brought this change]
+
+  CMake: use platform dependent name for dlopen() library
   
-  - Escape apostrophes at line start.
+  Closes #4279
+
+- quiche: expire when poll returned data
   
-  Some lines begin with a "'" (apostrophe, single quote), which is then
-  interpreted as a control character in *roff.
+  ... to make sure we continue draining the queue until empty
   
-  Such lines are interpreted as being a call to a macro, and if
-  undefined, the lines are removed from the output.
+  Closes #4281
+
+- quiche: decrease available buffer size, don't assign it!
   
-  Bug: https://bugs.debian.org/926352
-  Signed-off-by: Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
+  Found-by: Jeremy Lainé
+
+- RELEASE-NOTES: synced
+
+- [Kyohei Kadota brought this change]
+
+  curl: fix include conditions
+
+- [Kyohei Kadota brought this change]
+
+  plan9: fix installation instructions
   
-  Submitted-by: Alessandro Ghedini
+  Closes #4276
+
+- ngtcp2: on h3 stream close, call expire
   
-  Closes https://github.com/curl/curl/pull/4111
+  ... to trigger a new read to detect the stream close!
+  
+  Closes #4275
 
-Daniel Stenberg (14 Jul 2019)
-- libcurl-security.3: update to new CURLOPT_REDIR_PROTOCOLS defaults
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: build latest ngtcp2 and ngtcp2_crypto_openssl
   
-  follow-up to 6080ea098
+  Closes #4278
 
-- [Linos Giannopoulos brought this change]
+- ngtcp2: set flow control window to stream buffer size
+  
+  Closes #4274
 
-  libcurl: Add testcase for gopher redirects
+- [Christopher Head brought this change]
+
+  CURLOPT_HEADERFUNCTION.3: clarify
   
-  The testcase ensures that redirects to CURLPROTO_GOPHER won't be
-  allowed, by default, in the future. Also, curl is being used
-  for convenience while keeping the testcases DRY.
+  Closes #4273
+
+- CURLINFO docs: mention that in redirects times are added
   
-  The expected error code is CURLE_UNSUPPORTED_PROTOCOL when the client is
-  redirected to CURLPROTO_GOPHER
+  Suggested-by: Brandon Dong
+  Fixes #4250
+  Closes #4269
+
+- travis: enable ngtcp2 builds again
   
-  Signed-off-by: Linos Giannopoulos <lgian@skroutz.gr>
+  Switched to the openssl-quic-draft-22 openssl branch.
+  
+  Closes #4271
 
-- [Linos Giannopoulos brought this change]
+- HTTP3: switched openssl branch to use
 
-  libcurl: Restrict redirect schemes
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: Build with latest ngtcp2 and ngtcp2_crypto_openssl
   
-  All protocols except for CURLPROTO_FILE/CURLPROTO_SMB and their TLS
-  counterpart were allowed for redirect. This vastly broadens the
-  exploitation surface in case of a vulnerability such as SSRF [1], where
-  libcurl-based clients are forced to make requests to arbitrary hosts.
+  Closes #4270
+
+- http2: when marked for closure and wanted to close == OK
   
-  For instance, CURLPROTO_GOPHER can be used to smuggle any TCP-based
-  protocol by URL-encoding a payload in the URI. Gopher will open a TCP
-  connection and send the payload.
+  It could otherwise return an error even when closed correctly if GOAWAY
+  had been received previously.
   
-  Only HTTP/HTTPS and FTP are allowed. All other protocols have to be
-  explicitly enabled for redirects through CURLOPT_REDIR_PROTOCOLS.
+  Reported-by: Tom van der Woerdt
+  Fixes #4267
+  Closes #4268
+
+- RELEASE-NOTES: synced
+
+- build-openssl: fix build with Visual Studio 2019
   
-  [1]: https://www.acunetix.com/blog/articles/server-side-request-forgery-vulnerability/
+  Reviewed-by: Marcel Raad
+  Contributed-by: osabc on github
+  Fixes #4188
+  Closes #4266
+
+Kamil Dudka (26 Aug 2019)
+- vauth: return CURLE_AUTH_ERROR on gss_init_sec_context() failure
   
-  Signed-off-by: Linos Giannopoulos <lgian@skroutz.gr>
+  This is a follow-up to https://github.com/curl/curl/pull/3864 .
   
-  Closes #4094
+  Closes #4224
 
-- [Zenju brought this change]
+Daniel Stenberg (26 Aug 2019)
+- KNOWN_BUGS: USE_UNIX_SOCKETS on Windows
+  
+  Closes #4040
 
-  openssl: define HAVE_SSL_GET_SHUTDOWN based on version number
+- quiche: send the HTTP body correctly on callback uploads
   
-  Closes #4100
+  Closes #4265
 
-- [Peter Simonyi brought this change]
+- travis: disable ngtcp2 builds (temporarily)
+  
+  Just too many API changes right now
+  
+  Closes #4264
 
-  http: allow overriding timecond with custom header
+- ngtcp2: add support for SSLKEYLOGFILE
   
-  With CURLOPT_TIMECONDITION set, a header is automatically added (e.g.
-  If-Modified-Since).  Allow this to be replaced or suppressed with
-  CURLOPT_HTTPHEADER.
+  Closes #4260
+
+- ngtcp2: improve h3 response receiving
   
-  Fixes #4103
-  Closes #4109
+  Closes #4259
 
-Jay Satiro (11 Jul 2019)
-- [Juergen Hoetzel brought this change]
+- ngtcp2: use nghttp3_version()
 
-  smb: Use the correct error code for access denied on file open
+- ngtcp2: sync with upstream API changes
   
-  - Return CURLE_REMOTE_ACCESS_DENIED for SMB access denied on file open.
+  Assisted-by: Tatsuhiro Tsujikawa
+
+- [Kyle Abramowitz brought this change]
+
+  scp: fix directory name length used in memcpy
   
-  Prior to this change CURLE_REMOTE_FILE_NOT_FOUND was returned instead.
+  Fix read off end of array due to bad pointer math in getworkingpath for
+  SCP home directory case.
   
-  Closes https://github.com/curl/curl/pull/4095
-
-- [Daniel Gustafsson brought this change]
+  Closes #4258
 
-  DEPRECATE: fixup versions and spelling
+- http: the 'closed' struct field is used by both ngh2 and ngh3
   
-  Correctly set the July 17 version to 7.65.2, and update spelling to
-  be consistent. Also fix a typo.
+  and remove 'header_recvbuf', not used for anything
   
-  Closes https://github.com/curl/curl/pull/4107
+  Reported-by: Jeremy Lainé
+  
+  Closes #4257
 
-- [Gisle Vanem brought this change]
+- ngtcp2: accept upload via callback
+  
+  Closes #4256
 
-  system_win32: fix clang warning
+- defines: avoid underscore-prefixed defines
   
-  - Declare variable in header as extern.
+  Double-underscored or underscore plus uppercase letter at least.
   
-  Bug: https://github.com/curl/curl/commit/48b9ea4#commitcomment-34084597
-
-Daniel Gustafsson (10 Jul 2019)
-- headers: Remove no longer exported functions
+  ... as they're claimed to be reserved.
   
-  There were a leftover few prototypes of Curl_ functions that we used to
-  export but no longer do, this removes those prototypes and cleans up any
-  comments still referring to them.
+  Reported-by: patnyb on github
   
-  Curl_write32_le(), Curl_strcpy_url(), Curl_strlen_url(), Curl_up_free()
-  Curl_concat_url(), Curl_detach_connnection(), Curl_http_setup_conn()
-  were made static in 05b100aee247bb9bec8e9a1b0166496aa4248d1c.
-  Curl_http_perhapsrewind() made static in 574aecee208f79d391f10d57520b3.
+  Fixes #4254
+  Closes #4255
+
+- travis: add a build using ngtcp2 + nghttp3 (and a patched OpenSSL)
   
-  For the remainder, I didn't trawl the Git logs hard enough to capture
-  their exact time of deletion, but they were all gone: Curl_splayprint(),
-  Curl_http2_send_request(), Curl_global_host_cache_dtor(),
-  Curl_scan_cache_used(), Curl_hostcache_destroy(), Curl_second_connect(),
-  Curl_http_auth_stage() and Curl_close_connections().
+  Runs no tests
   
-  Closes #4096
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #4253
 
-- CMake: fix typos and spelling
+- travis: bump to using nghttp2 version 1.39.2
+  
+  Closes #4252
 
-- [Kyle Edwards brought this change]
+- [Gisle Vanem brought this change]
 
-  CMake: Convert errant elseif() to else()
+  docs/examples/curlx: fix errors
   
-  CMake interprets an elseif() with no arguments as elseif(FALSE),
-  resulting in the elseif() block not being executed. That is not what
-  was intended here. Change the empty elseif() to an else() as it was
-  intended.
+  Initialise 'mimetype' and require the -p12 arg.
   
-  Closes #4101
-  Reported-by: Artalus <artalus-mail@yandex.ru>
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Closes #4248
 
-- buildconf: fix header filename
+- cleanup: remove DOT_CHAR completely
   
-  The header file inclusion had a typo, it should be .h and not .hd.
-  Fix by renaming.
+  Follow-up to f9c7ba9096ec
   
-  Fixes #4102
-  Reported-by: AceCrow on Github
+  The use of DOT_CHAR for ".ssh" was probably a mistake and is removed
+  now.
+  
+  Pointed-out-by: Gisle Vanem
+  Bug: https://github.com/curl/curl/pull/4230#issuecomment-522960638
+  
+  Closes #4247
 
-- [Jan Chren brought this change]
+- spnego_sspi: add typecast to fix build warning
+  
+  Reported in build "Win32 target on Debian Stretch (64-bit) -
+  i686-w64-mingw32 - gcc-20170516"
+  
+  Closes #4245
 
-  configure: fix --disable-code-coverage
+- openssl: build warning free with boringssl
   
-  This fixes the case when --disable-code-coverage supplied to ./configure
-  would result in coverage="yes" being set.
+  Closes #4244
+
+- curl: make --libcurl use CURL_HTTP_VERSION_3
   
-  Closes #4099
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Closes #4243
 
-- cleanup: fix typo in comment
+- ngtcp2: make postfields-set posts work
+  
+  Closes #4242
 
-- RELEASE-NOTES: synced
+- http: remove chunked-encoding and expect header use for HTTP/3
 
-Jay Satiro (6 Jul 2019)
-- [Daniel Gustafsson brought this change]
+- [Alessandro Ghedini brought this change]
 
-  nss: support using libnss on macOS
+  configure: use pkg-config to detect quiche
   
-  The file suffix for dynamically loadable objects on macOS is .dylib,
-  which need to be added for the module definitions in order to get the
-  NSS TLS backend to work properly on macOS.
+  This removes the need to hard-code the quiche target path in
+  configure.ac.
   
-  Closes https://github.com/curl/curl/pull/4046
+  This depends on https://github.com/cloudflare/quiche/pull/128
+  
+  Closes #4237
 
-- [Daniel Gustafsson brought this change]
+- CURLOPT_SSL_VERIFYHOST: treat the value 1 as 2
+  
+  For a long time (since 7.28.1) we've returned error when setting the
+  value to 1 to make applications notice that we stopped supported the old
+  behavior for 1. Starting now, we treat 1 and 2 exactly the same.
+  
+  Closes #4241
 
-  nss: don't set unused parameter
+- curl: use .curlrc (with a dot) on Windows as well
   
-  The value of the maxPTDs parameter to PR_Init() has since at least
-  NSPR 2.1, which was released sometime in 1998, been marked ignored
-  as is accordingly not used in the initialization code.  Setting it
-  to a value when calling PR_Init() is thus benign, but indicates an
-  intent which may be misleading. Reset the value to zero to improve
-  clarity.
+  Fall-back to _curlrc if the dot-version is missing.
   
-  Closes https://github.com/curl/curl/pull/4054
-
-- [Daniel Gustafsson brought this change]
+  Co-Authored-By: Steve Holme
+  
+  Closes #4230
 
-  nss: only cache valid CRL entries
+- netrc: make the code try ".netrc" on Windows as well
   
-  Change the logic around such that we only keep CRLs that NSS actually
-  ended up caching around for later deletion.  If CERT_CacheCRL() fails
-  then there is little point in delaying the freeing of the CRL as it
-  is not used.
+  ... but fall back and try "_netrc" too if the dot version didn't work.
   
-  Closes https://github.com/curl/curl/pull/4053
-
-- [Gergely Nagy brought this change]
+  Co-Authored-By: Steve Holme
 
-  lib: Use UTF-8 encoding in comments
+- ngtcp2: use ngtcp2_version() to get the run-time version
   
-  Some editors and IDEs assume that source files use UTF-8 file encodings.
-  It also fixes the build with MSVC when /utf-8 command line option is
-  used (this option is mandatory for some other open-source projects, this
-  is useful when using the same options is desired for building all
-  libraries of a project).
+  ... which of course doesn't have to be the same used at build-time.
   
-  Closes https://github.com/curl/curl/pull/4087
-
-- [Caleb Raitto brought this change]
+  Function just recently merged in ngtcp2.
 
-  CURLOPT_HEADEROPT.3: Fix example
+- ngtcp2: move the h3 initing to immediately after the rx key
   
-  Fix an issue where example builds a curl_slist, but fails to actually
-  use it, or free it.
+  To fix a segfault and to better deal with 0-RTT
   
-  Closes https://github.com/curl/curl/pull/4090
+  Assisted-by: Tatsuhiro Tsujikawa
 
-- [Shankar Jadhavar brought this change]
+- [Alessandro Ghedini brought this change]
 
-  winbuild: Change Makefile to honor ENABLE_OPENSSL_AUTO_LOAD_CONFIG
+  quiche: register debug callback once and earlier
   
-  - Made changes so that ENABLE_OPENSSL_AUTO_LOAD_CONFIG will be honored.
+  The quiche debug callback is global and can only be initialized once, so
+  make sure we don't do it multiple times (e.g. if multiple requests are
+  executed).
   
-  - Also removed some ^M chars from file.
+  In addition this initializes the callback before the connection is
+  created, so we get logs for the handshake as well.
   
-  Prior to this change while building on Windows platform even if we pass
-  the ENABLE_OPENSSL_AUTO_LOAD_CONFIG option with value as "no" it does
-  not set the CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG flag.
+  Closes #4236
+
+- ssh: add a generic Curl_ssh_version function for SSH backends
   
-  Closes https://github.com/curl/curl/pull/4086
+  Closes #4235
 
-Daniel Stenberg (4 Jul 2019)
-- doh-url.d: added in 7.62.0
+- base64: check for SSH, not specific SSH backends
 
-Jay Satiro (30 Jun 2019)
-- docs: Fix links to OpenSSL docs
+- vssh: move ssh init/cleanup functions into backend code
+
+- vssh: create directory for SSH backend code
+
+- TODO/ROADMAP: remove "refuse downgrade redirects" and HTTP/3
   
-  OpenSSL changed their manual locations and does not redirect to the new
-  locations.
+  HTTP3 is now already in full progress
   
-  Bug: https://curl.haxx.se/mail/lib-2019-06/0056.html
-  Reported-by: Daniel Stenberg
+  Downgrade redirects can be achived almost exactly like that by setting
+  CURLOPT_REDIR_PROTOCOLS.
 
-Daniel Stenberg (26 Jun 2019)
-- [Gaël PORTAY brought this change]
+- RELEASE-NOTES: synced
 
-  curl_multi_wait.3: escape backslash in example
+- travis: add a quiche build
   
-  The backslash in the character Line Feed must be escaped.
+  Closes #4207
+
+- http: fix use of credentials from URL when using HTTP proxy
   
-  The current man-page outputs the code as following:
+  When a username and password are provided in the URL, they were wrongly
+  removed from the stored URL so that subsequent uses of the same URL
+  wouldn't find the crendentials. This made doing HTTP auth with multiple
+  connections (like Digest) mishave.
   
-          fprintf(stderr, "curl_multi failed, code %d.0, mc);
+  Regression from 46e164069d1a5230 (7.62.0)
   
-  The commit fixes it as follow:
+  Test case 335 added to verify.
   
-          fprintf(stderr, "curl_multi failed, code %d\n", mc);
+  Reported-by: Mike Crowe
   
-  Closes #4079
+  Fixes #4228
+  Closes #4229
 
-- openssl: disable engine if OPENSSL_NO_UI_CONSOLE is defined
+- [Mike Crowe brought this change]
+
+  tests: Replace outdated test case numbering documentation
   
-  ... since that needs UI_OpenSSL() which isn't provided when OpenSSL is
-  built with OPENSSL_NO_UI_CONSOLE which happens when OpenSSL is built for
-  UWP (with "VC-WIN32-UWP").
+  Tests are no longer grouped by numeric range[1]. Let's stop saying that
+  and provide some alternative advice for numbering tests.
   
-  Reported-by: Vasily Lobaskin
-  Fixes #4073
-  Closes #4077
+  [1] https://curl.haxx.se/mail/lib-2019-08/0043.html
+  
+  Closes #4227
 
-- test1521: adapt to SLISTPOINT
+- travis: reduce number of torture tests in 'coverage'
   
-  The header now has the slist-using options marked as SLISTPOINT so this
-  makes sure test 1521 understands that.
+  ... to make it complete in time. This cut seems not almost not affect
+  the coverage percentage and yet completes within 35 minutes on travis
+  where the previous runs recently always timed out after 50.
   
-  Follow-up to ae99b4de1c443ae989
+  Closes #4223
+
+- [Igor Makarov brought this change]
+
+  configure: use -lquiche to link to quiche
   
-  Closes #4074
+  Closes #4226
 
-- win32: make DLL loading a no-op for UWP
+- ngtcp2: provide the callbacks as a static struct
   
-  Reported-by: Michael Brehm
-  Fixes #4060
-  Closes #4072
+  ... instead of having them in quicsocket
 
-- [1ocalhost brought this change]
+- [Tatsuhiro Tsujikawa brought this change]
 
-  configure: fix typo '--disable-http-uath'
+  ngtcp2: add missing nghttp3_conn_add_write_offset call
   
-  Closes #4076
+  Closes #4225
 
-- [Niklas Hambüchen brought this change]
+- [Tatsuhiro Tsujikawa brought this change]
 
-  docs: fix string suggesting HTTP/2 is not the default
-  
-  Commit 25fd1057c9c86e3 made HTTP2 the default, and further down in the
-  man page that new default is mentioned, but the section at the top
-  contradicted it until now.
-  
-  Also remove claim that setting the HTTP version is not sensible.
-  
-  Closes #4075
+  ngtcp2: deal with stream close
 
-- RELEASE-NOTES: synced
+- [Tatsuhiro Tsujikawa brought this change]
 
-- [Stephan Szabo brought this change]
+  ngtcp2: Consume QUIC STREAM data properly
 
-  tests: update fixed IP for hostip/clientip split
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: don't reinitialize SSL on Retry
+
+- multi: getsock improvements for QUIC connecting
+
+- connect: connections are persistent by default for HTTP/3
+
+- quiche: happy eyeballs
   
-  These tests give differences for me on linux when using a hostip
-  pointing to the external ip address for the local machine.
+  Closes #4220
+
+- ngtcp2: do QUIC connections happy-eyeballs friendly
+
+- curl_version: bump string buffer size to 250
   
-  Closes #4070
+  With HTTP/3 libs and plenty TLS libs, I manged to hit the limit (which
+  causes a truncated output).
 
-Daniel Gustafsson (24 Jun 2019)
-- http: clarify header buffer size calculation
+- CURLOPT_ALTSVC.3: use a "" file name to not load from a file
+
+Jay Satiro (14 Aug 2019)
+- vauth: Use CURLE_AUTH_ERROR for auth function errors
   
-  The header buffer size calculation can from static analysis seem to
-  overlow as it performs an addition between two size_t variables and
-  stores the result in a size_t variable. Overflow is however guarded
-  against elsewhere since the input to the addition is regulated by
-  the maximum read buffer size. Clarify this with a comment since the
-  question was asked.
+  - Add new error code CURLE_AUTH_ERROR.
   
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Daniel Stenberg (24 Jun 2019)
-- KNOWN_BUGS: Don't clear digest for single realm
+  Prior to this change auth function errors were signaled by
+  CURLE_OUT_OF_MEMORY and CURLE_RECV_ERROR, and neither one was
+  technically correct.
   
-  Closes #3267
+  Ref: https://github.com/curl/curl/pull/3848
+  
+  Co-authored-by: Dominik Hölzl
+  
+  Closes https://github.com/curl/curl/pull/3864
 
-- KNOWN_BUGS: Schannel disable CURLOPT_SSL_VERIFYPEER and verify hostname
+Daniel Stenberg (13 Aug 2019)
+- curl_version_info: make the quic_version a const
   
-  Closes #3284
+  Follow-up from 1a2df1518ad8653f
+  
+  Closes #4222
 
-- http2: call done_sending on end of upload
+- examples: add http3.c, altsvc.c and http3-present.c
   
-  To make sure a HTTP/2 stream registers the end of stream.
+  Closes #4221
+
+Peter Wu (13 Aug 2019)
+- nss: use TLSv1.3 as default if supported
   
-  Bug #4043 made me find this problem but this fix doesn't correct the
-  reported issue.
+  SSL_VersionRangeGetDefault returns (TLSv1.0, TLSv1.2) as supported
+  range in NSS 3.45. It looks like the intention is to raise the minimum
+  version rather than lowering the maximum, so adjust accordingly. Note
+  that the caller (nss_setup_connect) initializes the version range to
+  (TLSv1.0, TLSv1.3), so there is no need to check for >= TLSv1.0 again.
   
-  Closes #4068
+  Closes #4187
+  Reviewed-by: Daniel Stenberg
+  Reviewed-by: Kamil Dudka
 
-- [James Brown brought this change]
+Daniel Stenberg (13 Aug 2019)
+- quic.h: remove unused proto
 
-  c-ares: honor port numbers in CURLOPT_DNS_SERVERS
+- curl_version_info.3: mentioned ALTSVC and HTTP3
   
-  By using ares_set_servers_ports_csv on new enough c-ares.
+  ... and sorted the list alphabetically
+
+- lib/quic.c: unused - removed
+
+- CURLOPT_ALTSVC_CTRL.3: remove CURLALTSVC_ALTUSED
   
-  Fixes #4066
-  Closes #4067
+  Follow-up to 98c3f148 that removed it from the header file
 
-Daniel Gustafsson (24 Jun 2019)
-- CURLMOPT_SOCKETFUNCTION.3: fix typo
+- [Junho Choi brought this change]
 
-Daniel Stenberg (24 Jun 2019)
-- [Koen Dergent brought this change]
+  docs/HTTP3: simplify quiche build instruction
+  
+  Use --recursive to get boringssl in one line
+  
+  Closes #4219
 
-  curl: skip CURLOPT_PROXY_CAPATH for disabled-proxy builds
+- altsvc: make it use h3-22 with ngtcp2 as well
+
+- ngtcp2: initial h3 request work
   
-  Closes #4061
+  Closes #4217
 
-- test153: fix content-length to avoid occasional hang
+- curl_version_info: offer quic (and h3) library info
   
-  Closes #4065
+  Closes #4216
+
+- HTTP3: use ngtcp2's draft-22 branch
 
 - RELEASE-NOTES: synced
 
-- multi: enable multiplexing by default (again)
-  
-  It was originally made default in d7c4213bd0c (7.62.0) but mistakenly
-  reverted in commit 2f44e94efb3d (7.65.0). Now enabled again.
+- CURLOPT_READFUNCTION.3: provide inline example
   
-  Closes #4051
+  ... instead of mentioning one in another place
 
-- typecheck: add 3 missing strings and a callback data pointer
-  
-  Closes #4050
+- [Tatsuhiro Tsujikawa brought this change]
 
-- tests: add disable-scan.pl to dist
+  ngtcp2: send HTTP/3 request with nghttp3
   
-  follow-up from 29177f422a5
+  This commit makes sending HTTP/3 request with nghttp3 work.  It
+  minimally receives HTTP response and calls nghttp3 callbacks, but no
+  processing is made at the moment.
   
-  Closes #4059
+  Closes #4215
 
-- http2: don't call stream-close on already closed streams
-  
-  Closes #4055
+- nghttp3: initial h3 template code added
 
-Marcel Raad (20 Jun 2019)
-- travis: enable alt-svc for coverage build
+- nghttp3: required when ngtcp2 is used for QUIC
   
-  Closes
+  - checked for by configure
+  - updated docs/HTTP3.md
+  - shown in the version string
+  
+  Closes #4210
 
-- travis: enable libssh2 for coverage build
+- [Eric Wong brought this change]
+
+  asyn-thread: issue CURL_POLL_REMOVE before closing socket
   
-  It was enabled by default before commit c92d2e14cfb.
+  This avoids EBADF errors from EPOLL_CTL_DEL operations in the
+  ephiperfifo.c example.  EBADF is dangerous in multi-threaded
+  applications where I rely on epoll_ctl to operate on the same
+  epoll description from different threads.
   
-  Disable torture tests 600 and 601 because of
-  https://github.com/curl/curl/issues/1678.
+  Follow-up to eb9a604f8d7db8
   
-  Closes
+  Bug: https://curl.haxx.se/mail/lib-2019-08/0026.html
+  Closes #4211
 
-- travis: disable threaded resolver for coverage build
+- [Carlo Marcelo Arenas Belón brought this change]
+
+  configure: avoid undefined check_for_ca_bundle
   
-  This enables more tests.
+  instead of using a "greater than 0" test, check for variable being
+  set, as it is always set to 1, and could be left unset if non of
+  OPENSSL MBEDTLS GNUTLS WOLFSSL is being configured for.
   
-  Closes
+  Closes #4213
 
-- travis: enable brotli for all xenial jobs
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: Send ALPN h3-22
   
-  There's no need for a separate job, and no need to build it from source
-  with Xenial.
+  Closes #4212
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: use ngtcp2_settings_default and specify initial_ts
+
+- curl_global_init_mem.3: mention it was added in 7.12.0
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: make the QUIC handshake work
   
-  Closes
+  Closes #4209
 
-- travis: enable warnings-as-errors for coverage build
+- [Alex Mayorga brought this change]
+
+  HTTP3.md: Update quiche build instructions
   
-  Closes
+  Added cloning for quiche and BoringSSL and modified the build
+  instructions so they work on a clean folder.
+  
+  Closes #4208
 
-GitHub (20 Jun 2019)
-- [Gisle Vanem brought this change]
+- CURLOPT_H3: removed
+  
+  There's no use for this anymore and it was never in a release.
+  
+  Closes #4206
 
-  system_win32: fix typo
+- http3: make connection reuse work
+  
+  Closes #4204
 
-Daniel Stenberg (20 Jun 2019)
-- typecheck: CURLOPT_CONNECT_TO takes an slist too
+- quiche: add SSLKEYLOGFILE support
+
+- cleanup: s/curl_debug/curl_dbg_debug in comments and docs
   
-  Additionally, add an alias in curl.h for slist-using options so that
-  we can grep/parse those out at will.
+  Leftovers from the function rename back in 76b63489495
   
-  Closes #4042
+  Reported-by: Gisle Vanem
+  Bug: https://github.com/curl/curl/commit/f3e0f071b14fcb46a453f69bdf4e062bcaacf362#com
+  mitcomment-34601751
+  
+  Closes #4203
 
-- [Stephan Szabo brought this change]
+- RELEASE-NOTES: synced
 
-  tests: support non-localhost HOSTIP for dict/smb servers
+- alt-svc: add protocol version selection masking
   
-  smbserver.py/dictserver.py were explicitly using localhost/127.0.0.1 for
-  binding the server which when we were running the tests with a separate
-  HOSTIP and CLIENTIP had failures verifying the server from the device we
-  were testing.
+  So that users can mask in/out specific HTTP versions when Alt-Svc is
+  used.
   
-  This changes them to take the address from runtests.py and default to
-  localhost/127.0.0.1 if none is given.
+   - Removed "h2c" and updated test case accordingly
+   - Changed how the altsvc struct is laid out
+   - Added ifdefs to make the unittest run even in a quiche-tree
   
-  Closes #4048
+  Closes #4201
 
-- test1523: basic test of CURLOPT_LOW_SPEED_LIMIT
+- http3: fix the HTTP/3 in the request, make alt-svc set right versions
+  
+  Closes #4200
 
-- configure: --disable-progress-meter
+- alt-svc: send Alt-Used: in redirected requests
   
-  Builds libcurl without support for the built-in progress meter.
+  RFC 7838 section 5:
   
-  Closes #4023
+     When using an alternative service, clients SHOULD include an Alt-Used
+     header field in all requests.
+  
+  Removed CURLALTSVC_ALTUSED again (feature is still EXPERIMENTAL thus
+  this is deemed ok).
+  
+  You can disable sending this header just like you disable any other HTTP
+  header in libcurl.
+  
+  Closes #4199
 
-- curl: improved skip-setopt-options when built with disabled features
+- CURLOPT_HTTP_VERSION: seting this to 3 forces HTTP/3 use directly
   
-  Reduces #ifdefs in src/tool_operate.c
+  Even though it cannot fall-back to a lower HTTP version automatically. The
+  safer way to upgrade remains via CURLOPT_ALTSVC.
   
-  Follow-up from 4e86f2fc4e6
-  Closes #3936
+  CURLOPT_H3 no longer has any bits that do anything and might be removed
+  before we remove the experimental label.
+  
+  Updated the curl tool accordingly to use "--http3".
+  
+  Closes #4197
 
-Steve Holme (18 Jun 2019)
-- netrc: Return the correct error code when out of memory
+- docs/ALTSVC: remove what works and the experimental explanation
   
-  Introduced in 763c5178.
+  Also, put the TODO items at the bottom.
   
-  Closes #4036
+  Closes #4198
 
-Daniel Stenberg (18 Jun 2019)
-- config-os400: add getpeername and getsockname defines
+- docs/EXPERIMENTAL: explain what it means and what's experimental now
+
+- curl: make use of CURLINFO_RETRY_AFTER when retrying
   
-  Reported-by: jonrumsey on github
-  Fixes #4037
-  Closes #4039
+  If a Retry-After: header was used in the response, that value overrides
+  other retry timing options.
+  
+  Fixes #3794
+  Closes #4195
 
-- runtests: keep logfiles around by default
+- curl: use CURLINFO_PROTOCOL to check for HTTP(s)
   
-  Make '-k' a no-op. The singletest function now clears the log directory
-  BEFORE each individual test and not after, which makes it possible to
-  always keep the logfiles around after a test has been run. No need to
-  specify -k anymore. Keeping the option parsing around to work with users
-  of old habits.
+  ... instead of CURLINFO_EFFECTIVE_URL to avoid string operations.
+
+- CURLINFO_RETRY_AFTER: parse the Retry-After header value
   
-  Some tests also didn't work properly when -k was used (since the old
-  logs would be kep when a new test starts) which this change also fixes.
+  This is only the libcurl part that provides the information. There's no
+  user of the parsed value. This change includes three new tests for the
+  parser.
   
-  Closes #4035
+  Ref: #3794
 
-- [Gergely Nagy brought this change]
+- docs/ALTSVC.md: first basic file format description
 
-  openssl: fix pubkey/signature algorithm detection in certinfo
+- curl: have -w's 'http_version' show '3' for HTTP/3
   
-  Certinfo gives the same result for all OpenSSL versions.
-  Also made printing RSA pubkeys consistent with older versions.
+  Closes #4196
+
+- curl.h: add CURL_HTTP_VERSION_3 to the version enum
   
-  Reported-by: Michael Wallner
-  Fixes #3706
-  Closes #4030
+  It can't be set for CURLOPT_HTTP_VERSION, but it can be extracted with
+  CURLINFO_HTTP_VERSION.
 
-- conn_maxage: move the check to prune_dead_connections()
+- quiche: make use of the connection timeout API properly
+
+- quiche: make POSTFIELDS posts work
+
+- quiche: improved error handling and memory cleanups
+
+- quiche: flush egress in h3_stream_recv() too
+
+- RELEASE-NOTES: synced
+
+Jay Satiro (6 Aug 2019)
+- [Patrick Monnerat brought this change]
+
+  os400: take care of CURLOPT_SASL_AUTHZID in curl_easy_setopt_ccsid().
   
-  ... and avoid the locking issue.
+  Ref: https://github.com/curl/curl/issues/3653
+  Ref: https://github.com/curl/curl/pull/3790
   
-  Reported-by: Kunal Ekawde
-  Fixes #4029
-  Closes #4032
+  NOTE: This commit was cherry-picked and is part of a series of commits
+  that added the authzid feature for upcoming 7.66.0. The series was
+  temporarily reverted in db8ec1f so that it would not ship in a 7.65.x
+  patch release.
+  
+  Closes https://github.com/curl/curl/pull/4186
 
-- tests: have runtests figure out disabled features
+- tests: Fix the line endings for the SASL alt-auth tests
   
-  ... so that runtests can skip individual test cases that test features
-  that are explicitly disabled in this build. This new logic is intended
-  for disabled features that aren't otherwise easily visible through the
-  curl_version_info() or other API calls.
+  - Change data and protocol sections to CRLF line endings.
   
-  tests/server/disabled is a newly built executable that will output a
-  list of disabled features. Outputs nothing for a default build.
+  Prior to this change the tests would fail or hang, which is because
+  certain sections such as protocol require CRLF line endings.
   
-  Closes #3950
-
-- test188/189: fix Content-Length
+  Follow-up to grandparent commit which added the tests.
   
-  This cures the flaky test results
+  Ref: https://github.com/curl/curl/issues/3653
+  Ref: https://github.com/curl/curl/pull/3790
   
-  Closes #4034
+  NOTE: This commit was cherry-picked and is part of a series of commits
+  that added the authzid feature for upcoming 7.66.0. The series was
+  temporarily reverted in db8ec1f so that it would not ship in a 7.65.x
+  patch release.
+  
+  Closes https://github.com/curl/curl/pull/4186
 
-- [Thomas Gamper brought this change]
+- [Steve Holme brought this change]
 
-  winbuild: use WITH_PREFIX if given
+  examples: Added SASL PLAIN authorisation identity (authzid) examples
   
-  Closes #4031
-
-Daniel Gustafsson (17 Jun 2019)
-- openssl: remove outdated comment
+  Ref: https://github.com/curl/curl/issues/3653
+  Ref: https://github.com/curl/curl/pull/3790
   
-  OpenSSL used to call exit(1) on syntax errors in OPENSSL_config(),
-  which is why we switched to CONF_modules_load_file() and introduced
-  a comment stating why. This behavior was however changed in OpenSSL
-  commit abdd677125f3a9e3082f8c5692203590fdb9b860, so remove the now
-  outdated and incorrect comment. The mentioned commit also declares
-  OPENSSL_config() deprecated so keep the current coding.
+  NOTE: This commit was cherry-picked and is part of a series of commits
+  that added the authzid feature for upcoming 7.66.0. The series was
+  temporarily reverted in db8ec1f so that it would not ship in a 7.65.x
+  patch release.
   
-  Closes #4033
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes https://github.com/curl/curl/pull/4186
 
-Daniel Stenberg (16 Jun 2019)
-- RELEASE-NOTES: synced
+- [Steve Holme brought this change]
 
-Patrick Monnerat (16 Jun 2019)
-- os400: make vsetopt() non-static as Curl_vsetopt() for os400 support.
+  curl: --sasl-authzid added to support CURLOPT_SASL_AUTHZID from the tool
   
-  Use it in curl_easy_setopt_ccsid().
+  Ref: https://github.com/curl/curl/issues/3653
+  Ref: https://github.com/curl/curl/pull/3790
   
-  Reported-by: jonrumsey on github
-  Fixes #3833
-  Closes #4028
+  NOTE: This commit was cherry-picked and is part of a series of commits
+  that added the authzid feature for upcoming 7.66.0. The series was
+  temporarily reverted in db8ec1f so that it would not ship in a 7.65.x
+  patch release.
+  
+  Closes https://github.com/curl/curl/pull/4186
 
-Daniel Stenberg (15 Jun 2019)
-- runtests: report single test time + total duration
+- [Steve Holme brought this change]
+
+  sasl: Implement SASL authorisation identity via CURLOPT_SASL_AUTHZID
   
-  ... after each successful test.
+  Added the ability for the calling program to specify the authorisation
+  identity (authzid), the identity to act as, in addition to the
+  authentication identity (authcid) and password when using SASL PLAIN
+  authentication.
   
-  Closes #4027
-
-- multi: fix the transfer hash function
+  Fixes #3653
+  Closes #3790
   
-  Follow-up from 8b987cc7eb
+  NOTE: This commit was cherry-picked and is part of a series of commits
+  that added the authzid feature for upcoming 7.66.0. The series was
+  temporarily reverted in db8ec1f so that it would not ship in a 7.65.x
+  patch release.
   
-  Reported-by: Tom van der Woerdt
-  Fixes #4018
-  Closes #4024
+  Closes https://github.com/curl/curl/pull/4186
 
-- unit1654: cleanup on memory failure
-  
-  ... to make it handle torture tests properly.
+Daniel Stenberg (6 Aug 2019)
+- docs/HTTP3: refreshed as it is now in master and HTTP/3 can be tested
+
+- [Yiming Jing brought this change]
+
+  mesalink: implement client authentication
   
-  Reported-by: Marcel Raad
-  Fixes #4021
-  Closes #4022
+  Closes #4184
 
-Marcel Raad (13 Jun 2019)
-- krb5: fix compiler warning
+- curl_multi_poll: a sister to curl_multi_wait() that waits more
   
-  Even though the variable was used in a DEBUGASSERT, GCC 8 warned in
-  debug mode:
-  krb5.c:324:17: error: unused variable 'maj' [-Werror=unused-variable]
+  Repeatedly we see problems where using curl_multi_wait() is difficult or
+  just awkward because if it has no file descriptor to wait for
+  internally, it returns immediately and leaves it to the caller to wait
+  for a small amount of time in order to avoid occasional busy-looping.
   
-  Just suppress the warning and declare the variable unconditionally
-  instead of only for DEBUGBUILD (which also missed the check for
-  HAVE_ASSERT_H).
+  This is often missed or misunderstood, leading to underperforming
+  applications.
   
-  Closes https://github.com/curl/curl/pull/4020
+  This change introduces curl_multi_poll() as a replacement drop-in
+  function that accepts the exact same set of arguments. This function
+  works identically to curl_multi_wait() - EXCEPT - for the case when
+  there's nothing to wait for internally, as then this function will by
+  itself wait for a "suitable" short time before it returns. This
+  effectiely avoids all risks of busy-looping and should also make it less
+  likely that apps "over-wait".
+  
+  This also changes the curl tool to use this funtion internally when
+  doing parallel transfers and changes curl_easy_perform() to use it
+  internally.
+  
+  Closes #4163
 
-Daniel Stenberg (13 Jun 2019)
-- quote.d: asterisk prefix works for SFTP as well
+- quiche:h3_stream_recv return 0 at end of stream
   
-  Reported-by: Ben Voris
-  Fixes #4017
-  Closes #4019
+  ... and remove some verbose messages we don't need. Made transfers from
+  facebook.com work better.
 
-- multi: fix the transfer hashes in the socket hash entries
+- altsvc: make quiche use h3-22 now
+
+- quiche: show the actual version number
+
+- quiche: first working HTTP/3 request
   
-  - The transfer hashes weren't using the correct keys so removing entries
-    failed.
+   - enable debug log
+   - fix use of quiche API
+   - use download buffer
+   - separate header/body
   
-  - Simplified the iteration logic over transfers sharing the same socket and
-    they now simply are set to expire and thus get handled in the "regular"
-    timer loop instead.
+  Closes #4193
+
+- http09: disable HTTP/0.9 by default in both tool and library
   
-  Reported-by: Tom van der Woerdt
-  Fixes #4012
-  Closes #4014
+  As the plan has been laid out in DEPRECATED. Update docs accordingly and
+  verify in test 1174. Now requires the option to be set to allow HTTP/0.9
+  responses.
+  
+  Closes #4191
 
-Jay Satiro (12 Jun 2019)
-- [Cliff Crosland brought this change]
+- quiche: initial h3 request send/receive
 
-  url: Fix CURLOPT_MAXAGE_CONN time comparison
+- lib/Makefile.am: make checksrc run in vquic too
+
+- altsvc: fix removal of expired cache entry
   
-  Old connections are meant to expire from the connection cache after
-  CURLOPT_MAXAGE_CONN seconds. However, they actually expire after 1000x
-  that value. This occurs because a time value measured in milliseconds is
-  accidentally divided by 1M instead of by 1,000.
+  Closes #4192
+
+- RELEASE-NOTES: synced
+
+Steve Holme (4 Aug 2019)
+- md4: Use our own MD4 implementation when no crypto libraries are available
   
-  Closes https://github.com/curl/curl/pull/4013
+  Closes #3780
 
-Daniel Stenberg (11 Jun 2019)
-- test1165: verify that CURL_DISABLE_ symbols are in sync
+- md4: No need to include Curl_md4.h for each TLS library
+
+- md4: No need for the NTLM code to call Curl_md4it() for each TLS library
   
-  between configure.ac and source code. They should be possible to switch
-  on/off in configure AND be used in source code.
+  As the NTLM code no longer calls any of TLS libraries' specific MD4
+  functions, there is no need to call this function for each #ifdef.
 
-- configure: remove CURL_DISABLE_TLS_SRP
+- md4: Move the mbed TLS MD4 implementation out of the NTLM code
+
+- md4: Move the WinCrypt implementation out of the NTLM code
+
+- md4: Move the SecureTransport implementation out of the NTLM code
+
+- md4: Use the Curl_md4it() function for OpenSSL based NTLM
+
+- md4: Move the GNU TLS gcrypt MD4 implementation out of the NTLM code
+
+- md4: Move the GNU TLS Nettle MD4 implementation out of the NTLM code
+
+Jay Satiro (4 Aug 2019)
+- OS400: Add CURLOPT_H3 symbols
   
-  It isn't used by code so stop providing the define.
+  Follow-up to 3af0e76 which added experimental H3 support.
   
-  Closes #4010
+  Closes https://github.com/curl/curl/pull/4185
 
-- Revert "cmake: add SMB to list of disabled protocols if HTTP_ONLY is specified"
+Daniel Stenberg (3 Aug 2019)
+- url: make use of new HTTP version if alt-svc has one
+
+- url: set conn->transport to default TCP at init time
+
+- altsvc: with quiche, use the quiche h3 alpn string
   
-  This reverts commit 36738caeb78603ce24e3ea089a167b8c216fb938.
+  Closes #4183
+
+- alt-svc: more liberal ALPN name parsing
   
-  Apparently several of the appveyor windows builds broke.
+  Allow pretty much anything to be part of the ALPN identifier. In
+  particular minus, which is used for "h3-20" (in-progress HTTP/3
+  versions) etc.
+  
+  Updated test 356.
+  Closes #4182
 
-- [sergey-raevskiy brought this change]
+- quiche: use the proper HTTP/3 ALPN
 
-  cmake: add SMB to list of disabled protocols if HTTP_ONLY is specified
+- quiche: add failf() calls for two error cases
   
-  Reviewed-by: Jakub Zakrzewski
-  Closes #3770
+  To aid debugging
+  
+  Closes #4181
 
-- RELEASE-NOTES: synced
+- mailmap: added Kyohei Kadota
 
-- http2: remove CURL_DISABLE_TYPECHECK define
+Kamil Dudka (1 Aug 2019)
+- http_negotiate: improve handling of gss_init_sec_context() failures
   
-  ... in http2-less builds as it served no use.
-
-- configure: more --disable switches to toggle off individual features
+  If HTTPAUTH_GSSNEGOTIATE was used for a POST request and
+  gss_init_sec_context() failed, the POST request was sent
+  with empty body.  This commit also restores the original
+  behavior of `curl --fail --negotiate`, which was changed
+  by commit 6c6035532383e300c712e4c1cd9fdd749ed5cf59.
   
-  ... actual support in the code for disabling these has already landed.
+  Add regression tests 2077 and 2078 to cover this.
   
-  Closes #4009
+  Fixes #3992
+  Closes #4171
 
-- wolfssl: fix key pinning build error
+Daniel Stenberg (1 Aug 2019)
+- mailmap: added 4 more names
   
-  follow-up from deb9462ff2de8
+  Evgeny Grin, Peter Pih, Anton Malov and Marquis de Muesli
 
-- CURLMOPT_SOCKETFUNCTION.3: clarified
+- mailmap: add Giorgos Oikonomou
+
+- src/makefile: fix uncompressed hugehelp.c generation
   
-  Moved away the callback explanation from curl_multi_socket_action.3 and
-  expanded it somewhat.
+  Regression from 5cf5d57ab9 (7.64.1)
   
-  Closes #4006
+  Fixed-by: Lance Ware
+  Fixes #4176
+  Closes #4177
 
-- wolfssl: fixup for SNI use
+- appveyor: pass on -k to make
+
+- timediff: make it 64 bit (if possible) even with 32 bit time_t
   
-  follow-up from deb9462ff2de8
+  ... to make it hold microseconds too.
   
-  Closes #4007
+  Fixes #4165
+  Closes #4168
 
-- CURLOPT_CAINFO.3: polished wording
-  
-  Clarify the functionality when built to use Schannel and Secure
-  Transport and stop calling it the "recommended" or "preferred" way and
-  instead rather call it the default.
+- ROADMAP: parallel transfers are merged now
+
+- getenv: support up to 4K environment variable contents on windows
   
-  Removed the reference to the ssl comparison table as it isn't necessary.
+  Reported-by: Michal Čaplygin
+  Fixes #4174
+  Closes #4175
+
+- [Kyohei Kadota brought this change]
+
+  plan9: add support for running on Plan 9
   
-  Reported-by: Richard Alcock
-  Bug: https://curl.haxx.se/mail/lib-2019-06/0019.html
-  Closes #4005
+  Closes #3701
 
-GitHub (10 Jun 2019)
-- [Daniel Stenberg brought this change]
+- [Kyohei Kadota brought this change]
 
-  SECURITY.md: created
+  ntlm: explicit type casting
+
+- [Justin brought this change]
+
+  curl.h: fix outdated comment
   
-  Brief security policy description for use/display on github.
+  Closes #4167
 
-Daniel Gustafsson (10 Jun 2019)
-- tool_cb_prg: Fix integer overflow in progress bar
+- curl: remove outdated comment
   
-  Commit 61faa0b420c236480bc9ef6fd52b4ecc1e0f8d17 fixed the progress bar
-  width calculation to avoid integer overflow, but failed to account for
-  the fact that initial_size is initialized to -1 when the file size is
-  retrieved from the remote on an upload, causing another signed integer
-  overflow.  Fix by separately checking for this case before the width
-  calculation.
+  Turned bad with commit b8894085000
   
-  Closes #3984
-  Reported-by: Brian Carpenter (Geeknik Labs)
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: niallor on github
+  Fixes #4172
+  Closes #4173
 
-Daniel Stenberg (10 Jun 2019)
-- wolfssl: refer to it as wolfSSL only
+- cleanup: remove the 'numsocks' argument used in many places
   
-  Remove support for, references to and use of "cyaSSL" from the source
-  and docs. wolfSSL is the current name and there's no point in keeping
-  references to ancient history.
+  It was used (intended) to pass in the size of the 'socks' array that is
+  also passed to these functions, but was rarely actually checked/used and
+  the array is defined to a fixed size of MAX_SOCKSPEREASYHANDLE entries
+  that should be used instead.
   
-  Assisted-by: Daniel Gustafsson
+  Closes #4169
+
+- readwrite_data: repair setting the TIMER_STARTTRANSFER stamp
   
-  Closes #3903
+  Regression, broken in commit 65eb65fde64bd5f (curl 7.64.1)
+  
+  Reported-by: Jonathan Cardoso Machado
+  Assisted-by: Jay Satiro
+  
+  Fixes #4136
+  Closes #4162
+
+- mailmap: Amit Katyal
+
+- asyn-thread: removed unused variable
+  
+  Follow-up to eb9a604f. Mistake caused by me when I edited the commit
+  before push...
 
 - RELEASE-NOTES: synced
 
-- bindlocal: detect and avoid IP version mismatches in bind()
+- [Amit Katyal brought this change]
+
+  asyn-thread: create a socketpair to wait on
   
-  Reported-by: Alex Grebenschikov
-  Fixes #3993
-  Closes #4002
+  Closes #4157
 
-- multi: make sure 'data' can present in several sockhash entries
+- curl: cap the maximum allowed values for retry time arguments
   
-  Since more than one socket can be used by each transfer at a given time,
-  each sockhash entry how has its own hash table with transfers using that
-  socket.
+  ... to avoid integer overflows later when multiplying with 1000 to
+  convert seconds to milliseconds.
   
-  In addition, the sockhash entry can now be marked 'blocked = TRUE'"
-  which then makes the delete function just set 'removed = TRUE' instead
-  of removing it "for real", as a way to not rip out the carpet under the
-  feet of a parent function that iterates over the transfers of that same
-  sockhash entry.
+  Added test 1269 to verify.
   
-  Reported-by: Tom van der Woerdt
-  Fixes #3961
-  Fixes #3986
-  Fixes #3995
-  Fixes #4004
-  Closes #3997
-
-- [Sorcus brought this change]
+  Reported-by: Jason Lee
+  Closes #4166
 
-  libcurl-tutorial.3: Fix small typo (mutipart -> multipart)
+- progress: reset download/uploaded counter
   
-  Fixed-by: MrSorcus on github
-  Closes #4000
+  ... to make CURLOPT_MAX_RECV_SPEED_LARGE and
+  CURLOPT_MAX_SEND_SPEED_LARGE work correctly on subsequent transfers that
+  reuse the same handle.
+  
+  Fixed-by: Ironbars13 on github
+  Fixes #4084
+  Closes #4161
 
-- unpause: trigger a timeout for event-based transfers
+- http2_recv: trigger another read when the last data is returned
   
-  ... so that timeouts or other state machine actions get going again
-  after a changing pause state. For example, if the last delivery was
-  paused there's no pending socket activity.
+  ... so that end-of-stream is detected properly.
   
-  Reported-by: sstruchtrup on github
-  Fixes #3994
-  Closes #4001
+  Reported-by: Tom van der Woerdt
+  Fixes #4043
+  Closes #4160
 
-Marcel Raad (9 Jun 2019)
-- travis: use xenial LLVM package for scan-build
+- curl: avoid uncessary libcurl timeouts (in parallel mode)
   
-  I missed that in commit 99a49d6.
-
-- travis: update scan-build job to xenial
+  When curl_multi_wait() returns OK without file descriptors to wait for,
+  it might already have done a long timeout.
   
-  Closes https://github.com/curl/curl/pull/3999
+  Closes #4159
 
-Daniel Stenberg (8 Jun 2019)
-- bump: start working on 7.65.2
+- [Balazs Kovacsics brought this change]
 
-Marcel Raad (5 Jun 2019)
-- examples/htmltitle: use C++ casts between pointer types
+  HTTP: use chunked Transfer-Encoding for HTTP_POST if size unknown
   
-  Compilers and static analyzers warn about using C-style casts here.
+  If using the read callback for HTTP_POST, and POSTFIELDSIZE is not set,
+  automatically add a Transfer-Encoding: chunked header, same as it is
+  already done for HTTP_PUT, HTTP_POST_FORM and HTTP_POST_MIME.  Update
+  test 1514 according to the new behaviour.
   
-  Closes https://github.com/curl/curl/pull/3975
+  Closes #4138
 
-- examples/fopen: fix comparison
+Jay Satiro (29 Jul 2019)
+- [Daniel Stenberg brought this change]
+
+  winbuild: add vquic to list of build directories
   
-  As want is size_t, (file->buffer_pos - want) is unsigned, so checking
-  if it's less than zero makes no sense.
-  Check if file->buffer_pos is less than want instead to avoid the
-  unsigned integer wraparound.
+  This fixes the winbuild build method which broke several days ago
+  when experimental quic support was added in 3af0e76.
   
-  Closes https://github.com/curl/curl/pull/3975
+  Reported-by: Michael Lee
+  
+  Fixes https://github.com/curl/curl/issues/4158
 
-- build: fix Codacy warnings
+- easy: resize receive buffer on easy handle reset
   
-  Reduce variable scopes and remove redundant variable stores.
+  - In curl_easy_reset attempt to resize the receive buffer to its default
+    size. If realloc fails then continue using the previous size.
   
-  Closes https://github.com/curl/curl/pull/3975
-
-- sws: remove unused variables
+  Prior to this change curl_easy_reset did not properly handle resetting
+  the receive buffer (data->state.buffer). It reset the variable holding
+  its size (data->set.buffer_size) to the default size (READBUFFER_SIZE)
+  but then did not actually resize the buffer. If a user resized the
+  buffer by using CURLOPT_BUFFERSIZE to set the size smaller than the
+  default, later called curl_easy_reset and attempted to reuse the handle
+  then a heap overflow would very likely occur during that handle's next
+  transfer.
   
-  Unused since commit 2f44e94.
+  Reported-by: Felix Hädicke
   
-  Closes https://github.com/curl/curl/pull/3975
-
-Version 7.65.1 (4 Jun 2019)
-
-Daniel Stenberg (4 Jun 2019)
-- RELEASE-NOTES: 7.65.1
-
-- THANKS: new contributors from 7.65.1
+  Fixes https://github.com/curl/curl/issues/4143
+  Closes https://github.com/curl/curl/pull/4145
 
-Steve Holme (4 Jun 2019)
-- [Frank Gevaerts brought this change]
+- [Brad Spencer brought this change]
 
-  ssl: Update outdated "openssl-only" comments for supported backends
+  examples: Avoid reserved names in hiperfifo examples
   
-  These are for features that used to be openssl-only but were expanded
-  over time to support other SSL backends.
+  - Trade in __attribute__((unused)) for the classic (void)x to silence
+    unused symbols.
   
-  Closes #3985
-
-Daniel Stenberg (4 Jun 2019)
-- curl_share_setopt.3: improve wording [ci ship]
+  Because the classic way is not gcc specific. Also because the prior
+  method mapped to symbol _Unused, which starts with _ and a capital
+  letter which is reserved.
   
-  Reported-by: Carlos ORyan
-
-Steve Holme (4 Jun 2019)
-- tool_parsecfg: Use correct return type for GetModuleFileName()
+  Assisted-by: The Infinnovation team
   
-  GetModuleFileName() returns a DWORD which is a typedef of an unsigned
-  long and not an int.
+  Bug: https://github.com/curl/curl/issues/4120#issuecomment-512542108
   
-  Closes #3980
+  Closes https://github.com/curl/curl/pull/4153
 
-Daniel Stenberg (3 Jun 2019)
-- TODO: "at least N milliseconds between requests" [ci skip]
-  
-  Suggested-by: dkwolfe4 on github
-  Closes #3920
+Daniel Stenberg (25 Jul 2019)
+- RELEASE-NOTES: synced
 
-Steve Holme (2 Jun 2019)
-- tests/server/.gitignore: Add socksd to the ignore list
-  
-  Missed in 04fd6755.
-  
-  Closes #3978
+- [Felix Hädicke brought this change]
 
-- tool_parsecfg: Fix control flow issue (DEADCODE)
+  ssh-libssh: do not specify O_APPEND when not in append mode
   
-  Follow-up to 8144ba38.
+  Specifying O_APPEND in conjunction with O_TRUNC and O_CREAT does not
+  make much sense. And this combination of flags is not accepted by all
+  SFTP servers (at least not Apache SSHD).
   
-  Detected by Coverity CID 1445663
-  Closes #3976
+  Fixes #4147
+  Closes #4148
 
-Daniel Stenberg (2 Jun 2019)
-- [Sergey Ogryzkov brought this change]
+- [Gergely Nagy brought this change]
 
-  NTLM: reset proxy "multipass" state when CONNECT request is done
+  multi: call detach_connection before Curl_disconnect
   
-  Closes #3972
-
-- test334: verify HTTP 204 response with chunked coding header
+  Curl_disconnect bails out if conn->easyq is not empty, detach_connection
+  needs to be called first to remove the current easy from the queue.
   
-  Verifies that a bodyless response don't parse this content-related
-  header.
-
-- [Michael Kaufmann brought this change]
+  Fixes #4144
+  Closes #4151
 
-  http: don't parse body-related headers bodyless responses
-  
-  Responses with status codes 1xx, 204 or 304 don't have a response body. For
-  these, don't parse these headers:
+Jay Satiro (23 Jul 2019)
+- tool_operate: fix implicit call to easysrc_cleanup
   
-  - Content-Encoding
-  - Content-Length
-  - Content-Range
-  - Last-Modified
-  - Transfer-Encoding
+  easysrc_cleanup is only defined when CURL_DISABLE_LIBCURL_OPTION is not
+  defined, and prior to this change would be called regardless.
   
-  This change ensures that HTTP/2 upgrades work even if a
-  "Content-Length: 0" or a "Transfer-Encoding: chunked" header is present.
+  Bug: https://github.com/curl/curl/pull/3804#issuecomment-513922637
+  Reported-by: Marcel Raad
   
-  Co-authored-by: Daniel Stenberg
-  Closes #3702
-  Fixes #3968
-  Closes #3977
+  Closes https://github.com/curl/curl/pull/4142
 
-- tls13-docs: mention it is only for OpenSSL >= 1.1.1
+Daniel Stenberg (22 Jul 2019)
+- curl:create_transfers check return code from curl_easy_setopt
   
-  Reported-by: Jay Satiro
-  Co-authored-by: Jay Satiro
-  Fixes #3938
-  Closes #3946
+  From commit b8894085
+  
+  Pointed out by Coverity CID 1451703
+  
+  Closes #4134
 
-- dump-header.d: spell out that no headers == empty file [ci skip]
+- HTTP3: initial (experimental) support
   
-  Reported-by: wesinator at github
-  Fixes #3964
-  Closes #3974
+  USe configure --with-ngtcp2 or --with-quiche
+  
+  Using either option will enable a HTTP3 build.
+  Co-authored-by: Alessandro Ghedini <alessandro@ghedini.me>
+  
+  Closes #3500
 
-- singlesocket: use separate variable for inner loop
+- curl: remove dead code
   
-  An inner loop within the singlesocket() function wrongly re-used the
-  variable for the outer loop which then could cause an infinite
-  loop. Change to using a separate variable!
+  The loop never loops (since b889408500), pointed out by Coverity (CID
+  1451702)
   
-  Reported-by: Eric Wu
-  Fixes #3970
-  Closes #3973
+  Closes #4133
 
-- RELEASE-NOTES: synced
+- docs/PARALLEL-TRANSFERS: correct the version number
 
-- [Josie Huddleston brought this change]
+- docs/PARALLEL-TRANSFERS: added
 
-  http2: Stop drain from being permanently set on
+- curl: support parallel transfers
   
-  Various functions called within Curl_http2_done() can have the
-  side-effect of setting the Easy connection into drain mode (by calling
-  drain_this()).  However, the last time we unset this for a transfer (by
-  calling drained_transfer()) is at the beginning of Curl_http2_done().
-  If the Curl_easy is reused for another transfer, it is then stuck in
-  drain mode permanently, which in practice makes it unable to write any
-  data in the new transfer.
+  This is done by making sure each individual transfer is first added to a
+  linked list as then they can be performed serially, or at will, in
+  parallel.
   
-  This fix moves the last call to drained_transfer() to later in
-  Curl_http2_done(), after the functions that could potentially call for a
-  drain.
+  Closes #3804
+
+- docs/MANUAL.md: converted to markdown from plain text
   
-  Fixes #3966
-  Closes #3967
-  Reported-by: Josie-H
+  ... will make it render as a nicer web page.
+  
+  Closes #4131
 
-Steve Holme (29 May 2019)
-- conncache: Remove the DEBUGASSERT on length check
+- curl_version_info: provide nghttp2 details
   
-  We trust the calling code as this is an internal function.
+  Introducing CURLVERSION_SIXTH with nghttp2 info.
   
-  Closes #3962
+  Closes #4121
 
-Jay Satiro (29 May 2019)
-- [Gisle Vanem brought this change]
+- bump: start working on 7.66.0
 
-  system_win32: fix function prototype
+- source: remove names from source comments
   
-  - Change if_nametoindex parameter type from char * to const char *.
+  Several reasons:
   
-  Follow-up to 09eef8af from this morning.
+  - we can't add everyone who's helping out so its unfair to just a few
+  selected ones.
+  - we already list all helpers in THANKS and in RELEASE-NOTES for each
+  release
+  - we don't want to give the impression that some parts of the code is
+  "owned" or "controlled" by specific persons
   
-  Bug: https://github.com/curl/curl/commit/09eef8af#r33716067
+  Assisted-by: Daniel Gustafsson
+  Closes #4129
 
-Marcel Raad (29 May 2019)
-- appveyor: add Visual Studio solution build
+Version 7.65.3 (19 Jul 2019)
+
+Daniel Stenberg (19 Jul 2019)
+- RELEASE-NOTES: 7.65.3
+
+- THANKS: 7.65.3 status
+
+- progress: make the progress meter appear again
   
-  Closes https://github.com/curl/curl/pull/3941
+  Fix regression caused by 21080e1
+  
+  Reported-by: Chih-Hsuan Yen
+  Fixes #4122
+  Closes #4124
 
-- appveyor: add support for other build systems
+- version: bump to 7.65.3
+
+- RELEASE-NOTES: Contributors or now 1990
+
+Version 7.65.2 (17 Jul 2019)
+
+Daniel Stenberg (17 Jul 2019)
+- RELEASE-NOTES: 7.65.2
+
+- THANKS: add contributors from 7.65.2
+
+Jay Satiro (17 Jul 2019)
+- [aasivov brought this change]
+
+  cmake: Fix finding Brotli on case-sensitive file systems
   
-  Introduce BUILD_SYSTEM variable, which is currently always CMake.
+  - Find package "Brotli" instead of "BROTLI" since the former is the
+    casing used for CMake/FindBrotli.cmake, and otherwise find_package
+    may fail on a case-sensitive file system.
   
-  Closes https://github.com/curl/curl/pull/3941
+  Fixes https://github.com/curl/curl/issues/4117
 
-Steve Holme (29 May 2019)
-- url: Load if_nametoindex() dynamically from iphlpapi.dll on Windows
+- CURLOPT_RANGE.3: Caution against using it for HTTP PUT
   
-  This fixes the static dependency on iphlpapi.lib and allows curl to
-  build for targets prior to Windows Vista.
+  AFAICT CURLOPT_RANGE does not support ranged HTTP PUT uploads so I've
+  cautioned against using it for that purpose and included a workaround.
   
-  This partially reverts 170bd047.
+  Bug: https://curl.haxx.se/mail/lib-2019-04/0075.html
+  Reported-by: Christopher Head
   
-  Fixes #3960
-  Closes #3958
+  Closes https://github.com/curl/curl/issues/3814
 
-Daniel Stenberg (29 May 2019)
-- http: fix "error: equality comparison with extraneous parentheses"
+- [Stefano Simonelli brought this change]
 
-- parse_proxy: make sure portptr is initialized
-  
-  Reported-by: Benbuck Nason
+  CURLOPT_SEEKDATA.3: fix variable name
   
-  fixes #3959
+  Closes https://github.com/curl/curl/pull/4118
 
-- url: default conn->port to the same as conn->remote_port
+- [Giorgos Oikonomou brought this change]
+
+  CIPHERS.md: Explain Schannel error SEC_E_ALGORITHM_MISMATCH
   
-  ... so that it has a sensible value when ConnectionExists() is called which
-  needs it set to differentiate host "bundles" correctly on port number!
+  If the SSL backend is Schannel and the user specifies an Schannel CALG_
+  that is not supported by the protocol or the server then curl returns
+  CURLE_SSL_CONNECT_ERROR (35) SEC_E_ALGORITHM_MISMATCH.
   
-  Also, make conncache:hashkey() use correct port for bundles that are proxy vs
-  host connections.
+  Fixes https://github.com/curl/curl/issues/3389
+  Closes https://github.com/curl/curl/pull/4106
+
+- [Daniel Gustafsson brought this change]
+
+  nss: inspect returnvalue of token check
   
-  Probably a regression from 7.62.0
+  PK11_IsPresent() checks for the token for the given slot is available,
+  and sets needlogin flags for the PK11_Authenticate() call.  Should it
+  return false, we should however treat it as an error and bail out.
   
-  Reported-by: Tom van der Woerdt
-  Fixes #3956
-  Closes #3957
+  Closes https://github.com/curl/curl/pull/4110
 
-- conncache: make "bundles" per host name when doing proxy tunnels
+- docs: Explain behavior change in --tlsv1. options since 7.54
   
-  Only HTTP proxy use where multiple host names can be used over the same
-  connection should use the proxy host name for bundles.
+  Since 7.54 --tlsv1. options use the specified version or later, however
+  older versions of curl documented it as using just the specified version
+  which may or may not have happened depending on the TLS library.
+  Document this discrepancy to allay confusion for users familiar with the
+  old documentation that expect just the specified version.
   
-  Reported-by: Tom van der Woerdt
-  Fixes #3951
-  Closes #3955
+  Fixes https://github.com/curl/curl/issues/4097
+  Closes https://github.com/curl/curl/pull/4119
 
-- multi: track users of a socket better
+- libcurl: Restrict redirect schemes (follow-up)
   
-  They need to be removed from the socket hash linked list with more care.
+  - Allow FTPS on redirect.
   
-  When sh_delentry() is called to remove a sockethash entry, remove all
-  individual transfers from the list first. To enable this, each Curl_easy struct
-  now stores a pointer to the sockethash entry to know how to remove itself.
+  - Update default allowed redirect protocols in documentation.
   
-  Reported-by: Tom van der Woerdt and Kunal Ekawde
+  Follow-up to 6080ea0.
   
-  Fixes #3952
-  Fixes #3904
-  Closes #3953
+  Ref: https://github.com/curl/curl/pull/4094
+  
+  Closes https://github.com/curl/curl/pull/4115
 
-Steve Holme (28 May 2019)
-- curl-win32.h: Enable Unix Domain Sockets based on the Windows SDK version
+Daniel Stenberg (16 Jul 2019)
+- test1173: make it also check all libcurl option man pages
   
-  Microsoft added support for Unix Domain Sockets in Windows 10 1803
-  (RS4). Rather than expect the user to enable Unix Domain Sockets by
-  uncommenting the #define that was added in 0fd6221f we use the RS4
-  pre-processor variable that is present in newer versions of the
-  Windows SDK.
-  
-  Closes #3939
-
-Daniel Stenberg (28 May 2019)
-- [Jonas Vautherin brought this change]
-
-  cmake: support CMAKE_OSX_ARCHITECTURES when detecting SIZEOF variables
+  ... and adjust those that cause errors
   
-  Closes #3945
+  Closes #4116
 
-Marcel Raad (27 May 2019)
-- HAProxy tests: add keywords
+- curl: only accept COLUMNS less than 10000
   
-  Add the proxy and haproxy keywords in order to be able to exclude or
-  run these specific tests.
+  ... as larger values would rather indicate something silly (and could
+  potentially cause buffer problems).
   
-  Closes https://github.com/curl/curl/pull/3949
-
-Daniel Stenberg (27 May 2019)
-- [Maksim Stsepanenka brought this change]
+  Reported-by: pendrek at hackerone
+  Closes #4114
 
-  tests: make test 1420 and 1406 work with rtsp-disabled libcurl
+- dist: add manpage-syntax.pl
   
-  Closes #3948
-
-Kamil Dudka (27 May 2019)
-- [Hubert Kario brought this change]
+  follow-up to 7fb66c403
 
-  nss: allow to specify TLS 1.3 ciphers if supported by NSS
+- test1173: detect some basic man page format mistakes
   
-  Closes #3916
-
-Daniel Stenberg (26 May 2019)
-- RELEASE-NOTES: synced
+  Triggered by PR #4111
+  
+  Closes #4113
 
-- [Jay Satiro brought this change]
+Jay Satiro (15 Jul 2019)
+- [Bjarni Ingi Gislason brought this change]
 
-  Revert all SASL authzid (new feature) commits
+  docs: Fix missing lines caused by undefined macros
   
-  - Revert all commits related to the SASL authzid feature since the next
-    release will be a patch release, 7.65.1.
+  - Escape apostrophes at line start.
   
-  Prior to this change CURLOPT_SASL_AUTHZID  / --sasl-authzid was destined
-  for the next release, assuming it would be a feature release 7.66.0.
-  However instead the next release will be a patch release, 7.65.1 and
-  will not contain any new features.
+  Some lines begin with a "'" (apostrophe, single quote), which is then
+  interpreted as a control character in *roff.
   
-  After the patch release after the reverted commits can be restored by
-  using cherry-pick:
+  Such lines are interpreted as being a call to a macro, and if
+  undefined, the lines are removed from the output.
   
-  git cherry-pick a14d72c a9499ff 8c1cc36 c2a8d52 0edf690
+  Bug: https://bugs.debian.org/926352
+  Signed-off-by: Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
   
-  Details for all reverted commits:
+  Submitted-by: Alessandro Ghedini
   
-  Revert "os400: take care of CURLOPT_SASL_AUTHZID in curl_easy_setopt_ccsid()."
+  Closes https://github.com/curl/curl/pull/4111
+
+Daniel Stenberg (14 Jul 2019)
+- libcurl-security.3: update to new CURLOPT_REDIR_PROTOCOLS defaults
   
-  This reverts commit 0edf6907ae37e2020722e6f61229d8ec64095b0a.
+  follow-up to 6080ea098
+
+- [Linos Giannopoulos brought this change]
+
+  libcurl: Add testcase for gopher redirects
   
-  Revert "tests: Fix the line endings for the SASL alt-auth tests"
+  The testcase ensures that redirects to CURLPROTO_GOPHER won't be
+  allowed, by default, in the future. Also, curl is being used
+  for convenience while keeping the testcases DRY.
   
-  This reverts commit c2a8d52a1356a722ff9f4aeb983cd4eaf80ef221.
+  The expected error code is CURLE_UNSUPPORTED_PROTOCOL when the client is
+  redirected to CURLPROTO_GOPHER
   
-  Revert "examples: Added SASL PLAIN authorisation identity (authzid) examples"
+  Signed-off-by: Linos Giannopoulos <lgian@skroutz.gr>
+
+- [Linos Giannopoulos brought this change]
+
+  libcurl: Restrict redirect schemes
   
-  This reverts commit 8c1cc369d0c7163c6dcc91fd38edfea1f509ae75.
+  All protocols except for CURLPROTO_FILE/CURLPROTO_SMB and their TLS
+  counterpart were allowed for redirect. This vastly broadens the
+  exploitation surface in case of a vulnerability such as SSRF [1], where
+  libcurl-based clients are forced to make requests to arbitrary hosts.
   
-  Revert "curl: --sasl-authzid added to support CURLOPT_SASL_AUTHZID from the tool"
+  For instance, CURLPROTO_GOPHER can be used to smuggle any TCP-based
+  protocol by URL-encoding a payload in the URI. Gopher will open a TCP
+  connection and send the payload.
   
-  This reverts commit a9499ff136d89987af885e2d7dff0a066a3e5817.
+  Only HTTP/HTTPS and FTP are allowed. All other protocols have to be
+  explicitly enabled for redirects through CURLOPT_REDIR_PROTOCOLS.
   
-  Revert "sasl: Implement SASL authorisation identity via CURLOPT_SASL_AUTHZID"
+  [1]: https://www.acunetix.com/blog/articles/server-side-request-forgery-vulnerability/
   
-  This reverts commit a14d72ca2fec5d4eb5a043936e4f7ce08015c177.
-
-- [dbrowndan brought this change]
-
-  FAQ: more minor updates and spelling fixes
+  Signed-off-by: Linos Giannopoulos <lgian@skroutz.gr>
   
-  Closes #3937
+  Closes #4094
 
-- RELEASE-NOTES: synced
+- [Zenju brought this change]
 
-- sectransp: handle errSSLPeerAuthCompleted from SSLRead()
+  openssl: define HAVE_SSL_GET_SHUTDOWN based on version number
   
-  Reported-by: smuellerDD on github
-  Fixes #3932
-  Closes #3933
-
-GitHub (24 May 2019)
-- [Gisle Vanem brought this change]
+  Closes #4100
 
-  Fix typo.
+- [Peter Simonyi brought this change]
 
-Daniel Stenberg (23 May 2019)
-- tool_setopt: for builds with disabled-proxy, skip all proxy setopts()
+  http: allow overriding timecond with custom header
   
-  Reported-by: Marcel Raad
-  Fixes #3926
-  Closes #3929
-
-Steve Holme (23 May 2019)
-- winbuild: Use two space indentation
+  With CURLOPT_TIMECONDITION set, a header is automatically added (e.g.
+  If-Modified-Since).  Allow this to be replaced or suppressed with
+  CURLOPT_HTTPHEADER.
   
-  Closes #3930
+  Fixes #4103
+  Closes #4109
 
-GitHub (23 May 2019)
-- [Gisle Vanem brought this change]
+Jay Satiro (11 Jul 2019)
+- [Juergen Hoetzel brought this change]
 
-  tool_parse_cfg: Avoid 2 fopen() for WIN32
+  smb: Use the correct error code for access denied on file open
   
-  Using the memdebug.h mem-leak feature, I noticed 2 calls like:
-    FILE tool_parsecfg.c:70 fopen("c:\Users\Gisle\AppData\Roaming\_curlrc","rt")
-    FILE tool_parsecfg.c:114 fopen("c:\Users\Gisle\AppData\Roaming\_curlrc","rt")
+  - Return CURLE_REMOTE_ACCESS_DENIED for SMB access denied on file open.
   
-  No need for 'fopen(), 'fclose()' and a 'fopen()' yet again.
-
-Daniel Stenberg (23 May 2019)
-- md4: include the mbedtls config.h to get the MD4 info
-
-- md4: build correctly with openssl without MD4
+  Prior to this change CURLE_REMOTE_FILE_NOT_FOUND was returned instead.
   
-  Reported-by: elsamuko at github
-  Fixes #3921
-  Closes #3922
+  Closes https://github.com/curl/curl/pull/4095
 
-Patrick Monnerat (23 May 2019)
-- os400: take care of CURLOPT_SASL_AUTHZID in curl_easy_setopt_ccsid().
+- [Daniel Gustafsson brought this change]
 
-Daniel Stenberg (23 May 2019)
-- .github/FUNDING: mention our opencollective "home" [ci skip]
+  DEPRECATE: fixup versions and spelling
+  
+  Correctly set the July 17 version to 7.65.2, and update spelling to
+  be consistent. Also fix a typo.
+  
+  Closes https://github.com/curl/curl/pull/4107
 
-Marcel Raad (23 May 2019)
-- [Zenju brought this change]
+- [Gisle Vanem brought this change]
 
-  config-win32: add support for if_nametoindex and getsockname
+  system_win32: fix clang warning
   
-  Closes https://github.com/curl/curl/pull/3923
+  - Declare variable in header as extern.
+  
+  Bug: https://github.com/curl/curl/commit/48b9ea4#commitcomment-34084597
 
-Jay Satiro (23 May 2019)
-- tests: Fix the line endings for the SASL alt-auth tests
+Daniel Gustafsson (10 Jul 2019)
+- headers: Remove no longer exported functions
   
-  - Change data and protocol sections to CRLF line endings.
+  There were a leftover few prototypes of Curl_ functions that we used to
+  export but no longer do, this removes those prototypes and cleans up any
+  comments still referring to them.
   
-  Prior to this change the tests would fail or hang, which is because
-  certain sections such as protocol require CRLF line endings.
+  Curl_write32_le(), Curl_strcpy_url(), Curl_strlen_url(), Curl_up_free()
+  Curl_concat_url(), Curl_detach_connnection(), Curl_http_setup_conn()
+  were made static in 05b100aee247bb9bec8e9a1b0166496aa4248d1c.
+  Curl_http_perhapsrewind() made static in 574aecee208f79d391f10d57520b3.
   
-  Follow-up to a9499ff from today which added the tests.
+  For the remainder, I didn't trawl the Git logs hard enough to capture
+  their exact time of deletion, but they were all gone: Curl_splayprint(),
+  Curl_http2_send_request(), Curl_global_host_cache_dtor(),
+  Curl_scan_cache_used(), Curl_hostcache_destroy(), Curl_second_connect(),
+  Curl_http_auth_stage() and Curl_close_connections().
   
-  Ref: https://github.com/curl/curl/pull/3790
+  Closes #4096
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Daniel Stenberg (23 May 2019)
-- url: fix bad #ifdef
+- CMake: fix typos and spelling
+
+- [Kyle Edwards brought this change]
+
+  CMake: Convert errant elseif() to else()
   
-  Regression since e91e48161235272ff485.
+  CMake interprets an elseif() with no arguments as elseif(FALSE),
+  resulting in the elseif() block not being executed. That is not what
+  was intended here. Change the empty elseif() to an else() as it was
+  intended.
   
-  Reported-by: Tom Greenslade
-  Fixes #3924
-  Closes #3925
+  Closes #4101
+  Reported-by: Artalus <artalus-mail@yandex.ru>
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-- Revert "progress: CURL_DISABLE_PROGRESS_METER"
+- buildconf: fix header filename
   
-  This reverts commit 3b06e68b7734cb10a555f9d7e804dd5d808236a4.
+  The header file inclusion had a typo, it should be .h and not .hd.
+  Fix by renaming.
   
-  Clearly this change wasn't good enough as it broke CURLOPT_LOW_SPEED_LIMIT +
-  CURLOPT_LOW_SPEED_TIME
+  Fixes #4102
+  Reported-by: AceCrow on Github
+
+- [Jan Chren brought this change]
+
+  configure: fix --disable-code-coverage
   
-  Reported-by: Dave Reisner
+  This fixes the case when --disable-code-coverage supplied to ./configure
+  would result in coverage="yes" being set.
   
-  Fixes #3927
-  Closes #3928
+  Closes #4099
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-Steve Holme (22 May 2019)
-- examples: Added SASL PLAIN authorisation identity (authzid) examples
+- cleanup: fix typo in comment
 
-- curl: --sasl-authzid added to support CURLOPT_SASL_AUTHZID from the tool
+- RELEASE-NOTES: synced
 
-- sasl: Implement SASL authorisation identity via CURLOPT_SASL_AUTHZID
+Jay Satiro (6 Jul 2019)
+- [Daniel Gustafsson brought this change]
+
+  nss: support using libnss on macOS
   
-  Added the ability for the calling program to specify the authorisation
-  identity (authzid), the identity to act as, in addition to the
-  authentication identity (authcid) and password when using SASL PLAIN
-  authentication.
-  
-  Fixed #3653
-  Closes #3790
-
-Marc Hoersken (22 May 2019)
-- tests: add support to test against OpenSSH for Windows
+  The file suffix for dynamically loadable objects on macOS is .dylib,
+  which need to be added for the module definitions in order to get the
+  NSS TLS backend to work properly on macOS.
   
-  Testing against OpenSSH for Windows requires v7.7.0.0 or newer
-  due to the use of AllowUsers and DenyUsers. For more info see:
-  https://github.com/PowerShell/Win32-OpenSSH/wiki/sshd_config
+  Closes https://github.com/curl/curl/pull/4046
 
-Daniel Stenberg (22 May 2019)
-- bump: start on the next release
+- [Daniel Gustafsson brought this change]
 
-Marcel Raad (22 May 2019)
-- examples: fix "clarify calculation precedence" warnings
+  nss: don't set unused parameter
   
-  Closes https://github.com/curl/curl/pull/3919
-
-- hiperfifo: remove unused variable
+  The value of the maxPTDs parameter to PR_Init() has since at least
+  NSPR 2.1, which was released sometime in 1998, been marked ignored
+  as is accordingly not used in the initialization code.  Setting it
+  to a value when calling PR_Init() is thus benign, but indicates an
+  intent which may be misleading. Reset the value to zero to improve
+  clarity.
   
-  Closes https://github.com/curl/curl/pull/3919
+  Closes https://github.com/curl/curl/pull/4054
 
-- examples: remove dead variable stores
-  
-  Closes https://github.com/curl/curl/pull/3919
+- [Daniel Gustafsson brought this change]
 
-- examples: reduce variable scopes
+  nss: only cache valid CRL entries
   
-  Closes https://github.com/curl/curl/pull/3919
-
-- http2-download: fix format specifier
+  Change the logic around such that we only keep CRLs that NSS actually
+  ended up caching around for later deletion.  If CERT_CacheCRL() fails
+  then there is little point in delaying the freeing of the CRL as it
+  is not used.
   
-  Closes https://github.com/curl/curl/pull/3919
+  Closes https://github.com/curl/curl/pull/4053
 
-Daniel Stenberg (22 May 2019)
-- PolarSSL: deprecate support step 1. Removed from configure.
-  
-  Also removed mentions from most docs.
+- [Gergely Nagy brought this change]
+
+  lib: Use UTF-8 encoding in comments
   
-  Discussed: https://curl.haxx.se/mail/lib-2019-05/0045.html
+  Some editors and IDEs assume that source files use UTF-8 file encodings.
+  It also fixes the build with MSVC when /utf-8 command line option is
+  used (this option is mandatory for some other open-source projects, this
+  is useful when using the same options is desired for building all
+  libraries of a project).
   
-  Closes #3888
+  Closes https://github.com/curl/curl/pull/4087
 
-- configure/cmake: check for if_nametoindex()
-  
-  - adds the check to cmake
+- [Caleb Raitto brought this change]
+
+  CURLOPT_HEADEROPT.3: Fix example
   
-  - fixes the configure check to work for cross-compiled windows builds
+  Fix an issue where example builds a curl_slist, but fails to actually
+  use it, or free it.
   
-  Closes #3917
+  Closes https://github.com/curl/curl/pull/4090
 
-- parse_proxy: use the IPv6 zone id if given
+- [Shankar Jadhavar brought this change]
+
+  winbuild: Change Makefile to honor ENABLE_OPENSSL_AUTO_LOAD_CONFIG
   
-  If the proxy string is given as an IPv6 numerical address with a zone
-  id, make sure to use that for the connect to the proxy.
+  - Made changes so that ENABLE_OPENSSL_AUTO_LOAD_CONFIG will be honored.
   
-  Reported-by: Edmond Yu
+  - Also removed some ^M chars from file.
   
-  Fixes #3482
-  Closes #3918
+  Prior to this change while building on Windows platform even if we pass
+  the ENABLE_OPENSSL_AUTO_LOAD_CONFIG option with value as "no" it does
+  not set the CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG flag.
+  
+  Closes https://github.com/curl/curl/pull/4086
 
-Version 7.65.0 (22 May 2019)
+Daniel Stenberg (4 Jul 2019)
+- doh-url.d: added in 7.62.0
 
-Daniel Stenberg (22 May 2019)
-- RELEASE-NOTES: 7.65.0 release
+Jay Satiro (30 Jun 2019)
+- docs: Fix links to OpenSSL docs
+  
+  OpenSSL changed their manual locations and does not redirect to the new
+  locations.
+  
+  Bug: https://curl.haxx.se/mail/lib-2019-06/0056.html
+  Reported-by: Daniel Stenberg
 
-- THANKS: from the 7.65.0 release-notes
+Daniel Stenberg (26 Jun 2019)
+- [Gaël PORTAY brought this change]
 
-- url: convert the zone id from a IPv6 URL to correct scope id
+  curl_multi_wait.3: escape backslash in example
   
-  Reported-by: GitYuanQu on github
-  Fixes #3902
-  Closes #3914
-
-- configure: detect getsockname and getpeername on windows too
+  The backslash in the character Line Feed must be escaped.
   
-  Made detection macros for these two functions in the same style as other
-  functions possibly in winsock in the hope this will work better to
-  detect these functions when cross-compiling for Windows.
+  The current man-page outputs the code as following:
   
-  Follow-up to e91e4816123
+          fprintf(stderr, "curl_multi failed, code %d.0, mc);
   
-  Fixes #3913
-  Closes #3915
-
-Marcel Raad (21 May 2019)
-- examples: remove unused variables
+  The commit fixes it as follow:
   
-  Fixes Codacy/CppCheck warnings.
+          fprintf(stderr, "curl_multi failed, code %d\n", mc);
   
-  Closes
+  Closes #4079
 
-Daniel Gustafsson (21 May 2019)
-- udpateconninfo: mark variable unused
+- openssl: disable engine if OPENSSL_NO_UI_CONSOLE is defined
   
-  When compiling without getpeername() or getsockname(), the sockfd
-  paramter to Curl_udpateconninfo() became unused after commit e91e481612
-  added ifdef guards.
+  ... since that needs UI_OpenSSL() which isn't provided when OpenSSL is
+  built with OPENSSL_NO_UI_CONSOLE which happens when OpenSSL is built for
+  UWP (with "VC-WIN32-UWP").
   
-  Closes #3910
-  Fixes https://curl.haxx.se/dev/log.cgi?id=20190520172441-32196
-  Reviewed-by: Marcel Raad, Daniel Stenberg
+  Reported-by: Vasily Lobaskin
+  Fixes #4073
+  Closes #4077
 
-- ftp: move ftp_ccc in under featureflag
+- test1521: adapt to SLISTPOINT
   
-  Commit e91e48161235272ff485ff32bd048c53af731f43 moved ftp_ccc in under
-  the FTP featureflag in the UserDefined struct, but vtls callsites were
-  still using it unprotected.
+  The header now has the slist-using options marked as SLISTPOINT so this
+  makes sure test 1521 understands that.
   
-  Closes #3912
-  Fixes: https://curl.haxx.se/dev/log.cgi?id=20190520044705-29865
-  Reviewed-by: Daniel Stenberg, Marcel Raad
+  Follow-up to ae99b4de1c443ae989
+  
+  Closes #4074
 
-Daniel Stenberg (20 May 2019)
-- curl: report error for "--no-" on non-boolean options
+- win32: make DLL loading a no-op for UWP
   
-  Reported-by: Olen Andoni
-  Fixes #3906
-  Closes #3907
+  Reported-by: Michael Brehm
+  Fixes #4060
+  Closes #4072
 
-- [Guy Poizat brought this change]
+- [1ocalhost brought this change]
 
-  mbedtls: enable use of EC keys
+  configure: fix typo '--disable-http-uath'
   
-  Closes #3892
+  Closes #4076
 
-- lib1560: add tests for parsing URL with too long scheme
+- [Niklas Hambüchen brought this change]
+
+  docs: fix string suggesting HTTP/2 is not the default
   
-  Ref: #3905
+  Commit 25fd1057c9c86e3 made HTTP2 the default, and further down in the
+  man page that new default is mentioned, but the section at the top
+  contradicted it until now.
+  
+  Also remove claim that setting the HTTP version is not sensible.
+  
+  Closes #4075
 
-- [Omar Ramadan brought this change]
+- RELEASE-NOTES: synced
 
-  urlapi: increase supported scheme length to 40 bytes
+- [Stephan Szabo brought this change]
+
+  tests: update fixed IP for hostip/clientip split
   
-  The longest currently registered URI scheme at IANA is 36 bytes long.
+  These tests give differences for me on linux when using a hostip
+  pointing to the external ip address for the local machine.
   
-  Closes #3905
-  Closes #3900
+  Closes #4070
 
-Marcel Raad (20 May 2019)
-- lib: reduce variable scopes
+Daniel Gustafsson (24 Jun 2019)
+- http: clarify header buffer size calculation
   
-  Fixes Codacy/CppCheck warnings.
+  The header buffer size calculation can from static analysis seem to
+  overlow as it performs an addition between two size_t variables and
+  stores the result in a size_t variable. Overflow is however guarded
+  against elsewhere since the input to the addition is regulated by
+  the maximum read buffer size. Clarify this with a comment since the
+  question was asked.
   
-  Closes https://github.com/curl/curl/pull/3872
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- tool_formparse: remove redundant assignment
+Daniel Stenberg (24 Jun 2019)
+- KNOWN_BUGS: Don't clear digest for single realm
   
-  Just initialize word_begin with the correct value.
+  Closes #3267
+
+- KNOWN_BUGS: Schannel disable CURLOPT_SSL_VERIFYPEER and verify hostname
   
-  Closes https://github.com/curl/curl/pull/3873
+  Closes #3284
 
-- ssh: move variable declaration to where it's used
+- http2: call done_sending on end of upload
   
-  This way, we need only one call to free.
+  To make sure a HTTP/2 stream registers the end of stream.
   
-  Closes https://github.com/curl/curl/pull/3873
+  Bug #4043 made me find this problem but this fix doesn't correct the
+  reported issue.
+  
+  Closes #4068
 
-- ssh-libssh: remove unused variable
+- [James Brown brought this change]
+
+  c-ares: honor port numbers in CURLOPT_DNS_SERVERS
   
-  sock was only used to be assigned to fd_read.
+  By using ares_set_servers_ports_csv on new enough c-ares.
   
-  Closes https://github.com/curl/curl/pull/3873
+  Fixes #4066
+  Closes #4067
 
-Daniel Stenberg (20 May 2019)
-- test332: verify the blksize fix
+Daniel Gustafsson (24 Jun 2019)
+- CURLMOPT_SOCKETFUNCTION.3: fix typo
 
-- tftp: use the current blksize for recvfrom()
+Daniel Stenberg (24 Jun 2019)
+- [Koen Dergent brought this change]
+
+  curl: skip CURLOPT_PROXY_CAPATH for disabled-proxy builds
   
-  bug: https://curl.haxx.se/docs/CVE-2019-5436.html
-  Reported-by: l00p3r on hackerone
-  CVE-2019-5436
+  Closes #4061
 
-Daniel Gustafsson (19 May 2019)
-- version: make ssl_version buffer match for multi_ssl
+- test153: fix content-length to avoid occasional hang
   
-  When running a multi TLS backend build the version string needs more
-  buffer space. Make the internal ssl_buffer stack buffer match the one
-  in Curl_multissl_version() to allow for the longer string. For single
-  TLS backend builds there is no use in extended to buffer. This is a
-  fallout from #3863 which fixes up the multi_ssl string generation to
-  avoid a buffer overflow when the buffer is too small.
-  
-  Closes #3875
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #4065
 
-Steve Holme (18 May 2019)
-- http_ntlm_wb: Handle auth for only a single request
-  
-  Currently when the server responds with 401 on NTLM authenticated
-  connection (re-used) we consider it to have failed.  However this is
-  legitimate and may happen when for example IIS is set configured to
-  'authPersistSingleRequest' or when the request goes thru a proxy (with
-  'via' header).
+- RELEASE-NOTES: synced
+
+- multi: enable multiplexing by default (again)
   
-  Implemented by imploying an additional state once a connection is
-  re-used to indicate that if we receive 401 we need to restart
-  authentication.
+  It was originally made default in d7c4213bd0c (7.62.0) but mistakenly
+  reverted in commit 2f44e94efb3d (7.65.0). Now enabled again.
   
-  Missed in fe6049f0.
+  Closes #4051
 
-- http_ntlm_wb: Cleanup handshake after clean NTLM failure
+- typecheck: add 3 missing strings and a callback data pointer
   
-  Missed in 50b87c4e.
+  Closes #4050
 
-- http_ntlm_wb: Return the correct error on receiving an empty auth message
+- tests: add disable-scan.pl to dist
   
-  Missed in fe20826b as it wasn't implemented in http.c in b4d6db83.
+  follow-up from 29177f422a5
   
-  Closes #3894
+  Closes #4059
 
-Daniel Stenberg (18 May 2019)
-- curl: make code work with protocol-disabled libcurl
+- http2: don't call stream-close on already closed streams
   
-  Closes #3844
-
-- libcurl: #ifdef away more code for disabled features/protocols
-
-- progress: CURL_DISABLE_PROGRESS_METER
-
-- hostip: CURL_DISABLE_SHUFFLE_DNS
-
-- netrc: CURL_DISABLE_NETRC
+  Closes #4055
 
-Viktor Szakats (16 May 2019)
-- docs: Markdown and misc improvements [ci skip]
+Marcel Raad (20 Jun 2019)
+- travis: enable alt-svc for coverage build
   
-  Approved-by: Daniel Stenberg
-  Closes #3896
+  Closes
 
-- docs/RELEASE-PROCEDURE: link to live iCalendar [ci skip]
+- travis: enable libssh2 for coverage build
   
-  Ref: https://github.com/curl/curl/commit/0af41b40b2c7bd379b2251cbe7cd618e21fa0ea1#commitcomment-33563135
-  Approved-by: Daniel Stenberg
-  Closes #3895
-
-Daniel Stenberg (16 May 2019)
-- travis: add an osx http-only build
+  It was enabled by default before commit c92d2e14cfb.
   
-  Closes #3887
+  Disable torture tests 600 and 601 because of
+  https://github.com/curl/curl/issues/1678.
+  
+  Closes
 
-- cleanup: remove FIXME and TODO comments
+- travis: disable threaded resolver for coverage build
   
-  They serve very little purpose and mostly just add noise. Most of them
-  have been around for a very long time. I read them all before removing
-  or rephrasing them.
+  This enables more tests.
   
-  Ref: #3876
-  Closes #3883
+  Closes
 
-- curl: don't set FTP options for FTP-disabled builds
+- travis: enable brotli for all xenial jobs
   
-  ... since libcurl has started to be totally unaware of options for
-  disabled protocols they now return error.
+  There's no need for a separate job, and no need to build it from source
+  with Xenial.
   
-  Bug: https://github.com/curl/curl/commit/c9c5304dd4747cbe75d2f24be85920d572fcb5b8#commitcomment-33533937
+  Closes
+
+- travis: enable warnings-as-errors for coverage build
   
-  Reported-by: Marcel Raad
-  Closes #3886
+  Closes
 
-Steve Holme (16 May 2019)
-- http_ntlm_wb: Move the type-2 message processing into a dedicated function
+GitHub (20 Jun 2019)
+- [Gisle Vanem brought this change]
+
+  system_win32: fix typo
+
+Daniel Stenberg (20 Jun 2019)
+- typecheck: CURLOPT_CONNECT_TO takes an slist too
   
-  This brings the code inline with the other HTTP authentication mechanisms.
+  Additionally, add an alias in curl.h for slist-using options so that
+  we can grep/parse those out at will.
   
-  Closes #3890
-
-Daniel Stenberg (15 May 2019)
-- RELEASE-NOTES: synced
+  Closes #4042
 
-- docs/RELEASE-PROCEDURE: updated coming releases dates [ci skip]
+- [Stephan Szabo brought this change]
 
-- CURLOPT_READFUNCTION.3: see also CURLOPT_UPLOAD_BUFFERSIZE [ci skip]
+  tests: support non-localhost HOSTIP for dict/smb servers
   
-  Reported-by: Roy Bellingan
-  Bug: #3885
+  smbserver.py/dictserver.py were explicitly using localhost/127.0.0.1 for
+  binding the server which when we were running the tests with a separate
+  HOSTIP and CLIENTIP had failures verifying the server from the device we
+  were testing.
+  
+  This changes them to take the address from runtests.py and default to
+  localhost/127.0.0.1 if none is given.
+  
+  Closes #4048
 
-- parse_proxy: use the URL parser API
+- test1523: basic test of CURLOPT_LOW_SPEED_LIMIT
+
+- configure: --disable-progress-meter
   
-  As we treat a given proxy as a URL we should use the unified URL parser
-  to extract the parts out of it.
+  Builds libcurl without support for the built-in progress meter.
   
-  Closes #3878
+  Closes #4023
 
-Steve Holme (15 May 2019)
-- http_negotiate: Move the Negotiate state out of the negotiatedata structure
+- curl: improved skip-setopt-options when built with disabled features
   
-  Given that this member variable is not used by the SASL based protocols
-  there is no need to have it here.
+  Reduces #ifdefs in src/tool_operate.c
   
-  Closes #3882
+  Follow-up from 4e86f2fc4e6
+  Closes #3936
 
-- http_ntlm: Move the NTLM state out of the ntlmdata structure
+Steve Holme (18 Jun 2019)
+- netrc: Return the correct error code when out of memory
   
-  Given that this member variable is not used by the SASL based protocols
-  there is no need to have it here.
+  Introduced in 763c5178.
+  
+  Closes #4036
 
-- url: Move the negotiate state type into a dedicated enum
+Daniel Stenberg (18 Jun 2019)
+- config-os400: add getpeername and getsockname defines
+  
+  Reported-by: jonrumsey on github
+  Fixes #4037
+  Closes #4039
 
-- url: Remove duplicate clean up of the winbind variables in conn_shutdown()
+- runtests: keep logfiles around by default
   
-  Given that Curl_disconnect() calls Curl_http_auth_cleanup_ntlm() prior
-  to calling conn_shutdown() and it in turn performs this, there is no
-  need to perform the same action in conn_shutdown().
+  Make '-k' a no-op. The singletest function now clears the log directory
+  BEFORE each individual test and not after, which makes it possible to
+  always keep the logfiles around after a test has been run. No need to
+  specify -k anymore. Keeping the option parsing around to work with users
+  of old habits.
   
-  Closes #3881
+  Some tests also didn't work properly when -k was used (since the old
+  logs would be kep when a new test starts) which this change also fixes.
+  
+  Closes #4035
 
-Daniel Stenberg (14 May 2019)
-- urlapi: require a non-zero host name length when parsing URL
+- [Gergely Nagy brought this change]
+
+  openssl: fix pubkey/signature algorithm detection in certinfo
   
-  Updated test 1560 to verify.
+  Certinfo gives the same result for all OpenSSL versions.
+  Also made printing RSA pubkeys consistent with older versions.
   
-  Closes #3880
+  Reported-by: Michael Wallner
+  Fixes #3706
+  Closes #4030
 
-- configure: error out if OpenSSL wasn't detected when asked for
+- conn_maxage: move the check to prune_dead_connections()
   
-  If --with-ssl is used and configure still couldn't enable SSL this
-  creates an error instead of just silently ignoring the fact.
+  ... and avoid the locking issue.
   
-  Suggested-by: Isaiah Norton
-  Fixes #3824
-  Closes #3830
+  Reported-by: Kunal Ekawde
+  Fixes #4029
+  Closes #4032
 
-Daniel Gustafsson (14 May 2019)
-- imap: Fix typo in comment
+- tests: have runtests figure out disabled features
+  
+  ... so that runtests can skip individual test cases that test features
+  that are explicitly disabled in this build. This new logic is intended
+  for disabled features that aren't otherwise easily visible through the
+  curl_version_info() or other API calls.
+  
+  tests/server/disabled is a newly built executable that will output a
+  list of disabled features. Outputs nothing for a default build.
+  
+  Closes #3950
 
-Steve Holme (14 May 2019)
-- url: Remove unnecessary initialisation from allocate_conn()
+- test188/189: fix Content-Length
   
-  No need to set variables to zero as calloc() does this for us.
+  This cures the flaky test results
   
-  Closes #3879
+  Closes #4034
 
-Daniel Stenberg (14 May 2019)
-- CURLOPT_CAINFO.3: with Schannel, you want Windows 8 or later [ci skip]
+- [Thomas Gamper brought this change]
+
+  winbuild: use WITH_PREFIX if given
   
-  Clues-provided-by: Jay Satiro
-  Clues-provided-by: Jeroen Ooms
-  Fixes #3711
-  Closes #3874
+  Closes #4031
 
-Daniel Gustafsson (13 May 2019)
-- vtls: fix potential ssl_buffer stack overflow
+Daniel Gustafsson (17 Jun 2019)
+- openssl: remove outdated comment
   
-  In Curl_multissl_version() it was possible to overflow the passed in
-  buffer if the generated version string exceeded the size of the buffer.
-  Fix by inverting the logic, and also make sure to not exceed the local
-  buffer during the string generation.
+  OpenSSL used to call exit(1) on syntax errors in OPENSSL_config(),
+  which is why we switched to CONF_modules_load_file() and introduced
+  a comment stating why. This behavior was however changed in OpenSSL
+  commit abdd677125f3a9e3082f8c5692203590fdb9b860, so remove the now
+  outdated and incorrect comment. The mentioned commit also declares
+  OPENSSL_config() deprecated so keep the current coding.
   
-  Closes #3863
-  Reported-by: nevv on HackerOne/curl
-  Reviewed-by: Jay Satiro
-  Reviewed-by: Daniel Stenberg
+  Closes #4033
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Daniel Stenberg (13 May 2019)
+Daniel Stenberg (16 Jun 2019)
 - RELEASE-NOTES: synced
 
-- appveyor: also build "/ci" branches like travis
-
-- pingpong: disable more when no pingpong enabled
+Patrick Monnerat (16 Jun 2019)
+- os400: make vsetopt() non-static as Curl_vsetopt() for os400 support.
+  
+  Use it in curl_easy_setopt_ccsid().
+  
+  Reported-by: jonrumsey on github
+  Fixes #3833
+  Closes #4028
 
-- proxy: acknowledge DISABLE_PROXY more
-
-- parsedate: CURL_DISABLE_PARSEDATE
-
-- sasl: only enable if there's a protocol enabled using it
-
-- mime: acknowledge CURL_DISABLE_MIME
+Daniel Stenberg (15 Jun 2019)
+- runtests: report single test time + total duration
+  
+  ... after each successful test.
+  
+  Closes #4027
 
-- wildcard: disable from build when FTP isn't present
+- multi: fix the transfer hash function
+  
+  Follow-up from 8b987cc7eb
+  
+  Reported-by: Tom van der Woerdt
+  Fixes #4018
+  Closes #4024
 
-- http: CURL_DISABLE_HTTP_AUTH
+- unit1654: cleanup on memory failure
+  
+  ... to make it handle torture tests properly.
+  
+  Reported-by: Marcel Raad
+  Fixes #4021
+  Closes #4022
 
-- base64: build conditionally if there are users
+Marcel Raad (13 Jun 2019)
+- krb5: fix compiler warning
+  
+  Even though the variable was used in a DEBUGASSERT, GCC 8 warned in
+  debug mode:
+  krb5.c:324:17: error: unused variable 'maj' [-Werror=unused-variable]
+  
+  Just suppress the warning and declare the variable unconditionally
+  instead of only for DEBUGBUILD (which also missed the check for
+  HAVE_ASSERT_H).
+  
+  Closes https://github.com/curl/curl/pull/4020
 
-- doh: CURL_DISABLE_DOH
+Daniel Stenberg (13 Jun 2019)
+- quote.d: asterisk prefix works for SFTP as well
+  
+  Reported-by: Ben Voris
+  Fixes #4017
+  Closes #4019
 
-Steve Holme (12 May 2019)
-- auth: Rename the various authentication clean up functions
+- multi: fix the transfer hashes in the socket hash entries
   
-  For consistency and to a avoid confusion.
+  - The transfer hashes weren't using the correct keys so removing entries
+    failed.
   
-  Closes #3869
+  - Simplified the iteration logic over transfers sharing the same socket and
+    they now simply are set to expire and thus get handled in the "regular"
+    timer loop instead.
+  
+  Reported-by: Tom van der Woerdt
+  Fixes #4012
+  Closes #4014
 
-Daniel Stenberg (12 May 2019)
-- [Jay Satiro brought this change]
+Jay Satiro (12 Jun 2019)
+- [Cliff Crosland brought this change]
 
-  docs/INSTALL: fix broken link [ci skip]
+  url: Fix CURLOPT_MAXAGE_CONN time comparison
   
-  Reported-by: Joombalaya on github
-  Fixes #3818
-
-Marcel Raad (12 May 2019)
-- easy: fix another "clarify calculation precedence" warning
+  Old connections are meant to expire from the connection cache after
+  CURLOPT_MAXAGE_CONN seconds. However, they actually expire after 1000x
+  that value. This occurs because a time value measured in milliseconds is
+  accidentally divided by 1M instead of by 1,000.
   
-  I missed this one in commit 6b3dde7fe62ea5a557fd1fd323fac2bcd0c2e9be.
+  Closes https://github.com/curl/curl/pull/4013
 
-- build: fix "clarify calculation precedence" warnings
-  
-  Codacy/CppCheck warns about this. Consistently use parentheses as we
-  already do in some places to silence the warning.
+Daniel Stenberg (11 Jun 2019)
+- test1165: verify that CURL_DISABLE_ symbols are in sync
   
-  Closes https://github.com/curl/curl/pull/3866
+  between configure.ac and source code. They should be possible to switch
+  on/off in configure AND be used in source code.
 
-- cmake: restore C89 compatibility of CurlTests.c
+- configure: remove CURL_DISABLE_TLS_SRP
   
-  I broke it in d1b5cf830bfe169745721b21245d2217d2c2453e and
-  97de97daefc2ed084c91eff34af2426f2e55e134.
+  It isn't used by code so stop providing the define.
   
-  Reported-by: Viktor Szakats
-  Ref: https://github.com/curl/curl/commit/97de97daefc2ed084c91eff34af2426f2e55e134#commitcomment-33499044
-  Closes https://github.com/curl/curl/pull/3868
+  Closes #4010
 
-Steve Holme (11 May 2019)
-- http_ntlm: Corrected the name of the include guard
+- Revert "cmake: add SMB to list of disabled protocols if HTTP_ONLY is specified"
   
-  Missed in f0bdd72c.
+  This reverts commit 36738caeb78603ce24e3ea089a167b8c216fb938.
   
-  Closes #3867
+  Apparently several of the appveyor windows builds broke.
 
-- http_digest: Don't expose functions when HTTP and Crypto Auth are disabled
-  
-  Closes #3861
+- [sergey-raevskiy brought this change]
 
-- http_negotiate: Don't expose functions when HTTP is disabled
+  cmake: add SMB to list of disabled protocols if HTTP_ONLY is specified
+  
+  Reviewed-by: Jakub Zakrzewski
+  Closes #3770
 
-Daniel Stenberg (11 May 2019)
-- SECURITY-PROCESS: fix links [ci skip]
+- RELEASE-NOTES: synced
 
-Marcel Raad (11 May 2019)
-- CMake: suppress unused variable warnings
+- http2: remove CURL_DISABLE_TYPECHECK define
   
-  I missed these in commit d1b5cf830bfe169745721b21245d2217d2c2453e.
+  ... in http2-less builds as it served no use.
 
-Daniel Stenberg (11 May 2019)
-- doh: disable DOH for the cases it doesn't work
-  
-  Due to limitations in Curl_resolver_wait_resolv(), it doesn't work for
-  DOH resolves. This fix disables DOH for those.
+- configure: more --disable switches to toggle off individual features
   
-  Limitation added to KNOWN_BUGS.
+  ... actual support in the code for disabling these has already landed.
   
-  Fixes #3850
-  Closes #3857
+  Closes #4009
 
-Jay Satiro (11 May 2019)
-- checksrc.bat: Ignore snprintf warnings in docs/examples
-  
-  .. because we allow snprintf use in docs/examples.
+- wolfssl: fix key pinning build error
   
-  Closes https://github.com/curl/curl/pull/3862
+  follow-up from deb9462ff2de8
 
-Steve Holme (10 May 2019)
-- vauth: Fix incorrect function description for Curl_auth_user_contains_domain()
+- CURLMOPT_SOCKETFUNCTION.3: clarified
   
-  ...and misalignment of these comments. From a78c61a4.
+  Moved away the callback explanation from curl_multi_socket_action.3 and
+  expanded it somewhat.
   
-  Closes #3860
+  Closes #4006
 
-Jay Satiro (10 May 2019)
-- Revert "multi: support verbose conncache closure handle"
-  
-  This reverts commit b0972bc.
+- wolfssl: fixup for SNI use
   
-  - No longer show verbose output for the conncache closure handle.
+  follow-up from deb9462ff2de8
   
-  The offending commit was added so that the conncache closure handle
-  would inherit verbose mode from the user's easy handle. (Note there is
-  no way for the user to set options for the closure handle which is why
-  that was necessary.) Other debug settings such as the debug function
-  were not also inherited since we determined that could lead to crashes
-  if the user's per-handle private data was used on an unexpected handle.
+  Closes #4007
+
+- CURLOPT_CAINFO.3: polished wording
   
-  The reporter here says he has a debug function to capture the verbose
-  output, and does not expect or want any output to stderr; however
-  because the conncache closure handle does not inherit the debug function
-  the verbose output for that handle does go to stderr.
+  Clarify the functionality when built to use Schannel and Secure
+  Transport and stop calling it the "recommended" or "preferred" way and
+  instead rather call it the default.
   
-  There are other plausible scenarios as well such as the user redirects
-  stderr on their handle, which is also not inherited since it could lead
-  to crashes when used on an unexpected handle.
+  Removed the reference to the ssl comparison table as it isn't necessary.
   
-  Short of allowing the user to set options for the conncache closure
-  handle I don't think there's much we can safely do except no longer
-  inherit the verbose setting.
+  Reported-by: Richard Alcock
+  Bug: https://curl.haxx.se/mail/lib-2019-06/0019.html
+  Closes #4005
+
+GitHub (10 Jun 2019)
+- [Daniel Stenberg brought this change]
+
+  SECURITY.md: created
   
-  Bug: https://curl.haxx.se/mail/lib-2019-05/0021.html
-  Reported-by: Kristoffer Gleditsch
+  Brief security policy description for use/display on github.
+
+Daniel Gustafsson (10 Jun 2019)
+- tool_cb_prg: Fix integer overflow in progress bar
   
-  Ref: https://github.com/curl/curl/pull/3598
-  Ref: https://github.com/curl/curl/pull/3618
+  Commit 61faa0b420c236480bc9ef6fd52b4ecc1e0f8d17 fixed the progress bar
+  width calculation to avoid integer overflow, but failed to account for
+  the fact that initial_size is initialized to -1 when the file size is
+  retrieved from the remote on an upload, causing another signed integer
+  overflow.  Fix by separately checking for this case before the width
+  calculation.
   
-  Closes https://github.com/curl/curl/pull/3856
+  Closes #3984
+  Reported-by: Brian Carpenter (Geeknik Labs)
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Steve Holme (10 May 2019)
-- ntlm: Fix misaligned function comments for Curl_auth_ntlm_cleanup()
+Daniel Stenberg (10 Jun 2019)
+- wolfssl: refer to it as wolfSSL only
   
-  From 6012fa5a.
+  Remove support for, references to and use of "cyaSSL" from the source
+  and docs. wolfSSL is the current name and there's no point in keeping
+  references to ancient history.
   
-  Closes #3858
-
-Daniel Stenberg (9 May 2019)
-- BUG-BOUNTY: minor formatting fixes [ci skip]
+  Assisted-by: Daniel Gustafsson
+  
+  Closes #3903
 
 - RELEASE-NOTES: synced
 
-- BUG-BOUNTY.md: add the Dropbox "bonus" extra payout ability [ci skip]
+- bindlocal: detect and avoid IP version mismatches in bind()
   
-  Closes #3839
+  Reported-by: Alex Grebenschikov
+  Fixes #3993
+  Closes #4002
 
-Kamil Dudka (9 May 2019)
-- http_negotiate: do not treat failure of gss_init_sec_context() as fatal
+- multi: make sure 'data' can present in several sockhash entries
   
-  Fixes #3726
-  Closes #3849
+  Since more than one socket can be used by each transfer at a given time,
+  each sockhash entry how has its own hash table with transfers using that
+  socket.
+  
+  In addition, the sockhash entry can now be marked 'blocked = TRUE'"
+  which then makes the delete function just set 'removed = TRUE' instead
+  of removing it "for real", as a way to not rip out the carpet under the
+  feet of a parent function that iterates over the transfers of that same
+  sockhash entry.
+  
+  Reported-by: Tom van der Woerdt
+  Fixes #3961
+  Fixes #3986
+  Fixes #3995
+  Fixes #4004
+  Closes #3997
 
-- spnego_gssapi: fix return code on gss_init_sec_context() failure
+- [Sorcus brought this change]
+
+  libcurl-tutorial.3: Fix small typo (mutipart -> multipart)
   
-  Fixes #3726
-  Closes #3849
+  Fixed-by: MrSorcus on github
+  Closes #4000
 
-Steve Holme (9 May 2019)
-- gen_resp_file.bat: Removed unnecessary @ from all but the first command
+- unpause: trigger a timeout for event-based transfers
   
-  There is need to use @ on every command once echo has been turned off.
+  ... so that timeouts or other state machine actions get going again
+  after a changing pause state. For example, if the last delivery was
+  paused there's no pending socket activity.
   
-  Closes #3854
+  Reported-by: sstruchtrup on github
+  Fixes #3994
+  Closes #4001
 
-Jay Satiro (8 May 2019)
-- http: Ignore HTTP/2 prior knowledge setting for HTTP proxies
+Marcel Raad (9 Jun 2019)
+- travis: use xenial LLVM package for scan-build
   
-  - Do not switch to HTTP/2 for an HTTP proxy that is not tunnelling to
-    the destination host.
+  I missed that in commit 99a49d6.
+
+- travis: update scan-build job to xenial
   
-  We already do something similar for HTTPS proxies by not sending h2. [1]
+  Closes https://github.com/curl/curl/pull/3999
+
+Daniel Stenberg (8 Jun 2019)
+- bump: start working on 7.65.2
+
+Marcel Raad (5 Jun 2019)
+- examples/htmltitle: use C++ casts between pointer types
   
-  Prior to this change setting CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE would
-  incorrectly use HTTP/2 to talk to the proxy, which is not something we
-  support (yet?). Also it's debatable whether or not that setting should
-  apply to HTTP/2 proxies.
+  Compilers and static analyzers warn about using C-style casts here.
   
-  [1]: https://github.com/curl/curl/commit/17c5d05
+  Closes https://github.com/curl/curl/pull/3975
+
+- examples/fopen: fix comparison
   
-  Bug: https://github.com/curl/curl/issues/3570
-  Bug: https://github.com/curl/curl/issues/3832
+  As want is size_t, (file->buffer_pos - want) is unsigned, so checking
+  if it's less than zero makes no sense.
+  Check if file->buffer_pos is less than want instead to avoid the
+  unsigned integer wraparound.
   
-  Closes https://github.com/curl/curl/pull/3853
+  Closes https://github.com/curl/curl/pull/3975
 
-Marcel Raad (8 May 2019)
-- travis: update mesalink build to xenial
+- build: fix Codacy warnings
   
-  Closes https://github.com/curl/curl/pull/3842
-
-Daniel Stenberg (8 May 2019)
-- [Ricky Leverence brought this change]
+  Reduce variable scopes and remove redundant variable stores.
+  
+  Closes https://github.com/curl/curl/pull/3975
 
-  OpenSSL: Report -fips in version if OpenSSL is built with FIPS
+- sws: remove unused variables
   
-  Older versions of OpenSSL report FIPS availabilty via an OPENSSL_FIPS
-  define. It uses this define to determine whether to publish -fips at
-  the end of the version displayed. Applications that utilize the version
-  reported by OpenSSL will see a mismatch if they compare it to what curl
-  reports, as curl is not modifying the version in the same way. This
-  change simply adds a check to see if OPENSSL_FIPS is defined, and will
-  alter the reported version to match what OpenSSL itself provides. This
-  only appears to be applicable in versions of OpenSSL <1.1.1
+  Unused since commit 2f44e94.
   
-  Closes #3771
+  Closes https://github.com/curl/curl/pull/3975
 
-Kamil Dudka (7 May 2019)
+Version 7.65.1 (4 Jun 2019)
+
+Daniel Stenberg (4 Jun 2019)
+- RELEASE-NOTES: 7.65.1
+
+- THANKS: new contributors from 7.65.1
+
+Steve Holme (4 Jun 2019)
 - [Frank Gevaerts brought this change]
 
-  nss: allow fifos and character devices for certificates.
-  
-  Currently you can do things like --cert <(cat ./cert.crt) with (at least) the
-  openssl backend, but that doesn't work for nss because is_file rejects fifos.
+  ssl: Update outdated "openssl-only" comments for supported backends
   
-  I don't actually know if this is sufficient, nss might do things internally
-  (like seeking back) that make this not work, so actual testing is needed.
+  These are for features that used to be openssl-only but were expanded
+  over time to support other SSL backends.
   
-  Closes #3807
-
-Daniel Gustafsson (6 May 2019)
-- test2100: Fix typos in test description
+  Closes #3985
 
-Daniel Stenberg (6 May 2019)
-- ssh: define USE_SSH if SSH is enabled (any backend)
+Daniel Stenberg (4 Jun 2019)
+- curl_share_setopt.3: improve wording [ci ship]
   
-  Closes #3846
+  Reported-by: Carlos ORyan
 
-Steve Holme (5 May 2019)
-- winbuild: Add our standard copyright header to the winbuild batch files
+Steve Holme (4 Jun 2019)
+- tool_parsecfg: Use correct return type for GetModuleFileName()
+  
+  GetModuleFileName() returns a DWORD which is a typedef of an unsigned
+  long and not an int.
+  
+  Closes #3980
 
-- makedebug: Fix ERRORLEVEL detection after running where.exe
+Daniel Stenberg (3 Jun 2019)
+- TODO: "at least N milliseconds between requests" [ci skip]
   
-  Closes #3838
+  Suggested-by: dkwolfe4 on github
+  Closes #3920
 
-Daniel Stenberg (5 May 2019)
-- urlapi: add CURLUPART_ZONEID to set and get
+Steve Holme (2 Jun 2019)
+- tests/server/.gitignore: Add socksd to the ignore list
   
-  The zoneid can be used with IPv6 numerical addresses.
+  Missed in 04fd6755.
   
-  Updated test 1560 to verify.
+  Closes #3978
+
+- tool_parsecfg: Fix control flow issue (DEADCODE)
   
-  Closes #3834
+  Follow-up to 8144ba38.
+  
+  Detected by Coverity CID 1445663
+  Closes #3976
 
-- [Taiyu Len brought this change]
+Daniel Stenberg (2 Jun 2019)
+- [Sergey Ogryzkov brought this change]
 
-  WRITEFUNCTION: add missing set_in_callback around callback
+  NTLM: reset proxy "multipass" state when CONNECT request is done
   
-  Closes #3837
+  Closes #3972
 
-- RELEASE-NOTES: synced
+- test334: verify HTTP 204 response with chunked coding header
+  
+  Verifies that a bodyless response don't parse this content-related
+  header.
 
-- CURLMOPT_TIMERFUNCTION.3: warn about the recursive risk [ci skip]
+- [Michael Kaufmann brought this change]
+
+  http: don't parse body-related headers bodyless responses
   
-  Reported-by: Ricardo Gomes
+  Responses with status codes 1xx, 204 or 304 don't have a response body. For
+  these, don't parse these headers:
   
-  Bug: #3537
-  Closes #3836
-
-- CURLOPT_CHUNK_BGN_FUNCTION.3: document the struct and time value
+  - Content-Encoding
+  - Content-Length
+  - Content-Range
+  - Last-Modified
+  - Transfer-Encoding
   
-  The time field in the curl_fileinfo struct will always be zero. No code
-  was ever implemented to actually convert the date string to a time_t.
+  This change ensures that HTTP/2 upgrades work even if a
+  "Content-Length: 0" or a "Transfer-Encoding: chunked" header is present.
   
-  Fixes #3829
-  Closes #3835
-
-- OS400/ccsidcurl.c: code style fixes
+  Co-authored-by: Daniel Stenberg
+  Closes #3702
+  Fixes #3968
+  Closes #3977
 
-- OS400/ccsidcurl: replace use of Curl_vsetopt
-  
-  (and make the code style comply)
+- tls13-docs: mention it is only for OpenSSL >= 1.1.1
   
-  Fixes #3833
+  Reported-by: Jay Satiro
+  Co-authored-by: Jay Satiro
+  Fixes #3938
+  Closes #3946
 
-- urlapi: strip off scope id from numerical IPv6 addresses
+- dump-header.d: spell out that no headers == empty file [ci skip]
   
-  ... to make the host name "usable". Store the scope id and put it back
-  when extracting a URL out of it.
+  Reported-by: wesinator at github
+  Fixes #3964
+  Closes #3974
+
+- singlesocket: use separate variable for inner loop
   
-  Also makes curl_url_set() syntax check CURLUPART_HOST.
+  An inner loop within the singlesocket() function wrongly re-used the
+  variable for the outer loop which then could cause an infinite
+  loop. Change to using a separate variable!
   
-  Fixes #3817
-  Closes #3822
+  Reported-by: Eric Wu
+  Fixes #3970
+  Closes #3973
 
 - RELEASE-NOTES: synced
 
-- multiif.h: remove unused protos
+- [Josie Huddleston brought this change]
+
+  http2: Stop drain from being permanently set on
   
-  ... for functions related to pipelining. Those functions were removed in
-  2f44e94efb3df.
+  Various functions called within Curl_http2_done() can have the
+  side-effect of setting the Easy connection into drain mode (by calling
+  drain_this()).  However, the last time we unset this for a transfer (by
+  calling drained_transfer()) is at the beginning of Curl_http2_done().
+  If the Curl_easy is reused for another transfer, it is then stuck in
+  drain mode permanently, which in practice makes it unable to write any
+  data in the new transfer.
   
-  Closes #3828
-
-- [Yiming Jing brought this change]
+  This fix moves the last call to drained_transfer() to later in
+  Curl_http2_done(), after the functions that could potentially call for a
+  drain.
+  
+  Fixes #3966
+  Closes #3967
+  Reported-by: Josie-H
 
-  travis: mesalink: temporarily disable test 3001
+Steve Holme (29 May 2019)
+- conncache: Remove the DEBUGASSERT on length check
   
-  ... due to SHA-1 signatures in test certs
+  We trust the calling code as this is an internal function.
+  
+  Closes #3962
 
-- [Yiming Jing brought this change]
+Jay Satiro (29 May 2019)
+- [Gisle Vanem brought this change]
 
-  travis: upgrade the MesaLink TLS backend to v1.0.0
+  system_win32: fix function prototype
   
-  Closes #3823
-  Closes #3776
-
-- ConnectionExists: improve non-multiplexing use case
+  - Change if_nametoindex parameter type from char * to const char *.
   
-  - better log output
+  Follow-up to 09eef8af from this morning.
   
-  - make sure multiplex is enabled for it to be used
+  Bug: https://github.com/curl/curl/commit/09eef8af#r33716067
 
-- multi: provide Curl_multiuse_state to update information
+Marcel Raad (29 May 2019)
+- appveyor: add Visual Studio solution build
   
-  As soon as a TLS backend gets ALPN conformation about the specific HTTP
-  version it can now set the multiplex situation for the "bundle" and
-  trigger moving potentially queued up transfers to the CONNECT state.
+  Closes https://github.com/curl/curl/pull/3941
 
-- process_pending_handles: mark queued transfers as previously pending
+- appveyor: add support for other build systems
   
-  With transfers being queued up, we only move one at a a time back to the
-  CONNECT state but now we mark moved transfers so that when a moved
-  transfer is confirmed "successful" (it connected) it will trigger the
-  move of another pending transfer. Previously, it would otherwise wait
-  until the transfer was done before doing this. This makes queued up
-  pending transfers get processed (much) faster.
-
-- http: mark bundle as not for multiuse on < HTTP/2 response
+  Introduce BUILD_SYSTEM variable, which is currently always CMake.
   
-  Fixes #3813
-  Closes #3815
+  Closes https://github.com/curl/curl/pull/3941
 
-Daniel Gustafsson (1 May 2019)
-- cookie: Guard against possible NULL ptr deref
+Steve Holme (29 May 2019)
+- url: Load if_nametoindex() dynamically from iphlpapi.dll on Windows
   
-  In case the name pointer isn't set (due to memory pressure most likely)
-  we need to skip the prefix matching and reject with a badcookie to avoid
-  a possible NULL pointer dereference.
+  This fixes the static dependency on iphlpapi.lib and allows curl to
+  build for targets prior to Windows Vista.
   
-  Closes #3820 #3821
-  Reported-by: Jonathan Moerman
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Patrick Monnerat (30 Apr 2019)
-- os400: Add CURLOPT_MAXAGE_CONN to ILE/RPG bindings
-
-Kamil Dudka (29 Apr 2019)
-- nss: provide more specific error messages on failed init
+  This partially reverts 170bd047.
   
-  Closes #3808
+  Fixes #3960
+  Closes #3958
 
-Daniel Stenberg (29 Apr 2019)
-- [Reed Loden brought this change]
+Daniel Stenberg (29 May 2019)
+- http: fix "error: equality comparison with extraneous parentheses"
 
-  docs: minor polish to the bug bounty / security docs
+- parse_proxy: make sure portptr is initialized
   
-  Closes #3811
-
-- CURL_MAX_INPUT_LENGTH: largest acceptable string input size
+  Reported-by: Benbuck Nason
   
-  This limits all accepted input strings passed to libcurl to be less than
-  CURL_MAX_INPUT_LENGTH (8000000) bytes, for these API calls:
-  curl_easy_setopt() and curl_url_set().
+  fixes #3959
+
+- url: default conn->port to the same as conn->remote_port
   
-  The 8000000 number is arbitrary picked and is meant to detect mistakes
-  or abuse, not to limit actual practical use cases. By limiting the
-  acceptable string lengths we also reduce the risk of integer overflows
-  all over.
+  ... so that it has a sensible value when ConnectionExists() is called which
+  needs it set to differentiate host "bundles" correctly on port number!
   
-  NOTE: This does not apply to `CURLOPT_POSTFIELDS`.
+  Also, make conncache:hashkey() use correct port for bundles that are proxy vs
+  host connections.
   
-  Test 1559 verifies.
+  Probably a regression from 7.62.0
   
-  Closes #3805
-
-- [Tseng Jun brought this change]
+  Reported-by: Tom van der Woerdt
+  Fixes #3956
+  Closes #3957
 
-  curlver.h: use parenthesis in CURL_VERSION_BITS macro
+- conncache: make "bundles" per host name when doing proxy tunnels
   
-  Closes #3809
-
-Marcel Raad (27 Apr 2019)
-- [Simon Warta brought this change]
-
-  cmake: rename CMAKE_USE_DARWINSSL to CMAKE_USE_SECTRANSP
+  Only HTTP proxy use where multiple host names can be used over the same
+  connection should use the proxy host name for bundles.
   
-  Closes https://github.com/curl/curl/pull/3769
-
-Steve Holme (23 Apr 2019)
-- ntlm: Missed pre-processor || (or) during rebase for cd15acd0
+  Reported-by: Tom van der Woerdt
+  Fixes #3951
+  Closes #3955
 
-- ntlm: Support the NT response in the type-3 when OpenSSL doesn't include MD4
+- multi: track users of a socket better
   
-  Just like we do for mbed TLS, use our local implementation of MD4 when
-  OpenSSL doesn't support it. This allows a type-3 message to include the
-  NT response.
-
-Daniel Gustafsson (23 Apr 2019)
-- INTERNALS: fix misindentation of ToC item
+  They need to be removed from the socket hash linked list with more care.
   
-  Kerberos was incorrectly indented as a subsection under FTP, which is
-  incorrect as they are both top level sections. A fix for this was first
-  attempted in commit fef38a0898322f285401c5ff2f5e7c90dbf3be63 but that
-  was a few paddles short of being complete.
-
-- [Aron Bergman brought this change]
-
-  INTERNALS: Add structs to ToC
+  When sh_delentry() is called to remove a sockethash entry, remove all
+  individual transfers from the list first. To enable this, each Curl_easy struct
+  now stores a pointer to the sockethash entry to know how to remove itself.
   
-  Add the subsections under "Structs in libcurl" to the table of contents.
+  Reported-by: Tom van der Woerdt and Kunal Ekawde
   
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-
-- [Aron Bergman brought this change]
+  Fixes #3952
+  Fixes #3904
+  Closes #3953
 
-  INTERNALS: Add code highlighting
+Steve Holme (28 May 2019)
+- curl-win32.h: Enable Unix Domain Sockets based on the Windows SDK version
   
-  Make all struct members under the Curl_handler section
-  print in monospace font.
+  Microsoft added support for Unix Domain Sockets in Windows 10 1803
+  (RS4). Rather than expect the user to enable Unix Domain Sockets by
+  uncommenting the #define that was added in 0fd6221f we use the RS4
+  pre-processor variable that is present in newer versions of the
+  Windows SDK.
   
-  Closes #3801
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Closes #3939
 
-Daniel Stenberg (22 Apr 2019)
-- docs/BUG-BOUNTY: bug bounty time [skip ci]
-  
-  Introducing the curl bug bounty program on hackerone. We now recommend
-  filing security issues directly in the hackerone ticket system which
-  only is readable to curl security team members.
-  
-  Assisted-by: Daniel Gustafsson
-  
-  Closes #3488
+Daniel Stenberg (28 May 2019)
+- [Jonas Vautherin brought this change]
 
-Steve Holme (22 Apr 2019)
-- sasl: Don't send authcid as authzid for the PLAIN mechanism as per RFC 4616
+  cmake: support CMAKE_OSX_ARCHITECTURES when detecting SIZEOF variables
   
-  RFC 4616 specifies the authzid is optional in the client authentication
-  message and that the server will derive the authorisation identity
-  (authzid) from the authentication identity (authcid) when not specified
-  by the client.
-
-Jay Satiro (22 Apr 2019)
-- [Gisle Vanem brought this change]
+  Closes #3945
 
-  memdebug: fix variable name
+Marcel Raad (27 May 2019)
+- HAProxy tests: add keywords
   
-  Follow-up to 76b6348 which renamed logfile as curl_dbg_logfile.
+  Add the proxy and haproxy keywords in order to be able to exclude or
+  run these specific tests.
   
-  Ref: https://github.com/curl/curl/commit/76b6348#r33259088
+  Closes https://github.com/curl/curl/pull/3949
 
-Steve Holme (21 Apr 2019)
-- vauth/cleartext: Don't send the authzid if it is empty
+Daniel Stenberg (27 May 2019)
+- [Maksim Stsepanenka brought this change]
+
+  tests: make test 1420 and 1406 work with rtsp-disabled libcurl
   
-  Follow up to 762a292f.
+  Closes #3948
 
-Daniel Stenberg (21 Apr 2019)
-- test 196,197,198: add 'retry' keyword [skip ci]
+Kamil Dudka (27 May 2019)
+- [Hubert Kario brought this change]
+
+  nss: allow to specify TLS 1.3 ciphers if supported by NSS
+  
+  Closes #3916
 
+Daniel Stenberg (26 May 2019)
 - RELEASE-NOTES: synced
 
-- CURLOPT_MAXAGE_CONN: set the maximum allowed age for conn reuse
+- [Jay Satiro brought this change]
+
+  Revert all SASL authzid (new feature) commits
   
-  ... and disconnect too old ones instead of trying to reuse.
+  - Revert all commits related to the SASL authzid feature since the next
+    release will be a patch release, 7.65.1.
   
-  Default max age is set to 118 seconds.
+  Prior to this change CURLOPT_SASL_AUTHZID  / --sasl-authzid was destined
+  for the next release, assuming it would be a feature release 7.66.0.
+  However instead the next release will be a patch release, 7.65.1 and
+  will not contain any new features.
   
-  Ref: #3722
-  Closes #3782
-
-Daniel Gustafsson (20 Apr 2019)
-- [Po-Chuan Hsieh brought this change]
-
-  altsvc: Fix building with cookies disables
+  After the patch release after the reverted commits can be restored by
+  using cherry-pick:
   
-  ALTSVC requires Curl_get_line which is defined in lib/cookie.c inside a #if
-  check of HTTP and COOKIES. That makes Curl_get_line undefined if COOKIES is
-  disabled. Fix by splitting out the function into a separate file which can
-  be included where needed.
+  git cherry-pick a14d72c a9499ff 8c1cc36 c2a8d52 0edf690
   
-  Closes #3717
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-
-Daniel Stenberg (20 Apr 2019)
-- test1002: correct the name [skip ci]
-
-- test660: verify CONNECT_ONLY with IMAP
+  Details for all reverted commits:
   
-  which basically just makes sure LOGOUT is *not* issued on disconnect
-
-- Curl_disconnect: treat all CONNECT_ONLY connections as "dead"
+  Revert "os400: take care of CURLOPT_SASL_AUTHZID in curl_easy_setopt_ccsid()."
   
-  Since the connection has been used by the "outside" we don't know the
-  state of it anymore and curl should not use it anymore.
+  This reverts commit 0edf6907ae37e2020722e6f61229d8ec64095b0a.
   
-  Bug: https://curl.haxx.se/mail/lib-2019-04/0052.html
+  Revert "tests: Fix the line endings for the SASL alt-auth tests"
   
-  Closes #3795
-
-- multi: fix the statenames (follow-up fix from 2f44e94efb3df8e)
+  This reverts commit c2a8d52a1356a722ff9f4aeb983cd4eaf80ef221.
   
-  The list of names must be in sync with the defined states in the header
-  file!
-
-Steve Holme (16 Apr 2019)
-- openvms: Remove pre-processors for Windows as VMS cannot support them
-
-- openvms: Remove pre-processor for SecureTransport as VMS cannot support it
+  Revert "examples: Added SASL PLAIN authorisation identity (authzid) examples"
   
-  Fixes #3768
-  Closes #3785
-
-Jay Satiro (16 Apr 2019)
-- TODO: Add issue link to an existing entry
-
-Daniel Stenberg (16 Apr 2019)
-- RELEASE-NOTES: synced
-
-Jay Satiro (16 Apr 2019)
-- tool_help: Warn if curl and libcurl versions do not match
+  This reverts commit 8c1cc369d0c7163c6dcc91fd38edfea1f509ae75.
   
-  .. because functionality may be affected if the versions differ.
+  Revert "curl: --sasl-authzid added to support CURLOPT_SASL_AUTHZID from the tool"
   
-  This commit implements TODO 18.7 "warning if curl version is not in sync
-  with libcurl version".
+  This reverts commit a9499ff136d89987af885e2d7dff0a066a3e5817.
   
-  Ref: https://github.com/curl/curl/blob/curl-7_64_1/docs/TODO#L1028-L1033
+  Revert "sasl: Implement SASL authorisation identity via CURLOPT_SASL_AUTHZID"
   
-  Closes https://github.com/curl/curl/pull/3774
-
-Steve Holme (16 Apr 2019)
-- md5: Update the function signature following d84da52d
+  This reverts commit a14d72ca2fec5d4eb5a043936e4f7ce08015c177.
 
-- md5: Forgot to update the code alignment in d84da52d
+- [dbrowndan brought this change]
 
-- md5: Return CURLcode from the internally accessible functions
+  FAQ: more minor updates and spelling fixes
   
-  Following 28f826b3 to return CURLE_OK instead of numeric 0.
+  Closes #3937
 
-Daniel Gustafsson (15 Apr 2019)
-- tests: Run global cleanup at end of tests
+- RELEASE-NOTES: synced
+
+- sectransp: handle errSSLPeerAuthCompleted from SSLRead()
   
-  Make sure to run curl_global_cleanup() when shutting down the test
-  suite to release any resources allocated in the SSL setup. This is
-  clearly visible when running tests with PolarSSL where the thread
-  lock calloc() memory which isn't released when not running cleanup.
-  Below is an excerpt from the autobuild logs:
-  
-    ==12368== 96 bytes in 1 blocks are possibly lost in loss record 1 of 2
-    ==12368== at 0x4837B65: calloc (vg_replace_malloc.c:752)
-    ==12368== by 0x11A76E: curl_dbg_calloc (memdebug.c:205)
-    ==12368== by 0x145CDF: Curl_polarsslthreadlock_thread_setup
-                           (polarssl_threadlock.c:54)
-    ==12368== by 0x145B37: Curl_polarssl_init (polarssl.c:865)
-    ==12368== by 0x14129D: Curl_ssl_init (vtls.c:171)
-    ==12368== by 0x118B4C: global_init (easy.c:158)
-    ==12368== by 0x118BF5: curl_global_init (easy.c:221)
-    ==12368== by 0x118D0B: curl_easy_init (easy.c:299)
-    ==12368== by 0x114E96: test (lib1906.c:32)
-    ==12368== by 0x115495: main (first.c:174)
-  
-  Closes #3783
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: smuellerDD on github
+  Fixes #3932
+  Closes #3933
 
-Marcel Raad (15 Apr 2019)
-- travis: use mbedtls from Xenial
-  
-  No need to build it from source anymore.
-  
-  Closes https://github.com/curl/curl/pull/3779
+GitHub (24 May 2019)
+- [Gisle Vanem brought this change]
 
-- travis: use libpsl from Xenial
-  
-  This makes building libpsl and libidn2 from source unnecessary and
-  removes the need for the autopoint and libunistring-dev packages.
-  
-  Closes https://github.com/curl/curl/pull/3779
+  Fix typo.
 
-Daniel Stenberg (15 Apr 2019)
-- runtests: start socksd like other servers
-  
-  ... without a $srcdir prefix. Triggered by the failures in several
-  autobuilds.
+Daniel Stenberg (23 May 2019)
+- tool_setopt: for builds with disabled-proxy, skip all proxy setopts()
   
-  Closes #3781
+  Reported-by: Marcel Raad
+  Fixes #3926
+  Closes #3929
 
-Daniel Gustafsson (14 Apr 2019)
-- socksd: Fix typos
+Steve Holme (23 May 2019)
+- winbuild: Use two space indentation
   
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #3930
 
-- socksd: Properly decorate static variables
+GitHub (23 May 2019)
+- [Gisle Vanem brought this change]
+
+  tool_parse_cfg: Avoid 2 fopen() for WIN32
   
-  Mark global variables static to avoid compiler warning in Clang when
-  using -Wmissing-variable-declarations.
+  Using the memdebug.h mem-leak feature, I noticed 2 calls like:
+    FILE tool_parsecfg.c:70 fopen("c:\Users\Gisle\AppData\Roaming\_curlrc","rt")
+    FILE tool_parsecfg.c:114 fopen("c:\Users\Gisle\AppData\Roaming\_curlrc","rt")
   
-  Closes #3778
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  No need for 'fopen(), 'fclose()' and a 'fopen()' yet again.
 
-Steve Holme (14 Apr 2019)
-- md(4|5): Fixed indentation oddities with the importation of replacement code
-  
-  The indentation from 211d5329 and 57d6d253 was a little strange as
-  parts didn't align correctly, uses 4 spaces rather than 2. Checked
-  the indentation of the original source so it aligns, albeit, using
-  curl style.
+Daniel Stenberg (23 May 2019)
+- md4: include the mbedtls config.h to get the MD4 info
 
-- md5: Code style to return CURLE_OK rather than numeric 0
+- md4: build correctly with openssl without MD4
+  
+  Reported-by: elsamuko at github
+  Fixes #3921
+  Closes #3922
 
-- md5: Corrected code style for some pointer arguments
+Patrick Monnerat (23 May 2019)
+- os400: take care of CURLOPT_SASL_AUTHZID in curl_easy_setopt_ccsid().
 
-Marcel Raad (13 Apr 2019)
-- travis: update some builds to xenial
-  
-  Xenial comes with more up-to-date software versions and more available
-  packages, some of which we currently build from source. Unfortunately,
-  some builds would fail with Xenial because of assertion failures in
-  Valgrind when using OpenSSL, so leave these at Trusty.
-  
-  Closes https://github.com/curl/curl/pull/3777
+Daniel Stenberg (23 May 2019)
+- .github/FUNDING: mention our opencollective "home" [ci skip]
 
-Daniel Stenberg (13 Apr 2019)
-- test: make tests and test scripts use socksd for SOCKS
-  
-  Make all SOCKS tests use socksd instead of ssh.
+Marcel Raad (23 May 2019)
+- [Zenju brought this change]
 
-- socksd: new SOCKS 4+5 server for tests
+  config-win32: add support for if_nametoindex and getsockname
   
-  Closes #3752
+  Closes https://github.com/curl/curl/pull/3923
 
-- singleipconnect: show port in the verbose "Trying ..." message
+Jay Satiro (23 May 2019)
+- tests: Fix the line endings for the SASL alt-auth tests
   
-  To aid debugging better.
-
-- [tmilburn brought this change]
-
-  CURLOPT_ADDRESS_SCOPE: fix range check and more
+  - Change data and protocol sections to CRLF line endings.
   
-  Commit 9081014 fixed most of the confusing issues between scope id and
-  scope however 844896d added bad limits checking assuming that the scope
-  is being set and not the scope id.
+  Prior to this change the tests would fail or hang, which is because
+  certain sections such as protocol require CRLF line endings.
   
-  I have fixed the documentation so it all refers to scope ids.
+  Follow-up to a9499ff from today which added the tests.
   
-  In addition Curl_if2ip refered to the scope id as remote_scope_id which
-  is incorrect, so I renamed it to local_scope_id.
+  Ref: https://github.com/curl/curl/pull/3790
+
+Daniel Stenberg (23 May 2019)
+- url: fix bad #ifdef
   
-  Adjusted-by: Daniel Stenberg
+  Regression since e91e48161235272ff485.
   
-  Closes #3655
-  Closes #3765
-  Fixes #3713
+  Reported-by: Tom Greenslade
+  Fixes #3924
+  Closes #3925
 
-- urlapi: stricter CURLUPART_PORT parsing
+- Revert "progress: CURL_DISABLE_PROGRESS_METER"
   
-  Only allow well formed decimal numbers in the input.
+  This reverts commit 3b06e68b7734cb10a555f9d7e804dd5d808236a4.
   
-  Document that the number MUST be between 1 and 65535.
+  Clearly this change wasn't good enough as it broke CURLOPT_LOW_SPEED_LIMIT +
+  CURLOPT_LOW_SPEED_TIME
   
-  Add tests to test 1560 to verify the above.
+  Reported-by: Dave Reisner
   
-  Ref: https://github.com/curl/curl/issues/3753
-  Closes #3762
+  Fixes #3927
+  Closes #3928
 
-Jay Satiro (13 Apr 2019)
-- [Jan Ehrhardt brought this change]
+Steve Holme (22 May 2019)
+- examples: Added SASL PLAIN authorisation identity (authzid) examples
 
-  winbuild: Support MultiSSL builds
-  
-  - Remove the lines in winbuild/Makefile.vc that generate an error with
-    multiple SSL backends.
-  
-  - Add /DCURL_WITH_MULTI_SSL in winbuild/MakefileBuild.vc if multiple SSL
-    backends are set.
-  
-  Closes https://github.com/curl/curl/pull/3772
+- curl: --sasl-authzid added to support CURLOPT_SASL_AUTHZID from the tool
 
-Daniel Stenberg (12 Apr 2019)
-- travis: remove mesalink builds (temporarily?)
+- sasl: Implement SASL authorisation identity via CURLOPT_SASL_AUTHZID
   
-  Since the mesalink build started to fail on travis, even though we build
-  a fixed release version, we disable it to prevent it from blocking
-  progress.
+  Added the ability for the calling program to specify the authorisation
+  identity (authzid), the identity to act as, in addition to the
+  authentication identity (authcid) and password when using SASL PLAIN
+  authentication.
   
-  Closes #3767
+  Fixed #3653
+  Closes #3790
 
-- openssl: mark connection for close on TLS close_notify
-  
-  Without this, detecting and avoid reusing a closed TLS connection
-  (without a previous GOAWAY) when doing HTTP/2 is tricky.
+Marc Hoersken (22 May 2019)
+- tests: add support to test against OpenSSH for Windows
   
-  Reported-by: Tom van der Woerdt
-  Fixes #3750
-  Closes #3763
+  Testing against OpenSSH for Windows requires v7.7.0.0 or newer
+  due to the use of AllowUsers and DenyUsers. For more info see:
+  https://github.com/PowerShell/Win32-OpenSSH/wiki/sshd_config
 
-- RELEASE-NOTES: synced
+Daniel Stenberg (22 May 2019)
+- bump: start on the next release
 
-Steve Holme (11 Apr 2019)
-- vauth/cleartext: Update the PLAIN login function signature to match RFC 4616
-  
-  Functionally this doesn't change anything as we still use the username
-  for both the authorisation identity and the authentication identity.
+Marcel Raad (22 May 2019)
+- examples: fix "clarify calculation precedence" warnings
   
-  Closes #3757
+  Closes https://github.com/curl/curl/pull/3919
 
-Daniel Stenberg (11 Apr 2019)
-- test1906: verify CURLOPT_CURLU + CURLOPT_PORT usage
+- hiperfifo: remove unused variable
   
-  Based-on-code-by: Poul T Lomholt
+  Closes https://github.com/curl/curl/pull/3919
 
-- url: always clone the CUROPT_CURLU handle
-  
-  Since a few code paths actually update that data.
-  
-  Fixes #3753
-  Closes #3761
+- examples: remove dead variable stores
   
-  Reported-by: Poul T Lomholt
+  Closes https://github.com/curl/curl/pull/3919
 
-- CURLOPT_DNS_USE_GLOBAL_CACHE: remove
-  
-  Remove the code too. The functionality has been disabled in code since
-  7.62.0. Setting this option will from now on simply be ignored and have
-  no function.
+- examples: reduce variable scopes
   
-  Closes #3654
+  Closes https://github.com/curl/curl/pull/3919
 
-Marcel Raad (11 Apr 2019)
-- travis: install libgnutls28-dev only for --with-gnutls build
-  
-  Reduces the time needed for the other jobs a little.
+- http2-download: fix format specifier
   
-  Closes https://github.com/curl/curl/pull/3721
+  Closes https://github.com/curl/curl/pull/3919
 
-- travis: install libnss3-dev only for --with-nss build
-  
-  Reduces the time needed for the other jobs a little.
+Daniel Stenberg (22 May 2019)
+- PolarSSL: deprecate support step 1. Removed from configure.
   
-  Closes https://github.com/curl/curl/pull/3721
-
-- travis: install libssh2-dev only for --with-libssh2 build
+  Also removed mentions from most docs.
   
-  Reduces the time needed for the other jobs a little.
+  Discussed: https://curl.haxx.se/mail/lib-2019-05/0045.html
   
-  Closes https://github.com/curl/curl/pull/3721
+  Closes #3888
 
-- travis: install libssh-dev only for --with-libssh build
+- configure/cmake: check for if_nametoindex()
   
-  Reduces the time needed for the other jobs a little.
+  - adds the check to cmake
   
-  Closes https://github.com/curl/curl/pull/3721
+  - fixes the configure check to work for cross-compiled windows builds
+  
+  Closes #3917
 
-- travis: install krb5-user only for --with-gssapi build
+- parse_proxy: use the IPv6 zone id if given
   
-  Reduces the time needed for the other jobs a little.
+  If the proxy string is given as an IPv6 numerical address with a zone
+  id, make sure to use that for the connect to the proxy.
   
-  Closes https://github.com/curl/curl/pull/3721
-
-- travis: install lcov only for the coverage job
+  Reported-by: Edmond Yu
   
-  Reduces the time needed for the other jobs a little.
+  Fixes #3482
+  Closes #3918
+
+Version 7.65.0 (22 May 2019)
+
+Daniel Stenberg (22 May 2019)
+- RELEASE-NOTES: 7.65.0 release
+
+- THANKS: from the 7.65.0 release-notes
+
+- url: convert the zone id from a IPv6 URL to correct scope id
   
-  Closes https://github.com/curl/curl/pull/3721
+  Reported-by: GitYuanQu on github
+  Fixes #3902
+  Closes #3914
 
-- travis: install clang only when needed
+- configure: detect getsockname and getpeername on windows too
   
-  This reduces the GCC job runtimes a little and it's needed to
-  selectively update clang builds to xenial.
+  Made detection macros for these two functions in the same style as other
+  functions possibly in winsock in the hope this will work better to
+  detect these functions when cross-compiling for Windows.
   
-  Closes https://github.com/curl/curl/pull/3721
-
-- AppVeyor: enable testing for WinSSL build
+  Follow-up to e91e4816123
   
-  Closes https://github.com/curl/curl/pull/3725
+  Fixes #3913
+  Closes #3915
 
-- build: fix Codacy/CppCheck warnings
+Marcel Raad (21 May 2019)
+- examples: remove unused variables
   
-  - remove unused variables
-  - declare conditionally used variables conditionally
-  - suppress unused variable warnings in the CMake tests
-  - remove dead variable stores
-  - consistently use WIN32 macro to detect Windows
+  Fixes Codacy/CppCheck warnings.
   
-  Closes https://github.com/curl/curl/pull/3739
+  Closes
 
-- polarssl_threadlock: remove conditionally unused code
+Daniel Gustafsson (21 May 2019)
+- udpateconninfo: mark variable unused
   
-  Make functions no-ops if neither both USE_THREADS_POSIX and
-  HAVE_PTHREAD_H nor both USE_THREADS_WIN32 and HAVE_PROCESS_H are
-  defined. Previously, if only one of them was defined, there was either
-  code compiled that did nothing useful or the wrong header included for
-  the functions used.
+  When compiling without getpeername() or getsockname(), the sockfd
+  paramter to Curl_udpateconninfo() became unused after commit e91e481612
+  added ifdef guards.
   
-  Also, move POLARSSL_MUTEX_T define to implementation file as it's not
-  used externally.
+  Closes #3910
+  Fixes https://curl.haxx.se/dev/log.cgi?id=20190520172441-32196
+  Reviewed-by: Marcel Raad, Daniel Stenberg
+
+- ftp: move ftp_ccc in under featureflag
   
-  Closes https://github.com/curl/curl/pull/3739
+  Commit e91e48161235272ff485ff32bd048c53af731f43 moved ftp_ccc in under
+  the FTP featureflag in the UserDefined struct, but vtls callsites were
+  still using it unprotected.
+  
+  Closes #3912
+  Fixes: https://curl.haxx.se/dev/log.cgi?id=20190520044705-29865
+  Reviewed-by: Daniel Stenberg, Marcel Raad
 
-- lib557: initialize variables
+Daniel Stenberg (20 May 2019)
+- curl: report error for "--no-" on non-boolean options
   
-  These variables are only conditionally initialized.
+  Reported-by: Olen Andoni
+  Fixes #3906
+  Closes #3907
+
+- [Guy Poizat brought this change]
+
+  mbedtls: enable use of EC keys
   
-  Closes https://github.com/curl/curl/pull/3739
+  Closes #3892
 
-- lib509: add missing include for strdup
+- lib1560: add tests for parsing URL with too long scheme
   
-  Closes https://github.com/curl/curl/pull/3739
+  Ref: #3905
 
-- README.md: fix no-consecutive-blank-lines Codacy warning
+- [Omar Ramadan brought this change]
+
+  urlapi: increase supported scheme length to 40 bytes
   
-  Consistently use one blank line between blocks.
+  The longest currently registered URI scheme at IANA is 36 bytes long.
   
-  Closes https://github.com/curl/curl/pull/3739
+  Closes #3905
+  Closes #3900
 
-- tests/server/util: fix Windows Unicode build
+Marcel Raad (20 May 2019)
+- lib: reduce variable scopes
   
-  Always use the ANSI version of FormatMessage as we don't have the
-  curl_multibyte gear available here.
+  Fixes Codacy/CppCheck warnings.
   
-  Closes https://github.com/curl/curl/pull/3758
+  Closes https://github.com/curl/curl/pull/3872
 
-Daniel Stenberg (11 Apr 2019)
-- curl_easy_getinfo.3: fix minor formatting mistake
+- tool_formparse: remove redundant assignment
+  
+  Just initialize word_begin with the correct value.
+  
+  Closes https://github.com/curl/curl/pull/3873
 
-Daniel Gustafsson (11 Apr 2019)
-- xattr: skip unittest on unsupported platforms
+- ssh: move variable declaration to where it's used
   
-  The stripcredentials unittest fails to compile on platforms without
-  xattr support, for example the Solaris member in the buildfarm which
-  fails with the following:
+  This way, we need only one call to free.
   
-    CC unit1621-unit1621.o
-    CC ../libtest/unit1621-first.o
-    CCLD unit1621
-    Undefined first referenced
-    symbol in file
-    stripcredentials unit1621-unit1621.o
-    goto problem 2
-    ld: fatal: symbol referencing errors. No output written to .libs/unit1621
-    collect2: error: ld returned 1 exit status
-    gmake[2]: *** [Makefile:996: unit1621] Error 1
+  Closes https://github.com/curl/curl/pull/3873
+
+- ssh-libssh: remove unused variable
   
-  Fix by excluding the test on such platforms by using the reverse
-  logic from where stripcredentials() is defined.
+  sock was only used to be assigned to fd_read.
   
-  Closes #3759
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes https://github.com/curl/curl/pull/3873
 
-Steve Holme (11 Apr 2019)
-- emailL Added reference to RFC8314 for implicit TLS
+Daniel Stenberg (20 May 2019)
+- test332: verify the blksize fix
 
-- README: Schannel, stop calling it "winssl"
+- tftp: use the current blksize for recvfrom()
   
-  Stick to "Schannel" everywhere - follow up to 180501cb.
+  bug: https://curl.haxx.se/docs/CVE-2019-5436.html
+  Reported-by: l00p3r on hackerone
+  CVE-2019-5436
 
-Jakub Zakrzewski (10 Apr 2019)
-- cmake: clear CMAKE_REQUIRED_LIBRARIES after each use
+Daniel Gustafsson (19 May 2019)
+- version: make ssl_version buffer match for multi_ssl
   
-  This fixes GSSAPI builds with the libraries in a non-standard location.
-  The testing for recv() were failing because it failed to link
-  the Kerberos libraries, which are not needed for this or subsequent
-  tests.
+  When running a multi TLS backend build the version string needs more
+  buffer space. Make the internal ssl_buffer stack buffer match the one
+  in Curl_multissl_version() to allow for the longer string. For single
+  TLS backend builds there is no use in extended to buffer. This is a
+  fallout from #3863 which fixes up the multi_ssl string generation to
+  avoid a buffer overflow when the buffer is too small.
   
-  fixes #3743
-  closes #3744
+  Closes #3875
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- cmake: avoid linking executable for some tests with cmake 3.6+
+Steve Holme (18 May 2019)
+- http_ntlm_wb: Handle auth for only a single request
   
-  With CMAKE_TRY_COMPILE_TARGET_TYPE set to STATIC_LIBRARY, the try_compile()
-  (which is used by check_c_source_compiles()) will build static library
-  instead of executable. This avoids linking additional libraries in and thus
-  speeds up those checks a little.
+  Currently when the server responds with 401 on NTLM authenticated
+  connection (re-used) we consider it to have failed.  However this is
+  legitimate and may happen when for example IIS is set configured to
+  'authPersistSingleRequest' or when the request goes thru a proxy (with
+  'via' header).
   
-  This commit also avoids #3743 (GSSAPI build errors) on itself with cmake
-  3.6 or above. That issue was fixed separately for all versions.
+  Implemented by imploying an additional state once a connection is
+  re-used to indicate that if we receive 401 we need to restart
+  authentication.
   
-  Ref: #3744
+  Missed in fe6049f0.
 
-- cmake: minor cleanup
-  
-  - Remove nneeded include_regular_expression.
-    It was setting what is already a default.
+- http_ntlm_wb: Cleanup handshake after clean NTLM failure
   
-  - Remove duplicated include.
+  Missed in 50b87c4e.
+
+- http_ntlm_wb: Return the correct error on receiving an empty auth message
   
-  - Don't check for pre-3.0.0 CMake version.
-    We already require at least 3.0.0, so it's just clutter.
+  Missed in fe20826b as it wasn't implemented in http.c in b4d6db83.
   
-  Ref: #3744
-
-Steve Holme (8 Apr 2019)
-- build-openssl.bat: Fixed support for OpenSSL v1.1.0+
-
-- build-openssl.bat: Perfer the use of if statements rather than goto (where possible)
-
-- build-openssl.bat: Perform the install for each build type directly after the build
+  Closes #3894
 
-- build-openssl.bat: Split the install of static and shared build types
+Daniel Stenberg (18 May 2019)
+- curl: make code work with protocol-disabled libcurl
+  
+  Closes #3844
 
-- build-openssl.bat: Split the building of static and shared build types
+- libcurl: #ifdef away more code for disabled features/protocols
 
-- build-openssl.bat: Move the installation into a separate function
+- progress: CURL_DISABLE_PROGRESS_METER
 
-- build-openssl.bat: Move the build step into a separate function
+- hostip: CURL_DISABLE_SHUFFLE_DNS
 
-- build-openssl.bat: Move the OpenSSL configuration into a separate function
+- netrc: CURL_DISABLE_NETRC
 
-- build-openssl.bat: Fixed the BUILD_CONFIG variable not being initialised
+Viktor Szakats (16 May 2019)
+- docs: Markdown and misc improvements [ci skip]
   
-  Should the parent environment set this variable then the build might
-  not be performed as the user intended.
-
-Daniel Stenberg (8 Apr 2019)
-- socks: fix error message
+  Approved-by: Daniel Stenberg
+  Closes #3896
 
-- config.d: clarify that initial : and = might need quoting [skip ci]
+- docs/RELEASE-PROCEDURE: link to live iCalendar [ci skip]
   
-  Fixes #3738
-  Closes #3749
+  Ref: https://github.com/curl/curl/commit/0af41b40b2c7bd379b2251cbe7cd618e21fa0ea1#commitcomment-33563135
+  Approved-by: Daniel Stenberg
+  Closes #3895
 
-- RELEASE-NOTES: synced
+Daniel Stenberg (16 May 2019)
+- travis: add an osx http-only build
   
-  bumped to 7.65.0 for next release
+  Closes #3887
 
-- socks5: user name and passwords must be shorter than 256
+- cleanup: remove FIXME and TODO comments
   
-  bytes... since the protocol needs to store the length in a single byte field.
+  They serve very little purpose and mostly just add noise. Most of them
+  have been around for a very long time. I read them all before removing
+  or rephrasing them.
   
-  Reported-by: XmiliaH on github
-  Fixes #3737
-  Closes #3740
-
-- [Jakub Zakrzewski brought this change]
-
-  test: urlapi: urlencode characters above 0x7f correctly
+  Ref: #3876
+  Closes #3883
 
-- [Jakub Zakrzewski brought this change]
-
-  urlapi: urlencode characters above 0x7f correctly
-  
-  fixes #3741
-  Closes #3742
-
-- [Even Rouault brought this change]
-
-  multi_runsingle(): fix use-after-free
-  
-  Fixes #3745
-  Closes #3746
-  
-  The following snippet
-  ```
-  
-  int main()
-  {
-      CURL* hCurlHandle = curl_easy_init();
-      curl_easy_setopt(hCurlHandle, CURLOPT_URL, "http://example.com");
-      curl_easy_setopt(hCurlHandle, CURLOPT_PROXY, "1");
-      curl_easy_perform(hCurlHandle);
-      curl_easy_cleanup(hCurlHandle);
-      return 0;
-  }
-  ```
-  triggers the following Valgrind warning
+- curl: don't set FTP options for FTP-disabled builds
   
-  ```
-  ==4125== Invalid read of size 8
-  ==4125==    at 0x4E7D1EE: Curl_llist_remove (llist.c:97)
-  ==4125==    by 0x4E7EF5C: detach_connnection (multi.c:798)
-  ==4125==    by 0x4E80545: multi_runsingle (multi.c:1451)
-  ==4125==    by 0x4E8197C: curl_multi_perform (multi.c:2072)
-  ==4125==    by 0x4E766A0: easy_transfer (easy.c:625)
-  ==4125==    by 0x4E76915: easy_perform (easy.c:719)
-  ==4125==    by 0x4E7697C: curl_easy_perform (easy.c:738)
-  ==4125==    by 0x4008BE: main (in /home/even/curl/test)
-  ==4125==  Address 0x9b3d1d0 is 1,120 bytes inside a block of size 1,600 free'd
-  ==4125==    at 0x4C2ECF0: free (vg_replace_malloc.c:530)
-  ==4125==    by 0x4E62C36: conn_free (url.c:756)
-  ==4125==    by 0x4E62D34: Curl_disconnect (url.c:818)
-  ==4125==    by 0x4E48DF9: Curl_once_resolved (hostip.c:1097)
-  ==4125==    by 0x4E8052D: multi_runsingle (multi.c:1446)
-  ==4125==    by 0x4E8197C: curl_multi_perform (multi.c:2072)
-  ==4125==    by 0x4E766A0: easy_transfer (easy.c:625)
-  ==4125==    by 0x4E76915: easy_perform (easy.c:719)
-  ==4125==    by 0x4E7697C: curl_easy_perform (easy.c:738)
-  ==4125==    by 0x4008BE: main (in /home/even/curl/test)
-  ==4125==  Block was alloc'd at
-  ==4125==    at 0x4C2F988: calloc (vg_replace_malloc.c:711)
-  ==4125==    by 0x4E6438E: allocate_conn (url.c:1654)
-  ==4125==    by 0x4E685B4: create_conn (url.c:3496)
-  ==4125==    by 0x4E6968F: Curl_connect (url.c:4023)
-  ==4125==    by 0x4E802E7: multi_runsingle (multi.c:1368)
-  ==4125==    by 0x4E8197C: curl_multi_perform (multi.c:2072)
-  ==4125==    by 0x4E766A0: easy_transfer (easy.c:625)
-  ==4125==    by 0x4E76915: easy_perform (easy.c:719)
-  ==4125==    by 0x4E7697C: curl_easy_perform (easy.c:738)
-  ==4125==    by 0x4008BE: main (in /home/even/curl/test)
-  ```
+  ... since libcurl has started to be totally unaware of options for
+  disabled protocols they now return error.
   
-  This has been bisected to commit 2f44e94
+  Bug: https://github.com/curl/curl/commit/c9c5304dd4747cbe75d2f24be85920d572fcb5b8#commitcomment-33533937
   
-  Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14109
-  Credit to OSS Fuzz
+  Reported-by: Marcel Raad
+  Closes #3886
 
-- pipelining: removed
+Steve Holme (16 May 2019)
+- http_ntlm_wb: Move the type-2 message processing into a dedicated function
   
-  As previously planned and documented in DEPRECATE.md, all pipelining
-  code is removed.
+  This brings the code inline with the other HTTP authentication mechanisms.
   
-  Closes #3651
+  Closes #3890
 
-- [cclauss brought this change]
+Daniel Stenberg (15 May 2019)
+- RELEASE-NOTES: synced
 
-  tests: make Impacket (SMB server) Python 3 compatible
-  
-  Closes #3731
-  Fixes #3289
+- docs/RELEASE-PROCEDURE: updated coming releases dates [ci skip]
 
-Marcel Raad (6 Apr 2019)
-- [Simon Warta brought this change]
+- CURLOPT_READFUNCTION.3: see also CURLOPT_UPLOAD_BUFFERSIZE [ci skip]
+  
+  Reported-by: Roy Bellingan
+  Bug: #3885
 
-  cmake: set SSL_BACKENDS
+- parse_proxy: use the URL parser API
   
-  This groups all SSL backends into the feature "SSL" and sets the
-  SSL_BACKENDS analogue to configure.ac
+  As we treat a given proxy as a URL we should use the unified URL parser
+  to extract the parts out of it.
   
-  Closes https://github.com/curl/curl/pull/3736
-
-- [Simon Warta brought this change]
+  Closes #3878
 
-  cmake: don't run SORT on empty list
+Steve Holme (15 May 2019)
+- http_negotiate: Move the Negotiate state out of the negotiatedata structure
   
-  In case of an empty list, SORTing leads to the cmake error "list
-  sub-command SORT requires list to be present."
+  Given that this member variable is not used by the SASL based protocols
+  there is no need to have it here.
   
-  Closes https://github.com/curl/curl/pull/3736
-
-Daniel Gustafsson (5 Apr 2019)
-- [Eli Schwartz brought this change]
+  Closes #3882
 
-  configure: fix default location for fish completions
+- http_ntlm: Move the NTLM state out of the ntlmdata structure
   
-  Fish defines a vendor completions directory for completions that are not
-  installed as part of the fish project itself, and the vendor completions
-  are preferred if they exist. This prevents trying to overwrite the
-  builtin curl.fish completion (or creating file conflicts in distro
-  packaging).
+  Given that this member variable is not used by the SASL based protocols
+  there is no need to have it here.
+
+- url: Move the negotiate state type into a dedicated enum
+
+- url: Remove duplicate clean up of the winbind variables in conn_shutdown()
   
-  Prefer the pkg-config defined location exported by fish, if it can be
-  found, and fall back to the correct directory defined by most systems.
+  Given that Curl_disconnect() calls Curl_http_auth_cleanup_ntlm() prior
+  to calling conn_shutdown() and it in turn performs this, there is no
+  need to perform the same action in conn_shutdown().
   
-  Closes #3723
-  Reviewed-by: Daniel Gustafsson
+  Closes #3881
 
-Marcel Raad (5 Apr 2019)
-- ftplistparser: fix LGTM alert "Empty block without comment"
+Daniel Stenberg (14 May 2019)
+- urlapi: require a non-zero host name length when parsing URL
   
-  Removing the block is consistent with line 954/957.
+  Updated test 1560 to verify.
   
-  Closes https://github.com/curl/curl/pull/3732
+  Closes #3880
 
-- transfer: fix LGTM alert "Comparison is always true"
+- configure: error out if OpenSSL wasn't detected when asked for
   
-  Just remove the redundant condition, which also makes it clear that
-  k->buf is always 0-terminated if this break is not hit.
+  If --with-ssl is used and configure still couldn't enable SSL this
+  creates an error instead of just silently ignoring the fact.
   
-  Closes https://github.com/curl/curl/pull/3732
+  Suggested-by: Isaiah Norton
+  Fixes #3824
+  Closes #3830
 
-Jay Satiro (4 Apr 2019)
-- [Rikard Falkeborn brought this change]
+Daniel Gustafsson (14 May 2019)
+- imap: Fix typo in comment
 
-  smtp: fix compiler warning
-  
-  - Fix clang string-plus-int warning.
-  
-  Clang 8 warns about adding a string to an int does not append to the
-  string. Indeed it doesn't, but that was not the intention either. Use
-  array indexing as suggested to silence the warning. There should be no
-  functional changes.
-  
-  (In other words clang warns about "foo"+2 but not &"foo"[2] so use the
-  latter.)
+Steve Holme (14 May 2019)
+- url: Remove unnecessary initialisation from allocate_conn()
   
-  smtp.c:1221:29: warning: adding 'int' to a string does not append to the
-  string [-Wstring-plus-int]
-        eob = strdup(SMTP_EOB + 2);
-              ~~~~~~~~~~~~~~~~^~~~
+  No need to set variables to zero as calloc() does this for us.
   
-  Closes https://github.com/curl/curl/pull/3729
+  Closes #3879
 
-Marcel Raad (4 Apr 2019)
-- VS projects: use Unicode for VC10+
+Daniel Stenberg (14 May 2019)
+- CURLOPT_CAINFO.3: with Schannel, you want Windows 8 or later [ci skip]
   
-  All Windows APIs have been natively UTF-16 since Windows 2000 and the
-  non-Unicode variants are just wrappers around them. Only Windows 9x
-  doesn't understand Unicode without the UnicoWS DLL. As later Visual
-  Studio versions cannot target Windows 9x anyway, using the ANSI API
-  doesn't really have any benefit there.
+  Clues-provided-by: Jay Satiro
+  Clues-provided-by: Jeroen Ooms
+  Fixes #3711
+  Closes #3874
+
+Daniel Gustafsson (13 May 2019)
+- vtls: fix potential ssl_buffer stack overflow
   
-  This avoids issues like KNOWN_BUGS 6.5.
+  In Curl_multissl_version() it was possible to overflow the passed in
+  buffer if the generated version string exceeded the size of the buffer.
+  Fix by inverting the logic, and also make sure to not exceed the local
+  buffer during the string generation.
   
-  Ref: https://github.com/curl/curl/issues/2120
-  Closes https://github.com/curl/curl/pull/3720
+  Closes #3863
+  Reported-by: nevv on HackerOne/curl
+  Reviewed-by: Jay Satiro
+  Reviewed-by: Daniel Stenberg
 
-Daniel Gustafsson (3 Apr 2019)
+Daniel Stenberg (13 May 2019)
 - RELEASE-NOTES: synced
-  
-  Bump the version in progress to 7.64.2, if we merge any "change"
-  before the cut-off date we can update the version.
 
-- [Tim Rühsen brought this change]
+- appveyor: also build "/ci" branches like travis
 
-  documentation: Fix several typos
-  
-  Closes #3724
-  Reviewed-by: Jakub Zakrzewski
-  Reviewed-by: Daniel Gustafsson
+- pingpong: disable more when no pingpong enabled
 
-Jay Satiro (2 Apr 2019)
-- [Mert Yazıcıoğlu brought this change]
+- proxy: acknowledge DISABLE_PROXY more
 
-  vauth/oauth2: Fix OAUTHBEARER token generation
+- parsedate: CURL_DISABLE_PARSEDATE
+
+- sasl: only enable if there's a protocol enabled using it
+
+- mime: acknowledge CURL_DISABLE_MIME
+
+- wildcard: disable from build when FTP isn't present
+
+- http: CURL_DISABLE_HTTP_AUTH
+
+- base64: build conditionally if there are users
+
+- doh: CURL_DISABLE_DOH
+
+Steve Holme (12 May 2019)
+- auth: Rename the various authentication clean up functions
   
-  OAUTHBEARER tokens were incorrectly generated in a format similar to
-  XOAUTH2 tokens. These changes make OAUTHBEARER tokens conform to the
-  RFC7628.
+  For consistency and to a avoid confusion.
   
-  Fixes: #2487
-  Reported-by: Paolo Mossino
+  Closes #3869
+
+Daniel Stenberg (12 May 2019)
+- [Jay Satiro brought this change]
+
+  docs/INSTALL: fix broken link [ci skip]
   
-  Closes https://github.com/curl/curl/pull/3377
+  Reported-by: Joombalaya on github
+  Fixes #3818
 
-Marcel Raad (2 Apr 2019)
-- tool_cb_wrt: fix bad-function-cast warning
+Marcel Raad (12 May 2019)
+- easy: fix another "clarify calculation precedence" warning
   
-  Commit f5bc578f4cdfdc6c708211dfc2962a0e9d79352d reintroduced the
-  warning fixed in commit 2f5f31bb57d68b54e03bffcd9648aece1fe564f8.
-  Extend fhnd's scope and reuse that variable instead of calling
-  _get_osfhandle a second time to fix the warning again.
-  
-  Closes https://github.com/curl/curl/pull/3718
+  I missed this one in commit 6b3dde7fe62ea5a557fd1fd323fac2bcd0c2e9be.
 
-- VC15 project: remove MinimalRebuild
+- build: fix "clarify calculation precedence" warnings
   
-  Already done in commit d5cfefd0ea8e331b884186bff484210fad36e345 for the
-  library project, but I forgot the tool project template. Now also
-  removed for that.
-
-Dan Fandrich (1 Apr 2019)
-- cirrus: Customize the disabled tests per FreeBSD version
+  Codacy/CppCheck warns about this. Consistently use parentheses as we
+  already do in some places to silence the warning.
   
-  Try to run as many test cases as possible on each OS version.
-  12.0 passes 13 more tests than the older versions, so we might as well
-  run them.
+  Closes https://github.com/curl/curl/pull/3866
 
-Daniel Stenberg (1 Apr 2019)
-- tool_help: include <strings.h> for strcasecmp
+- cmake: restore C89 compatibility of CurlTests.c
   
-  Reported-by: Wyatt O'Day
-  Fixes #3715
-  Closes #3716
+  I broke it in d1b5cf830bfe169745721b21245d2217d2c2453e and
+  97de97daefc2ed084c91eff34af2426f2e55e134.
+  
+  Reported-by: Viktor Szakats
+  Ref: https://github.com/curl/curl/commit/97de97daefc2ed084c91eff34af2426f2e55e134#commitcomment-33499044
+  Closes https://github.com/curl/curl/pull/3868
 
-Daniel Gustafsson (31 Mar 2019)
-- scripts: fix typos
+Steve Holme (11 May 2019)
+- http_ntlm: Corrected the name of the include guard
+  
+  Missed in f0bdd72c.
+  
+  Closes #3867
 
-Dan Fandrich (28 Mar 2019)
-- travis: allow builds on branches named "ci"
+- http_digest: Don't expose functions when HTTP and Crypto Auth are disabled
   
-  This allows a way to test changes other than through PRs.
+  Closes #3861
 
-Daniel Stenberg (27 Mar 2019)
-- [Brad Spencer brought this change]
+- http_negotiate: Don't expose functions when HTTP is disabled
 
-  resolve: apply Happy Eyeballs philosophy to parallel c-ares queries
+Daniel Stenberg (11 May 2019)
+- SECURITY-PROCESS: fix links [ci skip]
+
+Marcel Raad (11 May 2019)
+- CMake: suppress unused variable warnings
   
-  Closes #3699
+  I missed these in commit d1b5cf830bfe169745721b21245d2217d2c2453e.
 
-- multi: improved HTTP_1_1_REQUIRED handling
+Daniel Stenberg (11 May 2019)
+- doh: disable DOH for the cases it doesn't work
   
-  Make sure to downgrade to 1.1 even when we get this HTTP/2 stream error
-  on first flight.
+  Due to limitations in Curl_resolver_wait_resolv(), it doesn't work for
+  DOH resolves. This fix disables DOH for those.
   
-  Reported-by: niner on github
-  Fixes #3696
-  Closes #3707
-
-- [Leonardo Taccari brought this change]
-
-  configure: avoid unportable `==' test(1) operator
+  Limitation added to KNOWN_BUGS.
   
-  Closes #3709
-
-Version 7.64.1 (27 Mar 2019)
-
-Daniel Stenberg (27 Mar 2019)
-- RELEASE: 7.64.1
+  Fixes #3850
+  Closes #3857
 
-- Revert "ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set"
+Jay Satiro (11 May 2019)
+- checksrc.bat: Ignore snprintf warnings in docs/examples
   
-  This reverts commit 9130ead9fcabdb6b8fbdb37c0b38be2d326adb00.
+  .. because we allow snprintf use in docs/examples.
   
-  Fixes #3708
-
-- [Christian Schmitz brought this change]
+  Closes https://github.com/curl/curl/pull/3862
 
-  ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set
+Steve Holme (10 May 2019)
+- vauth: Fix incorrect function description for Curl_auth_user_contains_domain()
   
-  Closes #3704
+  ...and misalignment of these comments. From a78c61a4.
+  
+  Closes #3860
 
-Jay Satiro (26 Mar 2019)
-- tool_cb_wrt: fix writing to Windows null device NUL
+Jay Satiro (10 May 2019)
+- Revert "multi: support verbose conncache closure handle"
   
-  - Improve console detection.
+  This reverts commit b0972bc.
   
-  Prior to this change WriteConsole could be called to write to a handle
-  that may not be a console, which would cause an error. This issue is
-  limited to character devices that are not also consoles such as the null
-  device NUL.
+  - No longer show verbose output for the conncache closure handle.
   
-  Bug: https://github.com/curl/curl/issues/3175#issuecomment-439068724
-  Reported-by: Gisle Vanem
-
-- CURLMOPT_PIPELINING.3: fix typo
-
-Daniel Stenberg (25 Mar 2019)
-- TODO: config file parsing
+  The offending commit was added so that the conncache closure handle
+  would inherit verbose mode from the user's easy handle. (Note there is
+  no way for the user to set options for the closure handle which is why
+  that was necessary.) Other debug settings such as the debug function
+  were not also inherited since we determined that could lead to crashes
+  if the user's per-handle private data was used on an unexpected handle.
   
-  Closes #3698
-
-Jay Satiro (24 Mar 2019)
-- os400: Disable Alt-Svc by default since it's experimental
+  The reporter here says he has a debug function to capture the verbose
+  output, and does not expect or want any output to stderr; however
+  because the conncache closure handle does not inherit the debug function
+  the verbose output for that handle does go to stderr.
   
-  Follow-up to 520f0b4 which added Alt-Svc support and enabled it by
-  default for OS400. Since the feature is experimental, it should be
-  disabled by default.
+  There are other plausible scenarios as well such as the user redirects
+  stderr on their handle, which is also not inherited since it could lead
+  to crashes when used on an unexpected handle.
   
-  Ref: https://github.com/curl/curl/commit/520f0b4#commitcomment-32792332
-  Ref: https://curl.haxx.se/mail/lib-2019-02/0008.html
+  Short of allowing the user to set options for the conncache closure
+  handle I don't think there's much we can safely do except no longer
+  inherit the verbose setting.
   
-  Closes https://github.com/curl/curl/pull/3688
-
-Dan Fandrich (24 Mar 2019)
-- tests: Fixed XML validation errors in some test files.
-
-- tests: Fix some incorrect precheck error messages.
+  Bug: https://curl.haxx.se/mail/lib-2019-05/0021.html
+  Reported-by: Kristoffer Gleditsch
   
-  [ci skip]
-
-Daniel Stenberg (22 Mar 2019)
-- curl_url.3: this is not experimental anymore
-
-- travis: bump the used wolfSSL version to 4.0.0
+  Ref: https://github.com/curl/curl/pull/3598
+  Ref: https://github.com/curl/curl/pull/3618
   
-  Test 311 is now fine, leaving only 313 (CRL) disabled.
+  Closes https://github.com/curl/curl/pull/3856
+
+Steve Holme (10 May 2019)
+- ntlm: Fix misaligned function comments for Curl_auth_ntlm_cleanup()
   
-  Test 313 details can be found here:
-  https://github.com/wolfSSL/wolfssl/issues/1546
+  From 6012fa5a.
   
-  Closes #3697
+  Closes #3858
 
-Daniel Gustafsson (22 Mar 2019)
-- lib: Fix typos in comments
+Daniel Stenberg (9 May 2019)
+- BUG-BOUNTY: minor formatting fixes [ci skip]
 
-David Woodhouse (20 Mar 2019)
-- openssl: if cert type is ENG and no key specified, key is ENG too
+- RELEASE-NOTES: synced
+
+- BUG-BOUNTY.md: add the Dropbox "bonus" extra payout ability [ci skip]
   
-  Fixes #3692
-  Closes #3692
+  Closes #3839
 
-Daniel Stenberg (20 Mar 2019)
-- sectransp: tvOS 11 is required for ALPN support
+Kamil Dudka (9 May 2019)
+- http_negotiate: do not treat failure of gss_init_sec_context() as fatal
   
-  Reported-by: nianxuejie on github
-  Assisted-by: Nick Zitzmann
-  Assisted-by: Jay Satiro
-  Fixes #3689
-  Closes #3690
+  Fixes #3726
+  Closes #3849
 
-- test1541: threaded connection sharing
+- spnego_gssapi: fix return code on gss_init_sec_context() failure
   
-  The threaded-shared-conn.c example turned into test case. Only works if
-  pthread was detected.
+  Fixes #3726
+  Closes #3849
+
+Steve Holme (9 May 2019)
+- gen_resp_file.bat: Removed unnecessary @ from all but the first command
   
-  An attempt to detect future regressions such as e3a53e3efb942a5
+  There is need to use @ on every command once echo has been turned off.
   
-  Closes #3687
+  Closes #3854
 
-Patrick Monnerat (17 Mar 2019)
-- os400: alt-svc support.
+Jay Satiro (8 May 2019)
+- http: Ignore HTTP/2 prior knowledge setting for HTTP proxies
   
-  Although experimental, enable it in the platform config file.
-  Upgrade ILE/RPG binding.
-
-Daniel Stenberg (17 Mar 2019)
-- conncache: use conn->data to know if a transfer owns it
+  - Do not switch to HTTP/2 for an HTTP proxy that is not tunnelling to
+    the destination host.
   
-  - make sure an already "owned" connection isn't returned unless
-    multiplexed.
+  We already do something similar for HTTPS proxies by not sending h2. [1]
   
-  - clear ->data when returning the connection to the cache again
+  Prior to this change setting CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE would
+  incorrectly use HTTP/2 to talk to the proxy, which is not something we
+  support (yet?). Also it's debatable whether or not that setting should
+  apply to HTTP/2 proxies.
   
-  Regression since 7.62.0 (probably in commit 1b76c38904f0)
+  [1]: https://github.com/curl/curl/commit/17c5d05
   
-  Bug: https://curl.haxx.se/mail/lib-2019-03/0064.html
+  Bug: https://github.com/curl/curl/issues/3570
+  Bug: https://github.com/curl/curl/issues/3832
   
-  Closes #3686
+  Closes https://github.com/curl/curl/pull/3853
 
-- RELEASE-NOTES: synced
+Marcel Raad (8 May 2019)
+- travis: update mesalink build to xenial
+  
+  Closes https://github.com/curl/curl/pull/3842
 
-- [Chris Young brought this change]
+Daniel Stenberg (8 May 2019)
+- [Ricky Leverence brought this change]
 
-  configure: add --with-amissl
+  OpenSSL: Report -fips in version if OpenSSL is built with FIPS
   
-  AmiSSL is an Amiga native library which provides a wrapper over OpenSSL.
-  It also requires all programs using it to use bsdsocket.library
-  directly, rather than accessing socket functions through clib, which
-  libcurl was not necessarily doing previously. Configure will now check
-  for the headers and ensure they are included if found.
+  Older versions of OpenSSL report FIPS availabilty via an OPENSSL_FIPS
+  define. It uses this define to determine whether to publish -fips at
+  the end of the version displayed. Applications that utilize the version
+  reported by OpenSSL will see a mismatch if they compare it to what curl
+  reports, as curl is not modifying the version in the same way. This
+  change simply adds a check to see if OPENSSL_FIPS is defined, and will
+  alter the reported version to match what OpenSSL itself provides. This
+  only appears to be applicable in versions of OpenSSL <1.1.1
   
-  Closes #3677
+  Closes #3771
 
-- [Chris Young brought this change]
+Kamil Dudka (7 May 2019)
+- [Frank Gevaerts brought this change]
 
-  vtls: rename some of the SSL functions
+  nss: allow fifos and character devices for certificates.
   
-  ... in the SSL structure as AmiSSL is using macros for the socket API
-  functions.
-
-- [Chris Young brought this change]
-
-  tool_getpass: termios.h is present on AmigaOS 3, but no tcgetattr/tcsetattr
-
-- [Chris Young brought this change]
-
-  tool_operate: build on AmigaOS
-
-- makefile: make checksrc and hugefile commands "silent"
+  Currently you can do things like --cert <(cat ./cert.crt) with (at least) the
+  openssl backend, but that doesn't work for nss because is_file rejects fifos.
   
-  ... to match the style already used for compiling, linking
-  etc. Acknowledges 'make V=1' to enable verbose.
+  I don't actually know if this is sufficient, nss might do things internally
+  (like seeking back) that make this not work, so actual testing is needed.
   
-  Closes #3681
+  Closes #3807
 
-- curl.1: --user and --proxy-user are hidden from ps output
+Daniel Gustafsson (6 May 2019)
+- test2100: Fix typos in test description
+
+Daniel Stenberg (6 May 2019)
+- ssh: define USE_SSH if SSH is enabled (any backend)
   
-  Suggested-by: Eric Curtin
-  Improved-by: Dan Fandrich
-  Ref: #3680
+  Closes #3846
+
+Steve Holme (5 May 2019)
+- winbuild: Add our standard copyright header to the winbuild batch files
+
+- makedebug: Fix ERRORLEVEL detection after running where.exe
   
-  Closes #3683
+  Closes #3838
 
-- curl.1: mark the argument to --cookie as <data|filename>
+Daniel Stenberg (5 May 2019)
+- urlapi: add CURLUPART_ZONEID to set and get
   
-  From a discussion in #3676
+  The zoneid can be used with IPv6 numerical addresses.
   
-  Suggested-by: Tim Rühsen
+  Updated test 1560 to verify.
   
-  Closes #3682
-
-Dan Fandrich (14 Mar 2019)
-- fuzzer: Only clone the latest fuzzer code, for speed.
+  Closes #3834
 
-Daniel Stenberg (14 Mar 2019)
-- [Dominik Hölzl brought this change]
+- [Taiyu Len brought this change]
 
-  Negotiate: fix for HTTP POST with Negotiate
-  
-  * Adjusted unit tests 2056, 2057
-  * do not generally close connections with CURLAUTH_NEGOTIATE after every request
-  * moved negotiatedata from UrlState to connectdata
-  * Added stream rewind logic for CURLAUTH_NEGOTIATE
-  * introduced negotiatedata::GSS_AUTHDONE and negotiatedata::GSS_AUTHSUCC
-  * Consider authproblem state for CURLAUTH_NEGOTIATE
-  * Consider reuse_forbid for CURLAUTH_NEGOTIATE
-  * moved and adjusted negotiate authentication state handling from
-    output_auth_headers into Curl_output_negotiate
-  * Curl_output_negotiate: ensure auth done is always set
-  * Curl_output_negotiate: Set auth done also if result code is
-    GSS_S_CONTINUE_NEEDED/SEC_I_CONTINUE_NEEDED as this result code may
-    also indicate the last challenge request (only works with disabled
-    Expect: 100-continue and CURLOPT_KEEP_SENDING_ON_ERROR -> 1)
-  * Consider "Persistent-Auth" header, detect if not present;
-    Reset/Cleanup negotiate after authentication if no persistent
-    authentication
-  * apply changes introduced with #2546 for negotiate rewind logic
+  WRITEFUNCTION: add missing set_in_callback around callback
   
-  Fixes #1261
-  Closes #1975
+  Closes #3837
 
-- [Marc Schlatter brought this change]
+- RELEASE-NOTES: synced
 
-  http: send payload when (proxy) authentication is done
-  
-  The check that prevents payload from sending in case of authentication
-  doesn't check properly if the authentication is done or not.
+- CURLMOPT_TIMERFUNCTION.3: warn about the recursive risk [ci skip]
   
-  They're cases where the proxy respond "200 OK" before sending
-  authentication challenge. This change takes care of that.
+  Reported-by: Ricardo Gomes
   
-  Fixes #2431
-  Closes #3669
+  Bug: #3537
+  Closes #3836
 
-- file: fix "Checking if unsigned variable 'readcount' is less than zero."
+- CURLOPT_CHUNK_BGN_FUNCTION.3: document the struct and time value
   
-  Pointed out by codacy
+  The time field in the curl_fileinfo struct will always be zero. No code
+  was ever implemented to actually convert the date string to a time_t.
   
-  Closes #3672
+  Fixes #3829
+  Closes #3835
 
-- memdebug: log pointer before freeing its data
+- OS400/ccsidcurl.c: code style fixes
+
+- OS400/ccsidcurl: replace use of Curl_vsetopt
   
-  Coverity warned for two potentional "Use after free" cases. Both are false
-  positives because the memory wasn't used, it was only the actual pointer
-  value that was logged.
+  (and make the code style comply)
   
-  The fix still changes the order of execution to avoid the warnings.
+  Fixes #3833
+
+- urlapi: strip off scope id from numerical IPv6 addresses
   
-  Coverity CID 1443033 and 1443034
+  ... to make the host name "usable". Store the scope id and put it back
+  when extracting a URL out of it.
   
-  Closes #3671
+  Also makes curl_url_set() syntax check CURLUPART_HOST.
+  
+  Fixes #3817
+  Closes #3822
 
 - RELEASE-NOTES: synced
 
-Marcel Raad (12 Mar 2019)
-- travis: actually use updated compiler versions
-  
-  For the Linux builds, GCC 8 and 7 and clang 7 were installed, but the
-  new GCC versions were only used for the coverage build and for building
-  nghttp2, while the new clang version was not used at all.
-  
-  BoringSSL needs to use the default GCC as it respects CC, but not CXX,
-  so it would otherwise pass gcc 8 options to g++ 4.8 and fail.
-  
-  Also remove GCC 7, it's not needed anymore.
+- multiif.h: remove unused protos
   
-  Ref: https://docs.travis-ci.com/user/languages/c/#c11c11-and-beyond-and-toolchain-versioning
+  ... for functions related to pipelining. Those functions were removed in
+  2f44e94efb3df.
   
-  Closes https://github.com/curl/curl/pull/3670
+  Closes #3828
 
-- travis: update clang to version 7
+- [Yiming Jing brought this change]
+
+  travis: mesalink: temporarily disable test 3001
   
-  Closes https://github.com/curl/curl/pull/3670
+  ... due to SHA-1 signatures in test certs
 
-Jay Satiro (11 Mar 2019)
-- [Andre Guibert de Bruet brought this change]
+- [Yiming Jing brought this change]
 
-  examples/externalsocket: add missing close socket calls
-  
-  .. and for Windows also call WSACleanup since we call WSAStartup.
-  
-  The example is to demonstrate handling the socket independently of
-  libcurl. In this case libcurl is not responsible for creating, opening
-  or closing the socket, it is handled by the application (our example).
+  travis: upgrade the MesaLink TLS backend to v1.0.0
   
-  Fixes https://github.com/curl/curl/pull/3663
+  Closes #3823
+  Closes #3776
 
-Daniel Stenberg (11 Mar 2019)
-- multi: removed unused code for request retries
+- ConnectionExists: improve non-multiplexing use case
   
-  This code was once used for the non multi-interface using code path, but
-  ever since easy_perform was turned into a wrapper around the multi
-  interface, this code path never runs.
+  - better log output
   
-  Closes #3666
+  - make sure multiplex is enabled for it to be used
 
-Jay Satiro (11 Mar 2019)
-- doh: inherit some SSL options from user's easy handle
-  
-  - Inherit SSL options for the doh handle but not SSL client certs,
-    SSL ALPN/NPN, SSL engine, SSL version, SSL issuer cert,
-    SSL pinned public key, SSL ciphers, SSL id cache setting,
-    SSL kerberos or SSL gss-api settings.
-  
-  - Fix inheritance of verbose setting.
-  
-  - Inherit NOSIGNAL.
-  
-  There is no way for the user to set options for the doh (DNS-over-HTTPS)
-  handles and instead we inherit some options from the user's easy handle.
-  
-  My thinking for the SSL options not inherited is they are most likely
-  not intended by the user for the DOH transfer. I did inherit insecure
-  because I think that should still be in control of the user.
-  
-  Prior to this change doh did not work for me because CAINFO was not
-  inherited. Also verbose was set always which AFAICT was a bug (#3660).
+- multi: provide Curl_multiuse_state to update information
   
-  Fixes https://github.com/curl/curl/issues/3660
-  Closes https://github.com/curl/curl/pull/3661
+  As soon as a TLS backend gets ALPN conformation about the specific HTTP
+  version it can now set the multiplex situation for the "bundle" and
+  trigger moving potentially queued up transfers to the CONNECT state.
 
-Daniel Stenberg (9 Mar 2019)
-- test331: verify set-cookie for dotless host name
+- process_pending_handles: mark queued transfers as previously pending
   
-  Reproduced bug #3649
-  Closes #3659
+  With transfers being queued up, we only move one at a a time back to the
+  CONNECT state but now we mark moved transfers so that when a moved
+  transfer is confirmed "successful" (it connected) it will trigger the
+  move of another pending transfer. Previously, it would otherwise wait
+  until the transfer was done before doing this. This makes queued up
+  pending transfers get processed (much) faster.
 
-- Revert "cookies: extend domain checks to non psl builds"
-  
-  This reverts commit 3773de378d48b06c09931e44dca4d274d0bfdce0.
+- http: mark bundle as not for multiuse on < HTTP/2 response
   
-  Regression shipped in 7.64.0
-  Fixes #3649
+  Fixes #3813
+  Closes #3815
 
-- memdebug: make debug-specific functions use curl_dbg_ prefix
+Daniel Gustafsson (1 May 2019)
+- cookie: Guard against possible NULL ptr deref
   
-  To not "collide" or use up the regular curl_ name space. Also makes them
-  easier to detect in helper scripts.
+  In case the name pointer isn't set (due to memory pressure most likely)
+  we need to skip the prefix matching and reject with a badcookie to avoid
+  a possible NULL pointer dereference.
   
-  Closes #3656
+  Closes #3820 #3821
+  Reported-by: Jonathan Moerman
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- cmdline-opts/proxytunnel.d: the option tunnnels all protocols
-  
-  Clarify the language and simplify.
-  
-  Reported-by: Daniel Lublin
-  Closes #3658
+Patrick Monnerat (30 Apr 2019)
+- os400: Add CURLOPT_MAXAGE_CONN to ILE/RPG bindings
 
-- KNOWN_BUGS: Client cert (MTLS) issues with Schannel
+Kamil Dudka (29 Apr 2019)
+- nss: provide more specific error messages on failed init
   
-  Closes #3145
-
-- ROADMAP: updated to some more current things to work on
-
-- tests: fix multiple may be used uninitialized warnings
+  Closes #3808
 
-- RELEASE-NOTES: synced
+Daniel Stenberg (29 Apr 2019)
+- [Reed Loden brought this change]
 
-- source: fix two 'nread' may be used uninitialized warnings
-  
-  Both seem to be false positives but we don't like warnings.
+  docs: minor polish to the bug bounty / security docs
   
-  Closes #3646
+  Closes #3811
 
-- gopher: remove check for path == NULL
+- CURL_MAX_INPUT_LENGTH: largest acceptable string input size
   
-  Since it can't be NULL and it makes Coverity believe we lack proper NULL
-  checks. Verified by test 659, landed in commit 15401fa886b.
+  This limits all accepted input strings passed to libcurl to be less than
+  CURL_MAX_INPUT_LENGTH (8000000) bytes, for these API calls:
+  curl_easy_setopt() and curl_url_set().
   
-  Pointed out by Coverity CID 1442746.
-  
-  Assisted-by: Dan Fandrich
-  Fixes #3617
-  Closes #3642
-
-- examples: only include <curl/curl.h>
-  
-  That's the only public curl header we should encourage use of.
-  
-  Reviewed-by: Marcel Raad
-  Closes #3645
-
-- ssh: loop the state machine if not done and not blocking
+  The 8000000 number is arbitrary picked and is meant to detect mistakes
+  or abuse, not to limit actual practical use cases. By limiting the
+  acceptable string lengths we also reduce the risk of integer overflows
+  all over.
   
-  If the state machine isn't complete, didn't fail and it didn't return
-  due to blocking it can just as well loop again.
+  NOTE: This does not apply to `CURLOPT_POSTFIELDS`.
   
-  This addresses the problem with SFTP directory listings where we would
-  otherwise return back to the parent and as the multi state machine
-  doesn't have any code for using CURLM_CALL_MULTI_PERFORM for as long the
-  doing phase isn't complete, it would return out when in reality there
-  was more data to deal with.
+  Test 1559 verifies.
   
-  Fixes #3506
-  Closes #3644
+  Closes #3805
 
-Jay Satiro (5 Mar 2019)
-- multi: support verbose conncache closure handle
-  
-  - Change closure handle to receive verbose setting from the easy handle
-    most recently added via curl_multi_add_handle.
-  
-  The closure handle is a special easy handle used for closing cached
-  connections. It receives limited settings from the easy handle most
-  recently added to the multi handle. Prior to this change that did not
-  include verbose which was a problem because on connection shutdown
-  verbose mode was not acknowledged.
-  
-  Ref: https://github.com/curl/curl/pull/3598
-  
-  Co-authored-by: Daniel Stenberg
-  
-  Closes https://github.com/curl/curl/pull/3618
+- [Tseng Jun brought this change]
 
-Daniel Stenberg (4 Mar 2019)
-- CURLU: fix NULL dereference when used over proxy
-  
-  Test 659 verifies
-  
-  Also fixed the test 658 name
+  curlver.h: use parenthesis in CURL_VERSION_BITS macro
   
-  Closes #3641
+  Closes #3809
 
-- altsvc_out: check the return code from Curl_gmtime
-  
-  Pointed out by Coverity, CID 1442956.
-  
-  Closes #3640
+Marcel Raad (27 Apr 2019)
+- [Simon Warta brought this change]
 
-- docs/ALTSVC.md: docs describing the approach
+  cmake: rename CMAKE_USE_DARWINSSL to CMAKE_USE_SECTRANSP
   
-  Closes #3498
+  Closes https://github.com/curl/curl/pull/3769
 
-- alt-svc: add a travis build
+Steve Holme (23 Apr 2019)
+- ntlm: Missed pre-processor || (or) during rebase for cd15acd0
 
-- alt-svc: add test 355 and 356 to verify with command line curl
+- ntlm: Support the NT response in the type-3 when OpenSSL doesn't include MD4
+  
+  Just like we do for mbed TLS, use our local implementation of MD4 when
+  OpenSSL doesn't support it. This allows a type-3 message to include the
+  NT response.
 
-- alt-svc: the curl command line bits
+Daniel Gustafsson (23 Apr 2019)
+- INTERNALS: fix misindentation of ToC item
+  
+  Kerberos was incorrectly indented as a subsection under FTP, which is
+  incorrect as they are both top level sections. A fix for this was first
+  attempted in commit fef38a0898322f285401c5ff2f5e7c90dbf3be63 but that
+  was a few paddles short of being complete.
 
-- alt-svc: the libcurl bits
+- [Aron Bergman brought this change]
 
-- travis: add build using gnutls
+  INTERNALS: Add structs to ToC
   
-  Closes #3637
-
-- RELEASE-NOTES: synced
+  Add the subsections under "Structs in libcurl" to the table of contents.
+  
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-- [Simon Legner brought this change]
+- [Aron Bergman brought this change]
 
-  scripts/completion.pl: also generate fish completion file
+  INTERNALS: Add code highlighting
   
-  This is the renamed script formerly known as zsh.pl
+  Make all struct members under the Curl_handler section
+  print in monospace font.
   
-  Closes #3545
+  Closes #3801
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-- gnutls: remove call to deprecated gnutls_compression_get_name
+Daniel Stenberg (22 Apr 2019)
+- docs/BUG-BOUNTY: bug bounty time [skip ci]
   
-  It has been deprecated by GnuTLS since a year ago and now causes build
-  warnings.
+  Introducing the curl bug bounty program on hackerone. We now recommend
+  filing security issues directly in the hackerone ticket system which
+  only is readable to curl security team members.
   
-  Ref: https://gitlab.com/gnutls/gnutls/commit/b0041897d2846737f5fb0f
-  Docs: https://www.gnutls.org/manual/html_node/Compatibility-API.html
+  Assisted-by: Daniel Gustafsson
   
-  Closes #3636
+  Closes #3488
 
-Jay Satiro (2 Mar 2019)
-- system_win32: move win32_init here from easy.c
+Steve Holme (22 Apr 2019)
+- sasl: Don't send authcid as authzid for the PLAIN mechanism as per RFC 4616
   
-  .. since system_win32 is a more appropriate location for the functions
-  and to extern the globals.
+  RFC 4616 specifies the authzid is optional in the client authentication
+  message and that the server will derive the authorisation identity
+  (authzid) from the authentication identity (authcid) when not specified
+  by the client.
+
+Jay Satiro (22 Apr 2019)
+- [Gisle Vanem brought this change]
+
+  memdebug: fix variable name
   
-  Ref: https://github.com/curl/curl/commit/ca597ad#r32446578
-  Reported-by: Gisle Vanem
+  Follow-up to 76b6348 which renamed logfile as curl_dbg_logfile.
   
-  Closes https://github.com/curl/curl/pull/3625
+  Ref: https://github.com/curl/curl/commit/76b6348#r33259088
 
-Daniel Stenberg (1 Mar 2019)
-- curl_easy_duphandle.3: clarify that a duped handle has no shares
-  
-  Reported-by: Sara Golemon
+Steve Holme (21 Apr 2019)
+- vauth/cleartext: Don't send the authzid if it is empty
   
-  Fixes #3592
-  Closes #3634
+  Follow up to 762a292f.
 
-- 10-at-a-time.c: fix too long line
+Daniel Stenberg (21 Apr 2019)
+- test 196,197,198: add 'retry' keyword [skip ci]
 
-- [Arnaud Rebillout brought this change]
+- RELEASE-NOTES: synced
 
-  examples: various fixes in ephiperfifo.c
+- CURLOPT_MAXAGE_CONN: set the maximum allowed age for conn reuse
   
-  The main change here is the timer value that was wrong, it was given in
-  usecs (ms * 1000), while the itimerspec struct wants nsecs (ms * 1000 *
-  1000). This resulted in the callback being invoked WAY TOO OFTEN.
+  ... and disconnect too old ones instead of trying to reuse.
   
-  As a quick check you can run this command before and after applying this
-  commit:
+  Default max age is set to 118 seconds.
   
-      # shell 1
-      ./ephiperfifo 2>&1 | tee ephiperfifo.log
-      # shell 2
-      echo http://hacking.elboulangero.com > hiper.fifo
+  Ref: #3722
+  Closes #3782
+
+Daniel Gustafsson (20 Apr 2019)
+- [Po-Chuan Hsieh brought this change]
+
+  altsvc: Fix building with cookies disables
   
-  Then just compare the size of the logs files.
+  ALTSVC requires Curl_get_line which is defined in lib/cookie.c inside a #if
+  check of HTTP and COOKIES. That makes Curl_get_line undefined if COOKIES is
+  disabled. Fix by splitting out the function into a separate file which can
+  be included where needed.
   
-  Closes #3633
-  Fixes #3632
-  Signed-off-by: Arnaud Rebillout <arnaud.rebillout@collabora.com>
+  Closes #3717
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
 
-- urldata: simplify bytecounters
-  
-  - no need to have them protocol specific
+Daniel Stenberg (20 Apr 2019)
+- test1002: correct the name [skip ci]
+
+- test660: verify CONNECT_ONLY with IMAP
   
-  - no need to set pointers to them with the Curl_setup_transfer() call
+  which basically just makes sure LOGOUT is *not* issued on disconnect
+
+- Curl_disconnect: treat all CONNECT_ONLY connections as "dead"
   
-  - make Curl_setup_transfer() operate on a transfer pointer, not
-    connection
+  Since the connection has been used by the "outside" we don't know the
+  state of it anymore and curl should not use it anymore.
   
-  - switch some counters from long to the more proper curl_off_t type
+  Bug: https://curl.haxx.se/mail/lib-2019-04/0052.html
   
-  Closes #3627
+  Closes #3795
 
-- examples/10-at-a-time.c: improve readability and simplify
+- multi: fix the statenames (follow-up fix from 2f44e94efb3df8e)
   
-   - use better variable names to explain their purposes
-   - convert logic to curl_multi_wait()
+  The list of names must be in sync with the defined states in the header
+  file!
 
-- threaded-resolver: shutdown the resolver thread without error message
-  
-  When a transfer is done, the resolver thread will be brought down. That
-  could accidentally generate an error message in the error buffer even
-  though this is not an error situationand the transfer would still return
-  OK.  An application that still reads the error buffer could find a
-  "Could not resolve host: [host name]" message there and get confused.
+Steve Holme (16 Apr 2019)
+- openvms: Remove pre-processors for Windows as VMS cannot support them
+
+- openvms: Remove pre-processor for SecureTransport as VMS cannot support it
   
-  Reported-by: Michael Schmid
-  Fixes #3629
-  Closes #3630
+  Fixes #3768
+  Closes #3785
 
-- [Ԝеѕ brought this change]
+Jay Satiro (16 Apr 2019)
+- TODO: Add issue link to an existing entry
 
-  docs: update max-redirs.d phrasing
-  
-  clarify redir - "in absurdum" doesn't seem to make sense in this context
-  
-  Closes #3631
+Daniel Stenberg (16 Apr 2019)
+- RELEASE-NOTES: synced
 
-- ssh: fix Condition '!status' is always true
+Jay Satiro (16 Apr 2019)
+- tool_help: Warn if curl and libcurl versions do not match
   
-  in the same sftp_done function in both SSH backends. Simplify them
-  somewhat.
+  .. because functionality may be affected if the versions differ.
   
-  Pointed out by Codacy.
+  This commit implements TODO 18.7 "warning if curl version is not in sync
+  with libcurl version".
   
-  Closes #3628
+  Ref: https://github.com/curl/curl/blob/curl-7_64_1/docs/TODO#L1028-L1033
+  
+  Closes https://github.com/curl/curl/pull/3774
 
-- test578: make it read data from the correct test
+Steve Holme (16 Apr 2019)
+- md5: Update the function signature following d84da52d
 
-- Curl_easy: remove req.maxfd - never used!
+- md5: Forgot to update the code alignment in d84da52d
+
+- md5: Return CURLcode from the internally accessible functions
   
-  Introduced in 8b6314ccfb, but not used anymore in current code. Unclear
-  since when.
+  Following 28f826b3 to return CURLE_OK instead of numeric 0.
+
+Daniel Gustafsson (15 Apr 2019)
+- tests: Run global cleanup at end of tests
   
-  Closes #3626
+  Make sure to run curl_global_cleanup() when shutting down the test
+  suite to release any resources allocated in the SSL setup. This is
+  clearly visible when running tests with PolarSSL where the thread
+  lock calloc() memory which isn't released when not running cleanup.
+  Below is an excerpt from the autobuild logs:
+  
+    ==12368== 96 bytes in 1 blocks are possibly lost in loss record 1 of 2
+    ==12368== at 0x4837B65: calloc (vg_replace_malloc.c:752)
+    ==12368== by 0x11A76E: curl_dbg_calloc (memdebug.c:205)
+    ==12368== by 0x145CDF: Curl_polarsslthreadlock_thread_setup
+                           (polarssl_threadlock.c:54)
+    ==12368== by 0x145B37: Curl_polarssl_init (polarssl.c:865)
+    ==12368== by 0x14129D: Curl_ssl_init (vtls.c:171)
+    ==12368== by 0x118B4C: global_init (easy.c:158)
+    ==12368== by 0x118BF5: curl_global_init (easy.c:221)
+    ==12368== by 0x118D0B: curl_easy_init (easy.c:299)
+    ==12368== by 0x114E96: test (lib1906.c:32)
+    ==12368== by 0x115495: main (first.c:174)
+  
+  Closes #3783
+  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- http: set state.infilesize when sending formposts
+Marcel Raad (15 Apr 2019)
+- travis: use mbedtls from Xenial
   
-  Without it set, we would unwillingly triger the "HTTP error before end
-  of send, stop sending" condition even if the entire POST body had been
-  sent (since it wouldn't know the expected size) which would
-  unnecessarily log that message and close the connection when it didn't
-  have to.
+  No need to build it from source anymore.
   
-  Reported-by: Matt McClure
-  Bug: https://curl.haxx.se/mail/archive-2019-02/0023.html
-  Closes #3624
+  Closes https://github.com/curl/curl/pull/3779
 
-- INSTALL: refer to the current TLS library names and configure options
+- travis: use libpsl from Xenial
+  
+  This makes building libpsl and libidn2 from source unnecessary and
+  removes the need for the autopoint and libunistring-dev packages.
+  
+  Closes https://github.com/curl/curl/pull/3779
 
-- FAQ: minor updates and spelling fixes
+Daniel Stenberg (15 Apr 2019)
+- runtests: start socksd like other servers
+  
+  ... without a $srcdir prefix. Triggered by the failures in several
+  autobuilds.
+  
+  Closes #3781
 
-- GOVERNANCE.md: minor spelling fixes
+Daniel Gustafsson (14 Apr 2019)
+- socksd: Fix typos
+  
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- Secure Transport: no more "darwinssl"
+- socksd: Properly decorate static variables
   
-  Everyone calls it Secure Transport, now we do too.
+  Mark global variables static to avoid compiler warning in Clang when
+  using -Wmissing-variable-declarations.
   
-  Reviewed-by: Nick Zitzmann
+  Closes #3778
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+
+Steve Holme (14 Apr 2019)
+- md(4|5): Fixed indentation oddities with the importation of replacement code
   
-  Closes #3619
+  The indentation from 211d5329 and 57d6d253 was a little strange as
+  parts didn't align correctly, uses 4 spaces rather than 2. Checked
+  the indentation of the original source so it aligns, albeit, using
+  curl style.
 
-Marcel Raad (27 Feb 2019)
-- AppVeyor: add classic MinGW build
+- md5: Code style to return CURLE_OK rather than numeric 0
+
+- md5: Corrected code style for some pointer arguments
+
+Marcel Raad (13 Apr 2019)
+- travis: update some builds to xenial
   
-  But use the MSYS2 shell rather than the default MSYS shell because of
-  POSIX path conversion issues. Classic MinGW is only available on the
-  Visual Studio 2015 image.
+  Xenial comes with more up-to-date software versions and more available
+  packages, some of which we currently build from source. Unfortunately,
+  some builds would fail with Xenial because of assertion failures in
+  Valgrind when using OpenSSL, so leave these at Trusty.
   
-  Closes https://github.com/curl/curl/pull/3623
+  Closes https://github.com/curl/curl/pull/3777
 
-- AppVeyor: add MinGW-w64 build
-  
-  Add a MinGW-w64 build using CMake's MSYS Makefiles generator.
-  Use the Visual Studio 2015 image as it has GCC 8, while the
-  Visual Studio 2017 image only has GCC 7.2.
+Daniel Stenberg (13 Apr 2019)
+- test: make tests and test scripts use socksd for SOCKS
   
-  Closes https://github.com/curl/curl/pull/3623
+  Make all SOCKS tests use socksd instead of ssh.
 
-Daniel Stenberg (27 Feb 2019)
-- cookies: only save the cookie file if the engine is enabled
+- socksd: new SOCKS 4+5 server for tests
   
-  Follow-up to 8eddb8f4259.
+  Closes #3752
+
+- singleipconnect: show port in the verbose "Trying ..." message
   
-  If the cookieinfo pointer is NULL there really is nothing to save.
+  To aid debugging better.
+
+- [tmilburn brought this change]
+
+  CURLOPT_ADDRESS_SCOPE: fix range check and more
   
-  Without this fix, we got a problem when a handle was using shared object
-  with cookies and is told to "FLUSH" it to file (which worked) and then
-  the share object was removed and when the easy handle was closed just
-  afterwards it has no cookieinfo and no cookies so it decided to save an
-  empty jar (overwriting the file just flushed).
+  Commit 9081014 fixed most of the confusing issues between scope id and
+  scope however 844896d added bad limits checking assuming that the scope
+  is being set and not the scope id.
   
-  Test 1905 now verifies that this works.
+  I have fixed the documentation so it all refers to scope ids.
   
-  Assisted-by: Michael Wallner
-  Assisted-by: Marcel Raad
+  In addition Curl_if2ip refered to the scope id as remote_scope_id which
+  is incorrect, so I renamed it to local_scope_id.
   
-  Closes #3621
-
-- [DaVieS brought this change]
-
-  cacertinmem.c: use multiple certificates for loading CA-chain
+  Adjusted-by: Daniel Stenberg
   
-  Closes #3421
+  Closes #3655
+  Closes #3765
+  Fixes #3713
 
-- urldata: convert bools to bitfields and move to end
+- urlapi: stricter CURLUPART_PORT parsing
   
-  This allows the compiler to pack and align the structs better in
-  memory. For a rather feature-complete build on x86_64 Linux, gcc 8.1.2
-  makes the Curl_easy struct 4.9% smaller. From 6312 bytes to 6000.
+  Only allow well formed decimal numbers in the input.
   
-  Removed an unused struct field.
+  Document that the number MUST be between 1 and 65535.
   
-  No functionality changes.
+  Add tests to test 1560 to verify the above.
   
-  Closes #3610
+  Ref: https://github.com/curl/curl/issues/3753
+  Closes #3762
 
-- [Don J Olmstead brought this change]
+Jay Satiro (13 Apr 2019)
+- [Jan Ehrhardt brought this change]
 
-  curl.h: use __has_declspec_attribute for shared builds
+  winbuild: Support MultiSSL builds
   
-  Closes #3616
-
-- curl: display --version features sorted alphabetically
+  - Remove the lines in winbuild/Makefile.vc that generate an error with
+    multiple SSL backends.
   
-  Closes #3611
+  - Add /DCURL_WITH_MULTI_SSL in winbuild/MakefileBuild.vc if multiple SSL
+    backends are set.
+  
+  Closes https://github.com/curl/curl/pull/3772
 
-- runtests: detect "schannel" as an alias for "winssl"
+Daniel Stenberg (12 Apr 2019)
+- travis: remove mesalink builds (temporarily?)
   
-  Follow-up to 180501cb02
+  Since the mesalink build started to fail on travis, even though we build
+  a fixed release version, we disable it to prevent it from blocking
+  progress.
   
-  Reported-by: Marcel Raad
-  Fixes #3609
-  Closes #3620
+  Closes #3767
 
-Marcel Raad (26 Feb 2019)
-- AppVeyor: update to Visual Studio 2017
+- openssl: mark connection for close on TLS close_notify
   
-  Switch all Visual Studio 2015 builds to Visual Studio 2017. It's not a
-  moving target anymore as the last update, Update 9, has been released.
+  Without this, detecting and avoid reusing a closed TLS connection
+  (without a previous GOAWAY) when doing HTTP/2 is tricky.
   
-  Closes https://github.com/curl/curl/pull/3606
+  Reported-by: Tom van der Woerdt
+  Fixes #3750
+  Closes #3763
 
-- AppVeyor: switch VS 2015 builds to VS 2017 image
+- RELEASE-NOTES: synced
+
+Steve Holme (11 Apr 2019)
+- vauth/cleartext: Update the PLAIN login function signature to match RFC 4616
   
-  The Visual Studio 2017 image has Visual Studio 2015 and 2017 installed.
+  Functionally this doesn't change anything as we still use the username
+  for both the authorisation identity and the authentication identity.
   
-  Closes https://github.com/curl/curl/pull/3606
+  Closes #3757
 
-- AppVeyor: explicitly select worker image
-  
-  Currently, we're using the default Visual Studio 2015 image for
-  everything.
+Daniel Stenberg (11 Apr 2019)
+- test1906: verify CURLOPT_CURLU + CURLOPT_PORT usage
   
-  Closes https://github.com/curl/curl/pull/3606
+  Based-on-code-by: Poul T Lomholt
 
-Daniel Stenberg (26 Feb 2019)
-- strerror: make the strerror function use local buffers
+- url: always clone the CUROPT_CURLU handle
   
-  Instead of using a fixed 256 byte buffer in the connectdata struct.
+  Since a few code paths actually update that data.
   
-  In my build, this reduces the size of the connectdata struct by 11.8%,
-  from 2160 to 1904 bytes with no functionality or performance loss.
+  Fixes #3753
+  Closes #3761
   
-  This also fixes a bug in schannel's Curl_verify_certificate where it
-  called Curl_sspi_strerror when it should have called Curl_strerror for
-  string from GetLastError. the only effect would have been no text or the
-  wrong text being shown for the error.
+  Reported-by: Poul T Lomholt
+
+- CURLOPT_DNS_USE_GLOBAL_CACHE: remove
   
-  Co-authored-by: Jay Satiro
+  Remove the code too. The functionality has been disabled in code since
+  7.62.0. Setting this option will from now on simply be ignored and have
+  no function.
   
-  Closes #3612
-
-- [Michael Wallner brought this change]
+  Closes #3654
 
-  cookies: fix NULL dereference if flushing cookies with no CookieInfo set
+Marcel Raad (11 Apr 2019)
+- travis: install libgnutls28-dev only for --with-gnutls build
   
-  Regression brought by a52e46f3900fb0 (shipped in 7.63.0)
+  Reduces the time needed for the other jobs a little.
   
-  Closes #3613
+  Closes https://github.com/curl/curl/pull/3721
 
-Marcel Raad (26 Feb 2019)
-- AppVeyor: re-enable test 500
+- travis: install libnss3-dev only for --with-nss build
   
-  It's passing now.
+  Reduces the time needed for the other jobs a little.
   
-  Closes https://github.com/curl/curl/pull/3615
+  Closes https://github.com/curl/curl/pull/3721
 
-- AppVeyor: remove redundant builds
+- travis: install libssh2-dev only for --with-libssh2 build
   
-  Remove the Visual Studio 2012 and 2013 builds as they add little value.
+  Reduces the time needed for the other jobs a little.
   
-  Ref: https://github.com/curl/curl/pull/3606
-  Closes https://github.com/curl/curl/pull/3614
+  Closes https://github.com/curl/curl/pull/3721
 
-Daniel Stenberg (25 Feb 2019)
-- RELEASE-NOTES: synced
-
-- [Bernd Mueller brought this change]
-
-  OpenSSL: add support for TLS ASYNC state
+- travis: install libssh-dev only for --with-libssh build
   
-  Closes #3591
-
-Jay Satiro (25 Feb 2019)
-- [Michael Felt brought this change]
+  Reduces the time needed for the other jobs a little.
+  
+  Closes https://github.com/curl/curl/pull/3721
 
-  acinclude: add additional libraries to check for LDAP support
+- travis: install krb5-user only for --with-gssapi build
   
-  - Add an additional check for LDAP that also checks for OpenSSL since
-    on AIX those libraries may be required to link LDAP properly.
+  Reduces the time needed for the other jobs a little.
   
-  Fixes https://github.com/curl/curl/issues/3595
-  Closes https://github.com/curl/curl/pull/3596
-
-- [georgeok brought this change]
+  Closes https://github.com/curl/curl/pull/3721
 
-  schannel: support CALG_ECDH_EPHEM algorithm
+- travis: install lcov only for the coverage job
   
-  Add support for Ephemeral elliptic curve Diffie-Hellman key exchange
-  algorithm option when selecting ciphers. This became available on the
-  Win10 SDK.
+  Reduces the time needed for the other jobs a little.
   
-  Closes https://github.com/curl/curl/pull/3608
+  Closes https://github.com/curl/curl/pull/3721
 
-Daniel Stenberg (24 Feb 2019)
-- multi: call multi_done on connect timeouts
+- travis: install clang only when needed
   
-  Failing to do so would make the CURLINFO_TOTAL_TIME timeout to not get
-  updated correctly and could end up getting reported to the application
-  completely wrong (way too small).
+  This reduces the GCC job runtimes a little and it's needed to
+  selectively update clang builds to xenial.
   
-  Reported-by: accountantM on github
-  Fixes #3602
-  Closes #3605
+  Closes https://github.com/curl/curl/pull/3721
 
-- examples: remove recursive calls to curl_multi_socket_action
-  
-  From within the timer callbacks. Recursive is problematic for several
-  reasons. They should still work, but this way the examples and the
-  documentation becomes simpler. I don't think we need to encourage
-  recursive calls.
+- AppVeyor: enable testing for WinSSL build
   
-  Discussed in #3537
-  Closes #3601
+  Closes https://github.com/curl/curl/pull/3725
 
-Marcel Raad (23 Feb 2019)
-- configure: remove CURL_CHECK_FUNC_FDOPEN call
+- build: fix Codacy/CppCheck warnings
   
-  The macro itself has been removed in commit
-  11974ac859c5d82def59e837e0db56fef7f6794e.
+  - remove unused variables
+  - declare conditionally used variables conditionally
+  - suppress unused variable warnings in the CMake tests
+  - remove dead variable stores
+  - consistently use WIN32 macro to detect Windows
   
-  Closes https://github.com/curl/curl/pull/3604
+  Closes https://github.com/curl/curl/pull/3739
 
-Daniel Stenberg (23 Feb 2019)
-- wolfssl: stop custom-adding curves
+- polarssl_threadlock: remove conditionally unused code
   
-  since wolfSSL PR https://github.com/wolfSSL/wolfssl/pull/717 (shipped in
-  wolfSSL 3.10.2 and later) it sends these curves by default already.
+  Make functions no-ops if neither both USE_THREADS_POSIX and
+  HAVE_PTHREAD_H nor both USE_THREADS_WIN32 and HAVE_PROCESS_H are
+  defined. Previously, if only one of them was defined, there was either
+  code compiled that did nothing useful or the wrong header included for
+  the functions used.
   
-  Pointed-out-by: David Garske
+  Also, move POLARSSL_MUTEX_T define to implementation file as it's not
+  used externally.
   
-  Closes #3599
+  Closes https://github.com/curl/curl/pull/3739
 
-- configure: remove the unused fdopen macro
+- lib557: initialize variables
   
-  and the two remaining #ifdefs for it
+  These variables are only conditionally initialized.
   
-  Closes #3600
+  Closes https://github.com/curl/curl/pull/3739
 
-Jay Satiro (22 Feb 2019)
-- url: change conn shutdown order to unlink data as last step
-  
-  - Split off connection shutdown procedure from Curl_disconnect into new
-    function conn_shutdown.
-  
-  - Change the shutdown procedure to close the sockets before
-    disassociating the transfer.
+- lib509: add missing include for strdup
   
-  Prior to this change the sockets were closed after disassociating the
-  transfer so SOCKETFUNCTION wasn't called since the transfer was already
-  disassociated. That likely came about from recent work started in
-  Jan 2019 (#3442) to separate transfers from connections.
+  Closes https://github.com/curl/curl/pull/3739
+
+- README.md: fix no-consecutive-blank-lines Codacy warning
   
-  Bug: https://curl.haxx.se/mail/lib-2019-02/0101.html
-  Reported-by: Pavel Löbl
+  Consistently use one blank line between blocks.
   
-  Closes https://github.com/curl/curl/issues/3597
-  Closes https://github.com/curl/curl/pull/3598
+  Closes https://github.com/curl/curl/pull/3739
 
-Marcel Raad (22 Feb 2019)
-- Fix strict-prototypes GCC warning
+- tests/server/util: fix Windows Unicode build
   
-  As seen in the MinGW autobuilds. Caused by commit
-  f26bc29cfec0be84c67cf74065cf8e5e78fd68b7.
-
-Dan Fandrich (21 Feb 2019)
-- tests: Fixed XML validation errors in some test files.
-
-Daniel Stenberg (20 Feb 2019)
-- TODO: Allow SAN names in HTTP/2 server push
+  Always use the ANSI version of FormatMessage as we don't have the
+  curl_multibyte gear available here.
   
-  Suggested-by: Nicolas Grekas
+  Closes https://github.com/curl/curl/pull/3758
 
-- RELEASE-NOTES: synced
+Daniel Stenberg (11 Apr 2019)
+- curl_easy_getinfo.3: fix minor formatting mistake
 
-- curl: remove MANUAL from -M output
+Daniel Gustafsson (11 Apr 2019)
+- xattr: skip unittest on unsupported platforms
   
-  ... and remove it from the dist tarball. It has served its time, it
-  barely gets updated anymore and "everything curl" is now convering all
-  this document once tried to include, and does it more and better.
+  The stripcredentials unittest fails to compile on platforms without
+  xattr support, for example the Solaris member in the buildfarm which
+  fails with the following:
   
-  In the compressed scenario, this removes ~15K data from the binary,
-  which is 25% of the -M output.
+    CC unit1621-unit1621.o
+    CC ../libtest/unit1621-first.o
+    CCLD unit1621
+    Undefined first referenced
+    symbol in file
+    stripcredentials unit1621-unit1621.o
+    goto problem 2
+    ld: fatal: symbol referencing errors. No output written to .libs/unit1621
+    collect2: error: ld returned 1 exit status
+    gmake[2]: *** [Makefile:996: unit1621] Error 1
   
-  It remains in the git repo for now for as long as the web site builds a
-  page using that as source. It renders poorly on the site (especially for
-  mobile users) so its not even good there.
+  Fix by excluding the test on such platforms by using the reverse
+  logic from where stripcredentials() is defined.
   
-  Closes #3587
+  Closes #3759
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- http2: verify :athority in push promise requests
-  
-  RFC 7540 says we should verify that the push is for an "authoritative"
-  server. We make sure of this by only allowing push with an :athority
-  header that matches the host that was asked for in the URL.
-  
-  Fixes #3577
-  Reported-by: Nicolas Grekas
-  Bug: https://curl.haxx.se/mail/lib-2019-02/0057.html
-  Closes #3581
+Steve Holme (11 Apr 2019)
+- emailL Added reference to RFC8314 for implicit TLS
 
-- singlesocket: fix the 'sincebefore' placement
+- README: Schannel, stop calling it "winssl"
   
-  The variable wasn't properly reset within the loop and thus could remain
-  set for sockets that hadn't been set before and miss notifying the app.
+  Stick to "Schannel" everywhere - follow up to 180501cb.
+
+Jakub Zakrzewski (10 Apr 2019)
+- cmake: clear CMAKE_REQUIRED_LIBRARIES after each use
   
-  This is a follow-up to 4c35574 (shipped in curl 7.64.0)
+  This fixes GSSAPI builds with the libraries in a non-standard location.
+  The testing for recv() were failing because it failed to link
+  the Kerberos libraries, which are not needed for this or subsequent
+  tests.
   
-  Reported-by: buzo-ffm on github
-  Detected-by: Jan Alexander Steffens
-  Fixes #3585
-  Closes #3589
+  fixes #3743
+  closes #3744
 
-- connection: never reuse CONNECT_ONLY conections
+- cmake: avoid linking executable for some tests with cmake 3.6+
   
-  and make CONNECT_ONLY conections never reuse any existing ones either.
+  With CMAKE_TRY_COMPILE_TARGET_TYPE set to STATIC_LIBRARY, the try_compile()
+  (which is used by check_c_source_compiles()) will build static library
+  instead of executable. This avoids linking additional libraries in and thus
+  speeds up those checks a little.
   
-  Reported-by: Pavel Löbl
-  Bug: https://curl.haxx.se/mail/lib-2019-02/0064.html
-  Closes #3586
-
-Patrick Monnerat (19 Feb 2019)
-- cli tool: fix mime post with --disable-libcurl-option configure option
+  This commit also avoids #3743 (GSSAPI build errors) on itself with cmake
+  3.6 or above. That issue was fixed separately for all versions.
   
-  Reported-by: Marcel Raad
-  Fixes #3576
-  Closes #3583
+  Ref: #3744
 
-Daniel Stenberg (19 Feb 2019)
-- x509asn1: cleanup and unify code layout
+- cmake: minor cleanup
   
-  - rename 'n' to buflen in functions, and use size_t for them. Don't pass
-    in negative buffer lengths.
+  - Remove nneeded include_regular_expression.
+    It was setting what is already a default.
   
-  - move most function comments to above the function starts like we use
-    to
+  - Remove duplicated include.
   
-  - remove several unnecessary typecasts (especially of NULL)
+  - Don't check for pre-3.0.0 CMake version.
+    We already require at least 3.0.0, so it's just clutter.
   
-  Reviewed-by: Patrick Monnerat
-  Closes #3582
+  Ref: #3744
 
-- curl_multi_remove_handle.3: use at any time, just not from within callbacks
-  
-  [ci skip]
+Steve Holme (8 Apr 2019)
+- build-openssl.bat: Fixed support for OpenSSL v1.1.0+
 
-- http: make adding a blank header thread-safe
-  
-  Previously the function would edit the provided header in-place when a
-  semicolon is used to signify an empty header. This made it impossible to
-  use the same set of custom headers in multiple threads simultaneously.
-  
-  This approach now makes a local copy when it needs to edit the string.
-  
-  Reported-by: d912e3 on github
-  Fixes #3578
-  Closes #3579
+- build-openssl.bat: Perfer the use of if statements rather than goto (where possible)
 
-- unit1651: survive curl_easy_init() fails
+- build-openssl.bat: Perform the install for each build type directly after the build
 
-- [Frank Gevaerts brought this change]
+- build-openssl.bat: Split the install of static and shared build types
 
-  rand: Fix a mismatch between comments in source and header.
-  
-  Reported-by: Björn Stenberg <bjorn@haxx.se>
-  Closes #3584
+- build-openssl.bat: Split the building of static and shared build types
 
-Patrick Monnerat (18 Feb 2019)
-- x509asn1: replace single char with an array
-  
-  Although safe in this context, using a single char as an array may
-  cause invalid accesses to adjacent memory locations.
-  
-  Detected by Coverity.
+- build-openssl.bat: Move the installation into a separate function
 
-Daniel Stenberg (18 Feb 2019)
-- examples/http2-serverpush: add some sensible error checks
-  
-  To avoid NULL pointer dereferences etc in the case of problems.
-  
-  Closes #3580
+- build-openssl.bat: Move the build step into a separate function
 
-Jay Satiro (18 Feb 2019)
-- easy: fix win32 init to work without CURL_GLOBAL_WIN32
-  
-  - Change the behavior of win32_init so that the required initialization
-    procedures are not affected by CURL_GLOBAL_WIN32 flag.
-  
-  libcurl via curl_global_init supports initializing for win32 with an
-  optional flag CURL_GLOBAL_WIN32, which if omitted was meant to stop
-  Winsock initialization. It did so internally by skipping win32_init()
-  when that flag was set. Since then win32_init() has been expanded to
-  include required initialization routines that are separate from
-  Winsock and therefore must be called in all cases. This commit fixes
-  it so that CURL_GLOBAL_WIN32 only controls the optional win32
-  initialization (which is Winsock initialization, according to our doc).
-  
-  The only users affected by this change are those that don't pass
-  CURL_GLOBAL_WIN32 to curl_global_init. For them this commit removes the
-  risk of a potential crash.
-  
-  Ref: https://github.com/curl/curl/pull/3573
+- build-openssl.bat: Move the OpenSSL configuration into a separate function
+
+- build-openssl.bat: Fixed the BUILD_CONFIG variable not being initialised
   
-  Fixes https://github.com/curl/curl/issues/3313
-  Closes https://github.com/curl/curl/pull/3575
+  Should the parent environment set this variable then the build might
+  not be performed as the user intended.
 
-Daniel Gustafsson (17 Feb 2019)
-- cookie: Add support for cookie prefixes
+Daniel Stenberg (8 Apr 2019)
+- socks: fix error message
+
+- config.d: clarify that initial : and = might need quoting [skip ci]
   
-  The draft-ietf-httpbis-rfc6265bis-02 draft, specify a set of prefixes
-  and how they should affect cookie initialization, which has been
-  adopted by the major browsers. This adds support for the two prefixes
-  defined, __Host- and __Secure, and updates the testcase with the
-  supplied examples from the draft.
+  Fixes #3738
+  Closes #3749
+
+- RELEASE-NOTES: synced
   
-  Closes #3554
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  bumped to 7.65.0 for next release
 
-- mbedtls: release sessionid resources on error
+- socks5: user name and passwords must be shorter than 256
   
-  If mbedtls_ssl_get_session() fails, it may still have allocated
-  memory that needs to be freed to avoid leaking. Call the library
-  API function to release session resources on this errorpath as
-  well as on Curl_ssl_addsessionid() errors.
+  bytes... since the protocol needs to store the length in a single byte field.
   
-  Closes: #3574
-  Reported-by: Michał Antoniak <M.Antoniak@posnet.com>
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: XmiliaH on github
+  Fixes #3737
+  Closes #3740
 
-Patrick Monnerat (16 Feb 2019)
-- cli tool: refactor encoding conversion sequence for switch case fallthrough.
+- [Jakub Zakrzewski brought this change]
 
-- version.c: silent scan-build even when librtmp is not enabled
+  test: urlapi: urlencode characters above 0x7f correctly
 
-Daniel Stenberg (15 Feb 2019)
-- RELEASE-NOTES: synced
+- [Jakub Zakrzewski brought this change]
 
-- Curl_now: figure out windows version in win32_init
+  urlapi: urlencode characters above 0x7f correctly
   
-  ... and avoid use of static variables that aren't thread safe.
+  fixes #3741
+  Closes #3742
+
+- [Even Rouault brought this change]
+
+  multi_runsingle(): fix use-after-free
   
-  Fixes regression from e9ababd4f5a (present in the 7.64.0 release)
+  Fixes #3745
+  Closes #3746
   
-  Reported-by: Paul Groke
-  Fixes #3572
-  Closes #3573
-
-Marcel Raad (15 Feb 2019)
-- unit1307: just fail without FTP support
+  The following snippet
+  ```
   
-  I missed to check this in with commit
-  71786c0505926aaf7e9b2477b2fb7ee16a915ec6, which only disabled the test.
-  This fixes the actual linker error.
+  int main()
+  {
+      CURL* hCurlHandle = curl_easy_init();
+      curl_easy_setopt(hCurlHandle, CURLOPT_URL, "http://example.com");
+      curl_easy_setopt(hCurlHandle, CURLOPT_PROXY, "1");
+      curl_easy_perform(hCurlHandle);
+      curl_easy_cleanup(hCurlHandle);
+      return 0;
+  }
+  ```
+  triggers the following Valgrind warning
   
-  Closes https://github.com/curl/curl/pull/3568
-
-Daniel Stenberg (15 Feb 2019)
-- travis: enable valgrind for the iconv tests too
+  ```
+  ==4125== Invalid read of size 8
+  ==4125==    at 0x4E7D1EE: Curl_llist_remove (llist.c:97)
+  ==4125==    by 0x4E7EF5C: detach_connnection (multi.c:798)
+  ==4125==    by 0x4E80545: multi_runsingle (multi.c:1451)
+  ==4125==    by 0x4E8197C: curl_multi_perform (multi.c:2072)
+  ==4125==    by 0x4E766A0: easy_transfer (easy.c:625)
+  ==4125==    by 0x4E76915: easy_perform (easy.c:719)
+  ==4125==    by 0x4E7697C: curl_easy_perform (easy.c:738)
+  ==4125==    by 0x4008BE: main (in /home/even/curl/test)
+  ==4125==  Address 0x9b3d1d0 is 1,120 bytes inside a block of size 1,600 free'd
+  ==4125==    at 0x4C2ECF0: free (vg_replace_malloc.c:530)
+  ==4125==    by 0x4E62C36: conn_free (url.c:756)
+  ==4125==    by 0x4E62D34: Curl_disconnect (url.c:818)
+  ==4125==    by 0x4E48DF9: Curl_once_resolved (hostip.c:1097)
+  ==4125==    by 0x4E8052D: multi_runsingle (multi.c:1446)
+  ==4125==    by 0x4E8197C: curl_multi_perform (multi.c:2072)
+  ==4125==    by 0x4E766A0: easy_transfer (easy.c:625)
+  ==4125==    by 0x4E76915: easy_perform (easy.c:719)
+  ==4125==    by 0x4E7697C: curl_easy_perform (easy.c:738)
+  ==4125==    by 0x4008BE: main (in /home/even/curl/test)
+  ==4125==  Block was alloc'd at
+  ==4125==    at 0x4C2F988: calloc (vg_replace_malloc.c:711)
+  ==4125==    by 0x4E6438E: allocate_conn (url.c:1654)
+  ==4125==    by 0x4E685B4: create_conn (url.c:3496)
+  ==4125==    by 0x4E6968F: Curl_connect (url.c:4023)
+  ==4125==    by 0x4E802E7: multi_runsingle (multi.c:1368)
+  ==4125==    by 0x4E8197C: curl_multi_perform (multi.c:2072)
+  ==4125==    by 0x4E766A0: easy_transfer (easy.c:625)
+  ==4125==    by 0x4E76915: easy_perform (easy.c:719)
+  ==4125==    by 0x4E7697C: curl_easy_perform (easy.c:738)
+  ==4125==    by 0x4008BE: main (in /home/even/curl/test)
+  ```
   
-  Closes #3571
-
-- travis: add scan-build
+  This has been bisected to commit 2f44e94
   
-  Closes #3564
+  Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14109
+  Credit to OSS Fuzz
 
-- examples/sftpuploadresume: Value stored to 'result' is never read
+- pipelining: removed
   
-  Detected by scan-build
-
-- examples/http2-upload: cleaned up
+  As previously planned and documented in DEPRECATE.md, all pipelining
+  code is removed.
   
-  Fix scan-build warnings, no globals, no silly handle scan. Also remove
-  handles from the multi before cleaning up.
+  Closes #3651
 
-- examples/http2-download: cleaned up
-  
-  To avoid scan-build warnings and global variables.
+- [cclauss brought this change]
 
-- examples/postinmemory: Potential leak of memory pointed to by 'chunk.memory'
+  tests: make Impacket (SMB server) Python 3 compatible
   
-  Detected by scan-build
+  Closes #3731
+  Fixes #3289
 
-- examples/httpcustomheader: Value stored to 'res' is never read
-  
-  Detected by scan-build
+Marcel Raad (6 Apr 2019)
+- [Simon Warta brought this change]
 
-- examples: remove superfluous null-pointer checks
-  
-  in ftpget, ftpsget and sftpget, so that scan-build stops warning for
-  potential NULL pointer dereference below!
+  cmake: set SSL_BACKENDS
   
-  Detected by scan-build
-
-- strip_trailing_dot: make sure NULL is never used for strlen
+  This groups all SSL backends into the feature "SSL" and sets the
+  SSL_BACKENDS analogue to configure.ac
   
-  scan-build warning: Null pointer passed as an argument to a 'nonnull'
-  parameter
+  Closes https://github.com/curl/curl/pull/3736
 
-- [Jay Satiro brought this change]
+- [Simon Warta brought this change]
 
-  connection_check: restore original conn->data after the check
+  cmake: don't run SORT on empty list
   
-  - Save the original conn->data before it's changed to the specified
-    data transfer for the connection check and then restore it afterwards.
+  In case of an empty list, SORTing leads to the cmake error "list
+  sub-command SORT requires list to be present."
   
-  This is a follow-up to 38d8e1b 2019-02-11.
+  Closes https://github.com/curl/curl/pull/3736
+
+Daniel Gustafsson (5 Apr 2019)
+- [Eli Schwartz brought this change]
+
+  configure: fix default location for fish completions
   
-  History:
+  Fish defines a vendor completions directory for completions that are not
+  installed as part of the fish project itself, and the vendor completions
+  are preferred if they exist. This prevents trying to overwrite the
+  builtin curl.fish completion (or creating file conflicts in distro
+  packaging).
   
-  It was discovered a month ago that before checking whether to extract a
-  dead connection that that connection should be associated with a "live"
-  transfer for the check (ie original conn->data ignored and set to the
-  passed in data). A fix was landed in 54b201b which did that and also
-  cleared conn->data after the check. The original conn->data was not
-  restored, so presumably it was thought that a valid conn->data was no
-  longer needed.
+  Prefer the pkg-config defined location exported by fish, if it can be
+  found, and fall back to the correct directory defined by most systems.
   
-  Several days later it was discovered that a valid conn->data was needed
-  after the check and follow-up fix was landed in bbae24c which partially
-  reverted the original fix and attempted to limit the scope of when
-  conn->data was changed to only when pruning dead connections. In that
-  case conn->data was not cleared and the original conn->data not
-  restored.
+  Closes #3723
+  Reviewed-by: Daniel Gustafsson
+
+Marcel Raad (5 Apr 2019)
+- ftplistparser: fix LGTM alert "Empty block without comment"
   
-  A month later it was discovered that the original fix was somewhat
-  correct; a "live" transfer is needed for the check in all cases
-  because original conn->data could be null which could cause a bad deref
-  at arbitrary points in the check. A fix was landed in 38d8e1b which
-  expanded the scope to all cases. conn->data was not cleared and the
-  original conn->data not restored.
+  Removing the block is consistent with line 954/957.
   
-  A day later it was discovered that not restoring the original conn->data
-  may lead to busy loops in applications that use the event interface, and
-  given this observation it's a pretty safe assumption that there is some
-  code path that still needs the original conn->data. This commit is the
-  follow-up fix for that, it restores the original conn->data after the
-  connection check.
+  Closes https://github.com/curl/curl/pull/3732
+
+- transfer: fix LGTM alert "Comparison is always true"
   
-  Assisted-by: tholin@users.noreply.github.com
-  Reported-by: tholin@users.noreply.github.com
+  Just remove the redundant condition, which also makes it clear that
+  k->buf is always 0-terminated if this break is not hit.
   
-  Fixes https://github.com/curl/curl/issues/3542
-  Closes #3559
+  Closes https://github.com/curl/curl/pull/3732
 
-- memdebug: bring back curl_mark_sclose
+Jay Satiro (4 Apr 2019)
+- [Rikard Falkeborn brought this change]
+
+  smtp: fix compiler warning
   
-  Used by debug builds with NSS.
+  - Fix clang string-plus-int warning.
   
-  Reverted from 05b100aee247bb
-
-Patrick Monnerat (14 Feb 2019)
-- transfer.c: do not compute length of undefined hex buffer.
+  Clang 8 warns about adding a string to an int does not append to the
+  string. Indeed it doesn't, but that was not the intention either. Use
+  array indexing as suggested to silence the warning. There should be no
+  functional changes.
   
-  On non-ascii platforms, the chunked hex header was measured for char code
-  conversion length, even for chunked trailers that do not have an hex header.
-  In addition, the efective length is already known: use it.
-  Since the hex length can be zero, only convert if needed.
+  (In other words clang warns about "foo"+2 but not &"foo"[2] so use the
+  latter.)
   
-  Reported by valgrind.
-
-Daniel Stenberg (14 Feb 2019)
-- KNOWN_BUGS: Cannot compile against a static build of OpenLDAP
+  smtp.c:1221:29: warning: adding 'int' to a string does not append to the
+  string [-Wstring-plus-int]
+        eob = strdup(SMTP_EOB + 2);
+              ~~~~~~~~~~~~~~~~^~~~
   
-  Closes #2367
+  Closes https://github.com/curl/curl/pull/3729
 
-Patrick Monnerat (14 Feb 2019)
-- x509asn1: "Dereference of null pointer"
+Marcel Raad (4 Apr 2019)
+- VS projects: use Unicode for VC10+
   
-  Detected by scan-build (false positive).
-
-Daniel Stenberg (14 Feb 2019)
-- configure: show features as well in the final summary
+  All Windows APIs have been natively UTF-16 since Windows 2000 and the
+  non-Unicode variants are just wrappers around them. Only Windows 9x
+  doesn't understand Unicode without the UnicoWS DLL. As later Visual
+  Studio versions cannot target Windows 9x anyway, using the ANSI API
+  doesn't really have any benefit there.
   
-  Closes #3569
-
-- KNOWN_BUGS: curl compiled on OSX 10.13 failed to run on OSX 10.10
+  This avoids issues like KNOWN_BUGS 6.5.
   
-  Closes #2905
+  Ref: https://github.com/curl/curl/issues/2120
+  Closes https://github.com/curl/curl/pull/3720
 
-- KNOWN_BUGS: Deflate error after all content was received
+Daniel Gustafsson (3 Apr 2019)
+- RELEASE-NOTES: synced
   
-  Closes #2719
+  Bump the version in progress to 7.64.2, if we merge any "change"
+  before the cut-off date we can update the version.
 
-- gssapi: fix deprecated header warnings
-  
-  Heimdal includes on FreeBSD spewed out lots of them. Less so now.
-  
-  Closes #3566
+- [Tim Rühsen brought this change]
 
-- TODO: Upgrade to websockets
+  documentation: Fix several typos
   
-  Closes #3523
+  Closes #3724
+  Reviewed-by: Jakub Zakrzewski
+  Reviewed-by: Daniel Gustafsson
 
-- TODO: cmake test suite improvements
-  
-  Closes #3109
+Jay Satiro (2 Apr 2019)
+- [Mert Yazıcıoğlu brought this change]
 
-Patrick Monnerat (13 Feb 2019)
-- curl: "Dereference of null pointer"
+  vauth/oauth2: Fix OAUTHBEARER token generation
   
-  Rephrase to satisfy scan-build.
-
-Marcel Raad (13 Feb 2019)
-- unit1307: require FTP support
+  OAUTHBEARER tokens were incorrectly generated in a format similar to
+  XOAUTH2 tokens. These changes make OAUTHBEARER tokens conform to the
+  RFC7628.
   
-  This test doesn't link without FTP support after
-  fc7ab4835b5fd09d0a6f57000633bb6bb6edfda1, which made Curl_fnmatch
-  unavailable without FTP support.
+  Fixes: #2487
+  Reported-by: Paolo Mossino
   
-  Closes https://github.com/curl/curl/pull/3565
+  Closes https://github.com/curl/curl/pull/3377
 
-Daniel Stenberg (13 Feb 2019)
-- TODO: TFO support on Windows
+Marcel Raad (2 Apr 2019)
+- tool_cb_wrt: fix bad-function-cast warning
   
-  Nobody works on this now.
+  Commit f5bc578f4cdfdc6c708211dfc2962a0e9d79352d reintroduced the
+  warning fixed in commit 2f5f31bb57d68b54e03bffcd9648aece1fe564f8.
+  Extend fhnd's scope and reuse that variable instead of calling
+  _get_osfhandle a second time to fix the warning again.
   
-  Closes #3378
+  Closes https://github.com/curl/curl/pull/3718
 
-- multi: Dereference of null pointer
-  
-  Mostly a false positive, but this makes the code easier to read anyway.
-  
-  Detected by scan-build.
+- VC15 project: remove MinimalRebuild
   
-  Closes #3563
+  Already done in commit d5cfefd0ea8e331b884186bff484210fad36e345 for the
+  library project, but I forgot the tool project template. Now also
+  removed for that.
 
-- urlglob: Argument with 'nonnull' attribute passed null
+Dan Fandrich (1 Apr 2019)
+- cirrus: Customize the disabled tests per FreeBSD version
   
-  Detected by scan-build.
+  Try to run as many test cases as possible on each OS version.
+  12.0 passes 13 more tests than the older versions, so we might as well
+  run them.
 
-Jay Satiro (12 Feb 2019)
-- schannel: restore some debug output but only for debug builds
-  
-  Follow-up to 84c10dc from earlier today which wrapped a lot of the noisy
-  debug output in DEBUGF but omitted a few lines.
+Daniel Stenberg (1 Apr 2019)
+- tool_help: include <strings.h> for strcasecmp
   
-  Ref: https://github.com/curl/curl/commit/84c10dc#r32292900
+  Reported-by: Wyatt O'Day
+  Fixes #3715
+  Closes #3716
 
-- examples/crawler: Fix the Accept-Encoding setting
-  
-  - Pass an empty string to CURLOPT_ACCEPT_ENCODING to use the default
-    supported encodings.
-  
-  Prior to this change the specific encodings of gzip and deflate were set
-  but there's no guarantee they'd be supported by the user's libcurl.
+Daniel Gustafsson (31 Mar 2019)
+- scripts: fix typos
 
-Daniel Stenberg (12 Feb 2019)
-- mime: put the boundary buffer into the curl_mime struct
+Dan Fandrich (28 Mar 2019)
+- travis: allow builds on branches named "ci"
   
-  ... instead of allocating it separately and point to it. It is
-  fixed-size and always used for each part.
+  This allows a way to test changes other than through PRs.
+
+Daniel Stenberg (27 Mar 2019)
+- [Brad Spencer brought this change]
+
+  resolve: apply Happy Eyeballs philosophy to parallel c-ares queries
   
-  Closes #3561
+  Closes #3699
 
-- schannel: be quiet
+- multi: improved HTTP_1_1_REQUIRED handling
   
-  Convert numerous infof() calls into debug-build only messages since they
-  are annoyingly verbose for regular applications. Removed a few.
+  Make sure to downgrade to 1.1 even when we get this HTTP/2 stream error
+  on first flight.
   
-  Bug: https://curl.haxx.se/mail/lib-2019-02/0027.html
-  Reported-by: Volker Schmid
-  Closes #3552
+  Reported-by: niner on github
+  Fixes #3696
+  Closes #3707
 
-- [Romain Geissler brought this change]
+- [Leonardo Taccari brought this change]
 
-  Curl_resolv: fix a gcc -Werror=maybe-uninitialized warning
+  configure: avoid unportable `==' test(1) operator
   
-  Closes #3562
+  Closes #3709
 
-- http2: multi_connchanged() moved from multi.c, only used for h2
-  
-  Closes #3557
+Version 7.64.1 (27 Mar 2019)
 
-- curl: "Function call argument is an uninitialized value"
-  
-  Follow-up to cac0e4a6ad14b42471eb
-  
-  Detected by scan-build
-  Closes #3560
+Daniel Stenberg (27 Mar 2019)
+- RELEASE: 7.64.1
 
-- pretransfer: don't strlen() POSTFIELDS set for GET requests
+- Revert "ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set"
   
-  ... since that data won't be used in the request anyway.
+  This reverts commit 9130ead9fcabdb6b8fbdb37c0b38be2d326adb00.
   
-  Fixes #3548
-  Reported-by: Renaud Allard
-  Close #3549
+  Fixes #3708
 
-- multi: remove verbose "Expire in" ... messages
-  
-  Reported-by: James Brown
-  Bug: https://curl.haxx.se/mail/archive-2019-02/0013.html
-  Closes #3558
+- [Christian Schmitz brought this change]
 
-- mbedtls: make it build even if MBEDTLS_VERSION_C isn't set
+  ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set
   
-  Reported-by: MAntoniak on github
-  Fixes #3553
-  Closes #3556
+  Closes #3704
 
-Daniel Gustafsson (12 Feb 2019)
-- non-ascii.c: fix typos in comments
+Jay Satiro (26 Mar 2019)
+- tool_cb_wrt: fix writing to Windows null device NUL
   
-  Fix two occurrences of s/convers/converts/ spotted while reading code.
-
-Daniel Stenberg (12 Feb 2019)
-- fnmatch: disable if FTP is disabled
+  - Improve console detection.
   
-  Closes #3551
+  Prior to this change WriteConsole could be called to write to a handle
+  that may not be a console, which would cause an error. This issue is
+  limited to character devices that are not also consoles such as the null
+  device NUL.
+  
+  Bug: https://github.com/curl/curl/issues/3175#issuecomment-439068724
+  Reported-by: Gisle Vanem
 
-- curl_path: only enabled for SSH builds
+- CURLMOPT_PIPELINING.3: fix typo
 
-- [Frank Gevaerts brought this change]
+Daniel Stenberg (25 Mar 2019)
+- TODO: config file parsing
+  
+  Closes #3698
 
-  tests: add stderr comparison to the test suite
+Jay Satiro (24 Mar 2019)
+- os400: Disable Alt-Svc by default since it's experimental
   
-  The code is more or less copied from the stdout comparison code, maybe
-  some better reuse is possible.
+  Follow-up to 520f0b4 which added Alt-Svc support and enabled it by
+  default for OS400. Since the feature is experimental, it should be
+  disabled by default.
   
-  test 1457 is adjusted to make the output actually match (by using --silent)
-  test 506 used <stderr> without actually needing it, so that <stderr> block is removed
+  Ref: https://github.com/curl/curl/commit/520f0b4#commitcomment-32792332
+  Ref: https://curl.haxx.se/mail/lib-2019-02/0008.html
   
-  Closes #3536
+  Closes https://github.com/curl/curl/pull/3688
 
-Patrick Monnerat (11 Feb 2019)
-- cli tool: do not use mime.h private structures.
-  
-  Option -F generates an intermediate representation of the mime structure
-  that is used later to create the libcurl mime structure and generate
-  the --libcurl statements.
+Dan Fandrich (24 Mar 2019)
+- tests: Fixed XML validation errors in some test files.
+
+- tests: Fix some incorrect precheck error messages.
   
-  Reported-by: Daniel Stenberg
-  Fixes #3532
-  Closes #3546
+  [ci skip]
 
-Daniel Stenberg (11 Feb 2019)
-- curlver: bump to 7.64.1-dev
+Daniel Stenberg (22 Mar 2019)
+- curl_url.3: this is not experimental anymore
 
-- RELEASE-NOTES: synced
+- travis: bump the used wolfSSL version to 4.0.0
   
-  and bump the version in progress to 7.64.1. If we merge any "change"
-  before the cut-off date, we update again.
-
-Daniel Gustafsson (11 Feb 2019)
-- curl: follow-up to 3f16990ec84
+  Test 311 is now fine, leaving only 313 (CRL) disabled.
   
-  Commit 3f16990ec84cc4b followed-up a bug in b49652ac66cc0 but was
-  inadvertently introducing a new bug in the ternary expression.
+  Test 313 details can be found here:
+  https://github.com/wolfSSL/wolfssl/issues/1546
   
-  Close #3555
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #3697
 
-- dns: release sharelock as soon as possible
+Daniel Gustafsson (22 Mar 2019)
+- lib: Fix typos in comments
+
+David Woodhouse (20 Mar 2019)
+- openssl: if cert type is ENG and no key specified, key is ENG too
   
-  There is no benefit to holding the data sharelock when freeing the
-  addrinfo in case it fails, so ensure releaseing it as soon as we can
-  rather than holding on to it. This also aligns the code with other
-  consumers of sharelocks.
+  Fixes #3692
+  Closes #3692
+
+Daniel Stenberg (20 Mar 2019)
+- sectransp: tvOS 11 is required for ALPN support
   
-  Closes #3516
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: nianxuejie on github
+  Assisted-by: Nick Zitzmann
+  Assisted-by: Jay Satiro
+  Fixes #3689
+  Closes #3690
 
-Daniel Stenberg (11 Feb 2019)
-- curl: follow-up to b49652ac66cc0
+- test1541: threaded connection sharing
   
-  On FreeBSD, return non-zero on error otherwise zero.
+  The threaded-shared-conn.c example turned into test case. Only works if
+  pthread was detected.
   
-  Reported-by: Marcel Raad
-
-- multi: (void)-prefix when ignoring return values
+  An attempt to detect future regressions such as e3a53e3efb942a5
   
-  ... and added braces to two function calls which fixes warnings if they
-  are replace by empty macros at build-time.
+  Closes #3687
 
-- curl: fix FreeBSD compiler warning in the --xattr code
+Patrick Monnerat (17 Mar 2019)
+- os400: alt-svc support.
   
-  Closes #3550
+  Although experimental, enable it in the platform config file.
+  Upgrade ILE/RPG binding.
 
-- connection_check: set ->data to the transfer doing the check
+Daniel Stenberg (17 Mar 2019)
+- conncache: use conn->data to know if a transfer owns it
   
-  The http2 code for connection checking needs a transfer to use. Make
-  sure a working one is set before handler->connection_check() is called.
+  - make sure an already "owned" connection isn't returned unless
+    multiplexed.
   
-  Reported-by: jnbr on github
-  Fixes #3541
-  Closes #3547
-
-- hostip: make create_hostcache_id avoid alloc + free
+  - clear ->data when returning the connection to the cache again
   
-  Closes #3544
+  Regression since 7.62.0 (probably in commit 1b76c38904f0)
+  
+  Bug: https://curl.haxx.se/mail/lib-2019-03/0064.html
+  
+  Closes #3686
 
-- scripts/singleuse: script to use to track single-use functions
+- RELEASE-NOTES: synced
+
+- [Chris Young brought this change]
+
+  configure: add --with-amissl
   
-  That is functions that are declared global but are not used from outside
-  of the file in which it is declared. Such functions should be made
-  static or even at times be removed.
+  AmiSSL is an Amiga native library which provides a wrapper over OpenSSL.
+  It also requires all programs using it to use bsdsocket.library
+  directly, rather than accessing socket functions through clib, which
+  libcurl was not necessarily doing previously. Configure will now check
+  for the headers and ensure they are included if found.
   
-  It also verifies that all used curl_ prefixed functions are "blessed"
+  Closes #3677
+
+- [Chris Young brought this change]
+
+  vtls: rename some of the SSL functions
   
-  Closes #3538
+  ... in the SSL structure as AmiSSL is using macros for the socket API
+  functions.
 
-- cleanup: make local functions static
+- [Chris Young brought this change]
+
+  tool_getpass: termios.h is present on AmigaOS 3, but no tcgetattr/tcsetattr
+
+- [Chris Young brought this change]
+
+  tool_operate: build on AmigaOS
+
+- makefile: make checksrc and hugefile commands "silent"
   
-  urlapi: turn three local-only functions into statics
+  ... to match the style already used for compiling, linking
+  etc. Acknowledges 'make V=1' to enable verbose.
   
-  conncache: make conncache_find_first_connection static
+  Closes #3681
+
+- curl.1: --user and --proxy-user are hidden from ps output
   
-  multi: make detach_connnection static
+  Suggested-by: Eric Curtin
+  Improved-by: Dan Fandrich
+  Ref: #3680
   
-  connect: make getaddressinfo static
+  Closes #3683
+
+- curl.1: mark the argument to --cookie as <data|filename>
   
-  curl_ntlm_core: make hmac_md5 static
+  From a discussion in #3676
   
-  http2: make two functions static
+  Suggested-by: Tim Rühsen
   
-  http: make http_setup_conn static
+  Closes #3682
+
+Dan Fandrich (14 Mar 2019)
+- fuzzer: Only clone the latest fuzzer code, for speed.
+
+Daniel Stenberg (14 Mar 2019)
+- [Dominik Hölzl brought this change]
+
+  Negotiate: fix for HTTP POST with Negotiate
   
-  connect: make tcpnodelay static
+  * Adjusted unit tests 2056, 2057
+  * do not generally close connections with CURLAUTH_NEGOTIATE after every request
+  * moved negotiatedata from UrlState to connectdata
+  * Added stream rewind logic for CURLAUTH_NEGOTIATE
+  * introduced negotiatedata::GSS_AUTHDONE and negotiatedata::GSS_AUTHSUCC
+  * Consider authproblem state for CURLAUTH_NEGOTIATE
+  * Consider reuse_forbid for CURLAUTH_NEGOTIATE
+  * moved and adjusted negotiate authentication state handling from
+    output_auth_headers into Curl_output_negotiate
+  * Curl_output_negotiate: ensure auth done is always set
+  * Curl_output_negotiate: Set auth done also if result code is
+    GSS_S_CONTINUE_NEEDED/SEC_I_CONTINUE_NEEDED as this result code may
+    also indicate the last challenge request (only works with disabled
+    Expect: 100-continue and CURLOPT_KEEP_SENDING_ON_ERROR -> 1)
+  * Consider "Persistent-Auth" header, detect if not present;
+    Reset/Cleanup negotiate after authentication if no persistent
+    authentication
+  * apply changes introduced with #2546 for negotiate rewind logic
   
-  tests: make UNITTEST a thing to mark functions with, so they can be static for
-  normal builds and non-static for unit test builds
+  Fixes #1261
+  Closes #1975
+
+- [Marc Schlatter brought this change]
+
+  http: send payload when (proxy) authentication is done
   
-  ... and mark Curl_shuffle_addr accordingly.
+  The check that prevents payload from sending in case of authentication
+  doesn't check properly if the authentication is done or not.
   
-  url: make up_free static
+  They're cases where the proxy respond "200 OK" before sending
+  authentication challenge. This change takes care of that.
   
-  setopt: make vsetopt static
+  Fixes #2431
+  Closes #3669
+
+- file: fix "Checking if unsigned variable 'readcount' is less than zero."
   
-  curl_endian: make write32_le static
+  Pointed out by codacy
   
-  rtsp: make rtsp_connisdead static
+  Closes #3672
+
+- memdebug: log pointer before freeing its data
   
-  warnless: remove unused functions
+  Coverity warned for two potentional "Use after free" cases. Both are false
+  positives because the memory wasn't used, it was only the actual pointer
+  value that was logged.
   
-  memdebug: remove one unused function, made another static
-
-Dan Fandrich (10 Feb 2019)
-- cirrus: Added FreeBSD builds using Cirrus CI.
+  The fix still changes the order of execution to avoid the warnings.
   
-  The build logs will be at https://cirrus-ci.com/github/curl/curl
+  Coverity CID 1443033 and 1443034
   
-  Some tests are currently failing and so disabled for now. The SSH server
-  isn't starting for the SSH tests due to unsupported options used in its
-  config file. The DICT server also is failing on startup.
+  Closes #3671
 
-Daniel Stenberg (9 Feb 2019)
-- url/idnconvert: remove scan for <= 32 ascii values
+- RELEASE-NOTES: synced
+
+Marcel Raad (12 Mar 2019)
+- travis: actually use updated compiler versions
   
-  The check was added back in fa939220df before the URL parser would catch
-  these problems and therefore these will never trigger now.
+  For the Linux builds, GCC 8 and 7 and clang 7 were installed, but the
+  new GCC versions were only used for the coverage build and for building
+  nghttp2, while the new clang version was not used at all.
   
-  Closes #3539
-
-- urlapi: reduce variable scope, remove unreachable 'break'
+  BoringSSL needs to use the default GCC as it respects CC, but not CXX,
+  so it would otherwise pass gcc 8 options to g++ 4.8 and fail.
   
-  Both nits pointed out by codacy.com
+  Also remove GCC 7, it's not needed anymore.
   
-  Closes #3540
+  Ref: https://docs.travis-ci.com/user/languages/c/#c11c11-and-beyond-and-toolchain-versioning
+  
+  Closes https://github.com/curl/curl/pull/3670
 
-Alessandro Ghedini (7 Feb 2019)
-- zsh.pl: escape ':' character
+- travis: update clang to version 7
   
-  ':' is interpreted as separator by zsh, so if used as part of the argument
-  or option's description it needs to be escaped.
+  Closes https://github.com/curl/curl/pull/3670
+
+Jay Satiro (11 Mar 2019)
+- [Andre Guibert de Bruet brought this change]
+
+  examples/externalsocket: add missing close socket calls
   
-  The problem can be reproduced as follows:
+  .. and for Windows also call WSACleanup since we call WSAStartup.
   
-   % curl --reso<TAB>
-   % curl -E <TAB>
+  The example is to demonstrate handling the socket independently of
+  libcurl. In this case libcurl is not responsible for creating, opening
+  or closing the socket, it is handled by the application (our example).
   
-  Bug: https://bugs.debian.org/921452
+  Fixes https://github.com/curl/curl/pull/3663
 
-- zsh.pl: update regex to better match curl -h output
+Daniel Stenberg (11 Mar 2019)
+- multi: removed unused code for request retries
   
-  The current regex fails to match '<...>' arguments properly (e.g. those
-  with spaces in them), which causes an completion script with wrong
-  descriptions for some options.
+  This code was once used for the non multi-interface using code path, but
+  ever since easy_perform was turned into a wrapper around the multi
+  interface, this code path never runs.
   
-  Here's a diff of the generated completion script, comparing the previous
-  version to the one with this fix:
+  Closes #3666
+
+Jay Satiro (11 Mar 2019)
+- doh: inherit some SSL options from user's easy handle
   
-  --- /usr/share/zsh/vendor-completions/_curl     2019-01-15 20:47:40.000000000 +0000
-  +++ _curl       2019-02-05 20:57:29.453349040 +0000
-  @@ -9,48 +9,48 @@
+  - Inherit SSL options for the doh handle but not SSL client certs,
+    SSL ALPN/NPN, SSL engine, SSL version, SSL issuer cert,
+    SSL pinned public key, SSL ciphers, SSL id cache setting,
+    SSL kerberos or SSL gss-api settings.
   
-   _arguments -C -S \
-     --happy-eyeballs-timeout-ms'[How long to wait in milliseconds for IPv6 before trying IPv4]':'<milliseconds>' \
-  +  --resolve'[Resolve the host+port to this address]':'<host:port:address[,address]...>' \
-     {-c,--cookie-jar}'[Write cookies to <filename> after operation]':'<filename>':_files \
-     {-D,--dump-header}'[Write the received headers to <filename>]':'<filename>':_files \
-     {-y,--speed-time}'[Trigger '\''speed-limit'\'' abort after this time]':'<seconds>' \
-     --proxy-cacert'[CA certificate to verify peer against for proxy]':'<file>':_files \
-  -  --tls13-ciphers'[of TLS 1.3 ciphersuites> TLS 1.3 cipher suites to use]':'<list' \
-  +  --tls13-ciphers'[TLS 1.3 cipher suites to use]':'<list of TLS 1.3 ciphersuites>' \
-     {-E,--cert}'[Client certificate file and password]':'<certificate[:password]>' \
-     --libcurl'[Dump libcurl equivalent code of this command line]':'<file>':_files \
-     --proxy-capath'[CA directory to verify peer against for proxy]':'<dir>':_files \
-  -  --proxy-negotiate'[HTTP Negotiate (SPNEGO) authentication on the proxy]':'Use' \
-     --proxy-pinnedpubkey'[FILE/HASHES public key to verify proxy with]':'<hashes>' \
-     --crlfile'[Get a CRL list in PEM format from the given file]':'<file>':_files \
-  -  --proxy-insecure'[HTTPS proxy connections without verifying the proxy]':'Do' \
-  -  --proxy-ssl-allow-beast'[security flaw for interop for HTTPS proxy]':'Allow' \
-  +  --proxy-negotiate'[Use HTTP Negotiate (SPNEGO) authentication on the proxy]' \
-     --abstract-unix-socket'[Connect via abstract Unix domain socket]':'<path>' \
-     --pinnedpubkey'[FILE/HASHES Public key to verify peer against]':'<hashes>' \
-  +  --proxy-insecure'[Do HTTPS proxy connections without verifying the proxy]' \
-     --proxy-pass'[Pass phrase for the private key for HTTPS proxy]':'<phrase>' \
-  +  --proxy-ssl-allow-beast'[Allow security flaw for interop for HTTPS proxy]' \
-     {-p,--proxytunnel}'[Operate through an HTTP proxy tunnel (using CONNECT)]' \
-     --socks5-hostname'[SOCKS5 proxy, pass host name to proxy]':'<host[:port]>' \
-     --proto-default'[Use PROTOCOL for any URL missing a scheme]':'<protocol>' \
-  -  --proxy-tls13-ciphers'[list> TLS 1.3 proxy cipher suites]':'<ciphersuite' \
-  +  --proxy-tls13-ciphers'[TLS 1.3 proxy cipher suites]':'<ciphersuite list>' \
-     --socks5-gssapi-service'[SOCKS5 proxy service name for GSS-API]':'<name>' \
-     --ftp-alternative-to-user'[String to replace USER \[name\]]':'<command>' \
-  -  --ftp-ssl-control'[SSL/TLS for FTP login, clear for transfer]':'Require' \
-     {-T,--upload-file}'[Transfer local FILE to destination]':'<file>':_files \
-     --local-port'[Force use of RANGE for local port numbers]':'<num/range>' \
-     --proxy-tlsauthtype'[TLS authentication type for HTTPS proxy]':'<type>' \
-     {-R,--remote-time}'[Set the remote file'\''s time on the local output]' \
-  -  --retry-connrefused'[on connection refused (use with --retry)]':'Retry' \
-  -  --suppress-connect-headers'[proxy CONNECT response headers]':'Suppress' \
-  -  {-j,--junk-session-cookies}'[session cookies read from file]':'Ignore' \
-  -  --location-trusted'[--location, and send auth to other hosts]':'Like' \
-  +  --ftp-ssl-control'[Require SSL/TLS for FTP login, clear for transfer]' \
-     --proxy-cert-type'[Client certificate type for HTTPS proxy]':'<type>' \
-     {-O,--remote-name}'[Write output to a file named as the remote file]' \
-  +  --retry-connrefused'[Retry on connection refused (use with --retry)]' \
-  +  --suppress-connect-headers'[Suppress proxy CONNECT response headers]' \
-     --trace-ascii'[Like --trace, but without hex output]':'<file>':_files \
-     --connect-timeout'[Maximum time allowed for connection]':'<seconds>' \
-     --expect100-timeout'[How long to wait for 100-continue]':'<seconds>' \
-     {-g,--globoff}'[Disable URL sequences and ranges using {} and \[\]]' \
-  +  {-j,--junk-session-cookies}'[Ignore session cookies read from file]' \
-     {-m,--max-time}'[Maximum time allowed for the transfer]':'<seconds>' \
-     --dns-ipv4-addr'[IPv4 address to use for DNS requests]':'<address>' \
-     --dns-ipv6-addr'[IPv6 address to use for DNS requests]':'<address>' \
-  -  --ignore-content-length'[the size of the remote resource]':'Ignore' \
-     {-k,--insecure}'[Allow insecure server connections when using SSL]' \
-  +  --location-trusted'[Like --location, and send auth to other hosts]' \
-     --mail-auth'[Originator address of the original email]':'<address>' \
-     --noproxy'[List of hosts which do not use proxy]':'<no-proxy-list>' \
-     --proto-redir'[Enable/disable PROTOCOLS on redirect]':'<protocols>' \
-  @@ -62,18 +62,19 @@
-     --socks5-basic'[Enable username/password auth for SOCKS5 proxies]' \
-     --cacert'[CA certificate to verify peer against]':'<file>':_files \
-     {-H,--header}'[Pass custom header(s) to server]':'<header/@file>' \
-  +  --ignore-content-length'[Ignore the size of the remote resource]' \
-     {-i,--include}'[Include protocol response headers in the output]' \
-     --proxy-header'[Pass custom header(s) to proxy]':'<header/@file>' \
-     --unix-socket'[Connect through this Unix domain socket]':'<path>' \
-     {-w,--write-out}'[Use output FORMAT after completion]':'<format>' \
-  -  --http2-prior-knowledge'[HTTP 2 without HTTP/1.1 Upgrade]':'Use' \
-     {-o,--output}'[Write to file instead of stdout]':'<file>':_files \
-  -  {-J,--remote-header-name}'[the header-provided filename]':'Use' \
-  +  --preproxy'[\[protocol://\]host\[:port\] Use this proxy first]' \
-     --socks4a'[SOCKS4a proxy on given host + port]':'<host[:port]>' \
-     {-Y,--speed-limit}'[Stop transfers slower than this]':'<speed>' \
-     {-z,--time-cond}'[Transfer based on a time condition]':'<time>' \
-     --capath'[CA directory to verify peer against]':'<dir>':_files \
-     {-f,--fail}'[Fail silently (no output at all) on HTTP errors]' \
-  +  --http2-prior-knowledge'[Use HTTP 2 without HTTP/1.1 Upgrade]' \
-     --proxy-tlspassword'[TLS password for HTTPS proxy]':'<string>' \
-     {-U,--proxy-user}'[Proxy user and password]':'<user:password>' \
-     --proxy1.0'[Use HTTP/1.0 proxy on given port]':'<host[:port]>' \
-  @@ -81,52 +82,49 @@
-     {-A,--user-agent}'[Send User-Agent <name> to server]':'<name>' \
-     --egd-file'[EGD socket path for random data]':'<file>':_files \
-     --fail-early'[Fail on first transfer error, do not continue]' \
-  -  --haproxy-protocol'[HAProxy PROXY protocol v1 header]':'Send' \
-  -  --preproxy'[Use this proxy first]':'[protocol://]host[:port]' \
-  +  {-J,--remote-header-name}'[Use the header-provided filename]' \
-     --retry-max-time'[Retry only within this period]':'<seconds>' \
-     --socks4'[SOCKS4 proxy on given host + port]':'<host[:port]>' \
-     --socks5'[SOCKS5 proxy on given host + port]':'<host[:port]>' \
-  -  --socks5-gssapi-nec'[with NEC SOCKS5 server]':'Compatibility' \
-  -  --ssl-allow-beast'[security flaw to improve interop]':'Allow' \
-     --cert-status'[Verify the status of the server certificate]' \
-  -  --ftp-create-dirs'[the remote dirs if not present]':'Create' \
-     {-:,--next}'[Make next URL use its separate set of options]' \
-     --proxy-key-type'[Private key file type for proxy]':'<type>' \
-  -  --remote-name-all'[the remote file name for all URLs]':'Use' \
-     {-X,--request}'[Specify request command to use]':'<command>' \
-     --retry'[Retry request if transient problems occur]':'<num>' \
-  -  --ssl-no-revoke'[cert revocation checks (WinSSL)]':'Disable' \
-     --cert-type'[Certificate file type (DER/PEM/ENG)]':'<type>' \
-     --connect-to'[Connect to host]':'<HOST1:PORT1:HOST2:PORT2>' \
-     --create-dirs'[Create necessary local directory hierarchy]' \
-  +  --haproxy-protocol'[Send HAProxy PROXY protocol v1 header]' \
-     --max-redirs'[Maximum number of redirects allowed]':'<num>' \
-     {-n,--netrc}'[Must read .netrc for user name and password]' \
-  +  {-x,--proxy}'[\[protocol://\]host\[:port\] Use this proxy]' \
-     --proxy-crlfile'[Set a CRL list for proxy]':'<file>':_files \
-     --sasl-ir'[Enable initial response in SASL authentication]' \
-  -  --socks5-gssapi'[GSS-API auth for SOCKS5 proxies]':'Enable' \
-  +  --socks5-gssapi-nec'[Compatibility with NEC SOCKS5 server]' \
-  +  --ssl-allow-beast'[Allow security flaw to improve interop]' \
-  +  --ftp-create-dirs'[Create the remote dirs if not present]' \
-     --interface'[Use network INTERFACE (or address)]':'<name>' \
-     --key-type'[Private key file type (DER/PEM/ENG)]':'<type>' \
-     --netrc-file'[Specify FILE for netrc]':'<filename>':_files \
-     {-N,--no-buffer}'[Disable buffering of the output stream]' \
-     --proxy-service-name'[SPNEGO proxy service name]':'<name>' \
-  -  --styled-output'[styled output for HTTP headers]':'Enable' \
-  +  --remote-name-all'[Use the remote file name for all URLs]' \
-  +  --ssl-no-revoke'[Disable cert revocation checks (WinSSL)]' \
-     --max-filesize'[Maximum file size to download]':'<bytes>' \
-     --negotiate'[Use HTTP Negotiate (SPNEGO) authentication]' \
-     --no-keepalive'[Disable TCP keepalive on the connection]' \
-     {-#,--progress-bar}'[Display transfer progress as a bar]' \
-  -  {-x,--proxy}'[Use this proxy]':'[protocol://]host[:port]' \
-  -  --proxy-anyauth'[any proxy authentication method]':'Pick' \
-     {-Q,--quote}'[Send command(s) to server before transfer]' \
-  -  --request-target'[the target for this request]':'Specify' \
-  +  --socks5-gssapi'[Enable GSS-API auth for SOCKS5 proxies]' \
-     {-u,--user}'[Server user and password]':'<user:password>' \
-     {-K,--config}'[Read config from a file]':'<file>':_files \
-     {-C,--continue-at}'[Resumed transfer offset]':'<offset>' \
-     --data-raw'[HTTP POST data, '\''@'\'' allowed]':'<data>' \
-  -  --disallow-username-in-url'[username in url]':'Disallow' \
-     --krb'[Enable Kerberos with security <level>]':'<level>' \
-     --proxy-ciphers'[SSL ciphers to use for proxy]':'<list>' \
-     --proxy-digest'[Use Digest authentication on the proxy]' \
-     --proxy-tlsuser'[TLS username for HTTPS proxy]':'<name>' \
-  +  --styled-output'[Enable styled output for HTTP headers]' \
-     {-b,--cookie}'[Send cookies from string/file]':'<data>' \
-     --data-urlencode'[HTTP POST data url encoded]':'<data>' \
-     --delegation'[GSS-API delegation permission]':'<LEVEL>' \
-  @@ -134,7 +132,10 @@
-     --post301'[Do not switch to GET after following a 301]' \
-     --post302'[Do not switch to GET after following a 302]' \
-     --post303'[Do not switch to GET after following a 303]' \
-  +  --proxy-anyauth'[Pick any proxy authentication method]' \
-  +  --request-target'[Specify the target for this request]' \
-     --trace-time'[Add time stamps to trace/verbose output]' \
-  +  --disallow-username-in-url'[Disallow username in url]' \
-     --dns-servers'[DNS server addrs to use]':'<addresses>' \
-     {-G,--get}'[Put the post data in the URL and use GET]' \
-     --limit-rate'[Limit transfer speed to RATE]':'<speed>' \
-  @@ -148,21 +149,21 @@
-     --metalink'[Process given URLs as metalink XML file]' \
-     --tr-encoding'[Request compressed transfer encoding]' \
-     --xattr'[Store metadata in extended file attributes]' \
-  -  --ftp-skip-pasv-ip'[the IP address for PASV]':'Skip' \
-     --pass'[Pass phrase for the private key]':'<phrase>' \
-     --proxy-ntlm'[Use NTLM authentication on the proxy]' \
-     {-S,--show-error}'[Show error even when -s is used]' \
-  -  --ciphers'[of ciphers> SSL ciphers to use]':'<list' \
-  +  --ciphers'[SSL ciphers to use]':'<list of ciphers>' \
-     --form-string'[Specify multipart MIME data]':'<name=string>' \
-     --login-options'[Server login options]':'<options>' \
-     --tftp-blksize'[Set TFTP BLKSIZE option]':'<value>' \
-  -  --tftp-no-options'[not send any TFTP options]':'Do' \
-     {-v,--verbose}'[Make the operation more talkative]' \
-  +  --ftp-skip-pasv-ip'[Skip the IP address for PASV]' \
-     --proxy-key'[Private key for HTTPS proxy]':'<key>' \
-     {-F,--form}'[Specify multipart MIME data]':'<name=content>' \
-     --mail-from'[Mail from this address]':'<address>' \
-     --oauth2-bearer'[OAuth 2 Bearer Token]':'<token>' \
-     --proto'[Enable/disable PROTOCOLS]':'<protocols>' \
-  +  --tftp-no-options'[Do not send any TFTP options]' \
-     --tlsauthtype'[TLS authentication type]':'<type>' \
-     --doh-url'[Resolve host names over DOH]':'<URL>' \
-     --no-sessionid'[Disable SSL session-ID reusing]' \
-  @@ -173,14 +174,13 @@
-     --ftp-ssl-ccc'[Send CCC after authenticating]' \
-     {-4,--ipv4}'[Resolve names to IPv4 addresses]' \
-     {-6,--ipv6}'[Resolve names to IPv6 addresses]' \
-  -  --netrc-optional'[either .netrc or URL]':'Use' \
-     --service-name'[SPNEGO service name]':'<name>' \
-     {-V,--version}'[Show version number and quit]' \
-     --data-ascii'[HTTP POST ASCII data]':'<data>' \
-     --ftp-account'[Account data string]':'<data>' \
-  -  --compressed-ssh'[SSH compression]':'Enable' \
-     --disable-eprt'[Inhibit using EPRT or LPRT]' \
-     --ftp-method'[Control CWD usage]':'<method>' \
-  +  --netrc-optional'[Use either .netrc or URL]' \
-     --pubkey'[SSH Public key file name]':'<key>' \
-     --raw'[Do HTTP "raw"; no transfer decoding]' \
-     --anyauth'[Pick any authentication method]' \
-  @@ -189,6 +189,7 @@
-     --no-alpn'[Disable the ALPN TLS extension]' \
-     --tcp-nodelay'[Use the TCP_NODELAY option]' \
-     {-B,--use-ascii}'[Use ASCII/text transfer]' \
-  +  --compressed-ssh'[Enable SSH compression]' \
-     --digest'[Use HTTP Digest Authentication]' \
-     --proxy-tlsv1'[Use TLSv1 for HTTPS proxy]' \
-     --engine'[Crypto engine to use]':'<name>' \
-
-Marcel Raad (7 Feb 2019)
-- tool_operate: fix typecheck warning
+  - Fix inheritance of verbose setting.
   
-  Use long for CURLOPT_HTTP09_ALLOWED to fix the following warning:
-  tool_operate.c: In function 'operate_do':
-  ../include/curl/typecheck-gcc.h:47:9: error: call to
-  '_curl_easy_setopt_err_long' declared with attribute warning:
-  curl_easy_setopt expects a long argument for this option [-Werror]
+  - Inherit NOSIGNAL.
   
-  Closes https://github.com/curl/curl/pull/3534
-
-Jay Satiro (6 Feb 2019)
-- [Chris Araman brought this change]
+  There is no way for the user to set options for the doh (DNS-over-HTTPS)
+  handles and instead we inherit some options from the user's easy handle.
+  
+  My thinking for the SSL options not inherited is they are most likely
+  not intended by the user for the DOH transfer. I did inherit insecure
+  because I think that should still be in control of the user.
+  
+  Prior to this change doh did not work for me because CAINFO was not
+  inherited. Also verbose was set always which AFAICT was a bug (#3660).
+  
+  Fixes https://github.com/curl/curl/issues/3660
+  Closes https://github.com/curl/curl/pull/3661
 
-  url: close TLS before removing conn from cache
+Daniel Stenberg (9 Mar 2019)
+- test331: verify set-cookie for dotless host name
   
-  - Fix potential crashes in schannel shutdown.
+  Reproduced bug #3649
+  Closes #3659
+
+- Revert "cookies: extend domain checks to non psl builds"
   
-  Ensure any TLS shutdown messages are sent before removing the
-  association between the connection and the easy handle. Reverts
-  @bagder's previous partial fix for #3412.
+  This reverts commit 3773de378d48b06c09931e44dca4d274d0bfdce0.
   
-  Fixes https://github.com/curl/curl/issues/3412
-  Fixes https://github.com/curl/curl/issues/3505
-  Closes https://github.com/curl/curl/pull/3531
+  Regression shipped in 7.64.0
+  Fixes #3649
 
-Daniel Gustafsson (6 Feb 2019)
-- INTERNALS.md: fix subsection depth and link
+- memdebug: make debug-specific functions use curl_dbg_ prefix
   
-  The Kerberos subsection was mistakenly a subsubsection under FTP, and
-  the curlx subsection was missing an anchor for the TOC link.
+  To not "collide" or use up the regular curl_ name space. Also makes them
+  easier to detect in helper scripts.
   
-  Closes #3529
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #3656
 
-Version 7.64.0 (6 Feb 2019)
+- cmdline-opts/proxytunnel.d: the option tunnnels all protocols
+  
+  Clarify the language and simplify.
+  
+  Reported-by: Daniel Lublin
+  Closes #3658
 
-Daniel Stenberg (6 Feb 2019)
-- RELEASE-NOTES: 7.64.0
+- KNOWN_BUGS: Client cert (MTLS) issues with Schannel
+  
+  Closes #3145
 
-- RELEASE-PROCEDURE: update the release calendar
+- ROADMAP: updated to some more current things to work on
 
-- THANKS: 7.64.0 status
+- tests: fix multiple may be used uninitialized warnings
 
-Daniel Gustafsson (5 Feb 2019)
-- ROADMAP: remove already performed item
+- RELEASE-NOTES: synced
+
+- source: fix two 'nread' may be used uninitialized warnings
   
-  Commit 7a09b52c98ac8d840a8a9907b1a1d9a9e684bcf5 introduced support
-  for the draft-ietf-httpbis-cookie-alone-01 cookie draft, and while
-  the entry was removed from the TODO it was mistakenly left here.
-  Fix by removing and rewording the entry slightly.
+  Both seem to be false positives but we don't like warnings.
   
-  Closes #3530
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-- [Etienne Simard brought this change]
+  Closes #3646
 
-  CONTRIBUTE.md: Fix grammatical errors
+- gopher: remove check for path == NULL
   
-  Fix grammatical errors making the document read better. Also fixes
-  a typo.
+  Since it can't be NULL and it makes Coverity believe we lack proper NULL
+  checks. Verified by test 659, landed in commit 15401fa886b.
   
-  Closes #3525
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
-
-Daniel Stenberg (4 Feb 2019)
-- [Julian Z brought this change]
-
-  docs: use $(INSTALL_DATA) to install man page
+  Pointed out by Coverity CID 1442746.
   
-  Fixes #3518
-  Closes #3522
+  Assisted-by: Dan Fandrich
+  Fixes #3617
+  Closes #3642
 
-Jay Satiro (4 Feb 2019)
-- [Ladar Levison brought this change]
+- examples: only include <curl/curl.h>
+  
+  That's the only public curl header we should encourage use of.
+  
+  Reviewed-by: Marcel Raad
+  Closes #3645
 
-  runtests.pl: Fix perl call to include srcdir
+- ssh: loop the state machine if not done and not blocking
   
-  - Use explicit include opt for perl calls.
+  If the state machine isn't complete, didn't fail and it didn't return
+  due to blocking it can just as well loop again.
   
-  Prior to this change some scripts couldn't find their dependencies.
+  This addresses the problem with SFTP directory listings where we would
+  otherwise return back to the parent and as the multi state machine
+  doesn't have any code for using CURLM_CALL_MULTI_PERFORM for as long the
+  doing phase isn't complete, it would return out when in reality there
+  was more data to deal with.
   
-  At the top, perl is called using with the "-Isrcdir" option, and it
-  works:
+  Fixes #3506
+  Closes #3644
+
+Jay Satiro (5 Mar 2019)
+- multi: support verbose conncache closure handle
   
-  https://github.com/curl/curl/blob/curl-7_63_0/tests/runtests.pl#L183
+  - Change closure handle to receive verbose setting from the easy handle
+    most recently added via curl_multi_add_handle.
   
-  But on line 3868, that option is omitted. This caused problems for me,
-  as the symbol-scan.pl script in particular couldn't find its
-  dependencies properly:
+  The closure handle is a special easy handle used for closing cached
+  connections. It receives limited settings from the easy handle most
+  recently added to the multi handle. Prior to this change that did not
+  include verbose which was a problem because on connection shutdown
+  verbose mode was not acknowledged.
   
-  https://github.com/curl/curl/blob/curl-7_63_0/tests/runtests.pl#L3868
+  Ref: https://github.com/curl/curl/pull/3598
   
-  This patch fixes that oversight by making calls to perl sub-shells
-  uniform.
+  Co-authored-by: Daniel Stenberg
   
-  Closes https://github.com/curl/curl/pull/3496
-
-Daniel Stenberg (4 Feb 2019)
-- [Daniel Gustafsson brought this change]
+  Closes https://github.com/curl/curl/pull/3618
 
-  smtp: avoid risk of buffer overflow in strtol
+Daniel Stenberg (4 Mar 2019)
+- CURLU: fix NULL dereference when used over proxy
   
-  If the incoming len 5, but the buffer does not have a termination
-  after 5 bytes, the strtol() call may keep reading through the line
-  buffer until is exceeds its boundary. Fix by ensuring that we are
-  using a bounded read with a temporary buffer on the stack.
+  Test 659 verifies
   
-  Bug: https://curl.haxx.se/docs/CVE-2019-3823.html
-  Reported-by: Brian Carpenter (Geeknik Labs)
-  CVE-2019-3823
+  Also fixed the test 658 name
+  
+  Closes #3641
 
-- ntlm: fix *_type3_message size check to avoid buffer overflow
+- altsvc_out: check the return code from Curl_gmtime
   
-  Bug: https://curl.haxx.se/docs/CVE-2019-3822.html
-  Reported-by: Wenxiang Qian
-  CVE-2019-3822
+  Pointed out by Coverity, CID 1442956.
+  
+  Closes #3640
 
-- NTLM: fix size check condition for type2 received data
+- docs/ALTSVC.md: docs describing the approach
   
-  Bug: https://curl.haxx.se/docs/CVE-2018-16890.html
-  Reported-by: Wenxiang Qian
-  CVE-2018-16890
+  Closes #3498
 
-Marcel Raad (1 Feb 2019)
-- [georgeok brought this change]
+- alt-svc: add a travis build
 
-  spnego_sspi: add support for channel binding
-  
-  Attempt to add support for Secure Channel binding when negotiate
-  authentication is used. The problem to solve is that by default IIS
-  accepts channel binding and curl doesn't utilise them. The result was a
-  401 response. Scope affects only the Schannel(winssl)-SSPI combination.
+- alt-svc: add test 355 and 356 to verify with command line curl
+
+- alt-svc: the curl command line bits
+
+- alt-svc: the libcurl bits
+
+- travis: add build using gnutls
   
-  Fixes https://github.com/curl/curl/issues/3503
-  Closes https://github.com/curl/curl/pull/3509
+  Closes #3637
 
-Daniel Stenberg (1 Feb 2019)
 - RELEASE-NOTES: synced
 
-- schannel: stop calling it "winssl"
-  
-  Stick to "Schannel" everywhere. The configure option --with-winssl is
-  kept to allow existing builds to work but --with-schannel is added as an
-  alias.
-  
-  Closes #3504
+- [Simon Legner brought this change]
 
-- multi: set the EXPIRE_*TIMEOUT timers at TIMER_STARTSINGLE time
+  scripts/completion.pl: also generate fish completion file
   
-  To make sure Curl_timeleft() also thinks the timeout has been reached
-  when one of the EXPIRE_*TIMEOUTs expires.
+  This is the renamed script formerly known as zsh.pl
   
-  Bug: https://curl.haxx.se/mail/lib-2019-01/0073.html
-  Reported-by: Zhao Yisha
-  Closes #3501
-
-- [John Marshall brought this change]
+  Closes #3545
 
-  doc: use meaningless port number in CURLOPT_LOCALPORT example
+- gnutls: remove call to deprecated gnutls_compression_get_name
   
-  Use an ephemeral port number here; previously the example had 8080
-  which could be confusing as the common web server port number might
-  be misinterpreted as suggesting this option affects the remote port.
+  It has been deprecated by GnuTLS since a year ago and now causes build
+  warnings.
   
-  URL: https://curl.haxx.se/mail/lib-2019-01/0084.html
-  Closes #3513
-
-GitHub (29 Jan 2019)
-- [Gisle Vanem brought this change]
-
-  Escape the '\'
+  Ref: https://gitlab.com/gnutls/gnutls/commit/b0041897d2846737f5fb0f
+  Docs: https://www.gnutls.org/manual/html_node/Compatibility-API.html
   
-  A backslash should be escaped in Roff / Troff.
+  Closes #3636
 
-Jay Satiro (29 Jan 2019)
-- TODO: WinSSL: 'Add option to disable client cert auto-send'
+Jay Satiro (2 Mar 2019)
+- system_win32: move win32_init here from easy.c
   
-  By default WinSSL selects and send a client certificate automatically,
-  but for privacy and consistency we should offer an option to disable the
-  default auto-send behavior.
+  .. since system_win32 is a more appropriate location for the functions
+  and to extern the globals.
   
-  Reported-by: Jeroen Ooms
+  Ref: https://github.com/curl/curl/commit/ca597ad#r32446578
+  Reported-by: Gisle Vanem
   
-  Closes https://github.com/curl/curl/issues/2262
-
-Daniel Stenberg (28 Jan 2019)
-- [Jeremie Rapin brought this change]
+  Closes https://github.com/curl/curl/pull/3625
 
-  sigpipe: if mbedTLS is used, ignore SIGPIPE
-  
-  mbedTLS doesn't have a sigpipe management. If a write/read occurs when
-  the remote closes the socket, the signal is raised and kills the
-  application.  Use the curl mecanisms fix this behavior.
+Daniel Stenberg (1 Mar 2019)
+- curl_easy_duphandle.3: clarify that a duped handle has no shares
   
-  Signed-off-by: Jeremie Rapin <j.rapin@overkiz.com>
+  Reported-by: Sara Golemon
   
-  Closes #3502
+  Fixes #3592
+  Closes #3634
 
-- unit1653: make it survive torture tests
+- 10-at-a-time.c: fix too long line
 
-Jay Satiro (28 Jan 2019)
-- [Michael Kujawa brought this change]
+- [Arnaud Rebillout brought this change]
 
-  timeval: Disable MSVC Analyzer GetTickCount warning
+  examples: various fixes in ephiperfifo.c
   
-  Compiling with msvc /analyze and a recent Windows SDK warns against
-  using GetTickCount (Suggests to use GetTickCount64 instead.)
+  The main change here is the timer value that was wrong, it was given in
+  usecs (ms * 1000), while the itimerspec struct wants nsecs (ms * 1000 *
+  1000). This resulted in the callback being invoked WAY TOO OFTEN.
   
-  Since GetTickCount is only being used when GetTickCount64 isn't
-  available, I am disabling that warning.
+  As a quick check you can run this command before and after applying this
+  commit:
   
-  Fixes https://github.com/curl/curl/issues/3437
-  Closes https://github.com/curl/curl/pull/3440
-
-Daniel Stenberg (26 Jan 2019)
-- configure: rewrite --enable-code-coverage
+      # shell 1
+      ./ephiperfifo 2>&1 | tee ephiperfifo.log
+      # shell 2
+      echo http://hacking.elboulangero.com > hiper.fifo
   
-  The previously used ax_code_coverage.m4 is not license compatible and
-  must not be used.
+  Then just compare the size of the logs files.
   
-  Reported-by: William A. Rowe Jr
-  Fixes #3497
-  Closes #3499
-
-- [Felix Hädicke brought this change]
+  Closes #3633
+  Fixes #3632
+  Signed-off-by: Arnaud Rebillout <arnaud.rebillout@collabora.com>
 
-  setopt: enable CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION for libssh
+- urldata: simplify bytecounters
   
-  CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION are supported for
-  libssh as well. So accepting these options only when compiling with
-  libssh2 is wrong here.
+  - no need to have them protocol specific
   
-  Fixes #3493
-  Closes #3494
-
-- [Felix Hädicke brought this change]
-
-  libssh: do not let libssh create socket
-  
-  By default, libssh creates a new socket, instead of using the socket
-  created by curl for SSH connections.
-  
-  Pass the socket created by curl to libssh using ssh_options_set() with
-  SSH_OPTIONS_FD directly after ssh_new(). So libssh uses our socket
-  instead of creating a new one.
+  - no need to set pointers to them with the Curl_setup_transfer() call
   
-  This approach is very similar to what is done in the libssh2 code, where
-  the socket created by curl is passed to libssh2 when
-  libssh2_session_startup() is called.
+  - make Curl_setup_transfer() operate on a transfer pointer, not
+    connection
   
-  Fixes #3491
-  Closes #3495
-
-- RELEASE-NOTES: synced
-
-- [Archangel_SDY brought this change]
-
-  schannel: preserve original certificate path parameter
+  - switch some counters from long to the more proper curl_off_t type
   
-  Fixes #3480
-  Closes #3487
+  Closes #3627
 
-- KNOWN_BUGS: tests not compatible with python3
+- examples/10-at-a-time.c: improve readability and simplify
   
-  Closes #3289
-  [skip ci]
+   - use better variable names to explain their purposes
+   - convert logic to curl_multi_wait()
 
-Daniel Gustafsson (20 Jan 2019)
-- memcmp: avoid doing single char memcmp
+- threaded-resolver: shutdown the resolver thread without error message
   
-  There is no real gain in performing memcmp() comparisons on single
-  characters, so change these to array subscript inspections which
-  saves a call and makes the code clearer.
+  When a transfer is done, the resolver thread will be brought down. That
+  could accidentally generate an error message in the error buffer even
+  though this is not an error situationand the transfer would still return
+  OK.  An application that still reads the error buffer could find a
+  "Could not resolve host: [host name]" message there and get confused.
   
-  Closes #3486
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
+  Reported-by: Michael Schmid
+  Fixes #3629
+  Closes #3630
 
-Daniel Stenberg (19 Jan 2019)
-- COPYING: it's 2019
-  
-  [skip ci]
+- [Ԝеѕ brought this change]
 
-- [hhb brought this change]
+  docs: update max-redirs.d phrasing
+  
+  clarify redir - "in absurdum" doesn't seem to make sense in this context
+  
+  Closes #3631
 
-  configure: fix recv/send/select detection on Android
+- ssh: fix Condition '!status' is always true
   
-  This reverts commit d4f25201fb7da03fc88f90d51101beb3d0026db9.
+  in the same sftp_done function in both SSH backends. Simplify them
+  somewhat.
   
-  The overloadable attribute is removed again starting from
-  NDK17. Actually they only exist in two NDK versions (15 and 16). With
-  overloadable, the first condition tried will succeed. Results in wrong
-  detection result.
+  Pointed out by Codacy.
   
-  Closes #3484
+  Closes #3628
 
-Marcel Raad (19 Jan 2019)
-- [georgeok brought this change]
+- test578: make it read data from the correct test
 
-  ntlm_sspi: add support for channel binding
-  
-  Windows extended potection (aka ssl channel binding) is required
-  to login to ntlm IIS endpoint, otherwise the server returns 401
-  responses.
+- Curl_easy: remove req.maxfd - never used!
   
-  Fixes #3280
-  Closes #3321
-
-Daniel Stenberg (18 Jan 2019)
-- schannel: on connection close there might not be a transfer
+  Introduced in 8b6314ccfb, but not used anymore in current code. Unclear
+  since when.
   
-  Reported-by: Marcel Raad
-  Fixes #3412
-  Closes #3483
-
-- [Joel Depooter brought this change]
+  Closes #3626
 
-  ssh: log the libssh2 error message when ssh session startup fails
+- http: set state.infilesize when sending formposts
   
-  When a ssh session startup fails, it is useful to know why it has
-  failed. This commit changes the message from:
-     "Failure establishing ssh session"
-  to something like this, for example:
-     "Failure establishing ssh session: -5, Unable to exchange encryption keys"
+  Without it set, we would unwillingly triger the "HTTP error before end
+  of send, stop sending" condition even if the entire POST body had been
+  sent (since it wouldn't know the expected size) which would
+  unnecessarily log that message and close the connection when it didn't
+  have to.
   
-  Closes #3481
+  Reported-by: Matt McClure
+  Bug: https://curl.haxx.se/mail/archive-2019-02/0023.html
+  Closes #3624
 
-Alessandro Ghedini (16 Jan 2019)
-- Fix typo in manpage
+- INSTALL: refer to the current TLS library names and configure options
 
-Daniel Stenberg (16 Jan 2019)
-- RELEASE-NOTES: synced
+- FAQ: minor updates and spelling fixes
 
-Sergei Nikulov (16 Jan 2019)
-- cmake: updated check for HAVE_POLL_FINE to match autotools
+- GOVERNANCE.md: minor spelling fixes
 
-Daniel Stenberg (16 Jan 2019)
-- curl-compilers.m4: check for __ibmxl__ to detect xlclang
-  
-  Follow-up to 2fa0d57e2e3. The __xlc__ symbol is only defined there if a
-  particular flag is used for legacy macros.
+- Secure Transport: no more "darwinssl"
   
-  Fixes #3474
-  Closes #3479
-
-- openssl: fix the SSL_get_tlsext_status_ocsp_resp call
+  Everyone calls it Secure Transport, now we do too.
   
-  .... to not pass in a const in the second argument as that's not how it
-  is supposed to be used and might cause compiler warnings.
+  Reviewed-by: Nick Zitzmann
   
-  Reported-by: Pavel Pavlov
-  Fixes #3477
-  Closes #3478
+  Closes #3619
 
-- curl-compilers.m4: detect xlclang
+Marcel Raad (27 Feb 2019)
+- AppVeyor: add classic MinGW build
   
-  Since it isn't totally clang compatible, we detect this IBM clang
-  front-end and if detected, avoids some clang specific magic.
+  But use the MSYS2 shell rather than the default MSYS shell because of
+  POSIX path conversion issues. Classic MinGW is only available on the
+  Visual Studio 2015 image.
   
-  Reported-by: Kees Dekker
-  Fixes #3474
-  Closes #3476
+  Closes https://github.com/curl/curl/pull/3623
 
-- README: add codacy code quality badge
+- AppVeyor: add MinGW-w64 build
   
-  [skip ci]
-
-- extract_if_dead: follow-up to 54b201b48c90a
+  Add a MinGW-w64 build using CMake's MSYS Makefiles generator.
+  Use the Visual Studio 2015 image as it has GCC 8, while the
+  Visual Studio 2017 image only has GCC 7.2.
   
-  extract_if_dead() dead is called from two functions, and only one of
-  them should get conn->data updated and now neither call path clears it.
+  Closes https://github.com/curl/curl/pull/3623
+
+Daniel Stenberg (27 Feb 2019)
+- cookies: only save the cookie file if the engine is enabled
   
-  scan-build found a case where conn->data would be NULL dereferenced in
-  ConnectionExists() otherwise.
+  Follow-up to 8eddb8f4259.
   
-  Closes #3473
-
-- multi: remove "Dead assignment"
+  If the cookieinfo pointer is NULL there really is nothing to save.
   
-  Found by scan-build. Follow-up to 4c35574bb785ce.
+  Without this fix, we got a problem when a handle was using shared object
+  with cookies and is told to "FLUSH" it to file (which worked) and then
+  the share object was removed and when the easy handle was closed just
+  afterwards it has no cookieinfo and no cookies so it decided to save an
+  empty jar (overwriting the file just flushed).
   
-  Closes #3471
-
-- tests: move objnames-* from lib into tests
+  Test 1905 now verifies that this works.
   
-  Since they're used purely for testing purposes, I think they should
-  rather be stored there.
+  Assisted-by: Michael Wallner
+  Assisted-by: Marcel Raad
   
-  Closes #3470
-
-Sergei Nikulov (15 Jan 2019)
-- travis: added cmake build for osx
+  Closes #3621
 
-Daniel Stenberg (14 Jan 2019)
-- [Frank Gevaerts brought this change]
+- [DaVieS brought this change]
 
-  cookie: fix comment typo (url_path_len -> uri_path_len)
+  cacertinmem.c: use multiple certificates for loading CA-chain
   
-  Closes #3469
+  Closes #3421
 
-Marcel Raad (14 Jan 2019)
-- winbuild: conditionally use /DZLIB_WINAPI
+- urldata: convert bools to bitfields and move to end
   
-  zlibwapi.lib (dynamic library) and zlibstat.lib (static library) have
-  the ZLIB_WINAPI define set by default. Using them requires that define
-  too.
+  This allows the compiler to pack and align the structs better in
+  memory. For a rather feature-complete build on x86_64 Linux, gcc 8.1.2
+  makes the Curl_easy struct 4.9% smaller. From 6312 bytes to 6000.
   
-  Ref: https://zlib.net/DLL_FAQ.txt
+  Removed an unused struct field.
   
-  Fixes https://github.com/curl/curl/issues/3133
-  Closes https://github.com/curl/curl/pull/3460
+  No functionality changes.
+  
+  Closes #3610
 
-Daniel Stenberg (14 Jan 2019)
-- src/Makefile: make 'tidy' target work for metalink builds
+- [Don J Olmstead brought this change]
 
-- extract_if_dead: use a known working transfer when checking connections
+  curl.h: use __has_declspec_attribute for shared builds
   
-  Make sure that this function sets a proper "live" transfer for the
-  connection before calling the protocol-specific connection check
-  function, and then clear it again afterward as a non-used connection has
-  no current transfer.
+  Closes #3616
+
+- curl: display --version features sorted alphabetically
   
-  Reported-by: Jeroen Ooms
-  Reviewed-by: Marcel Raad
-  Reviewed-by: Daniel Gustafsson
-  Fixes #3463
-  Closes #3464
+  Closes #3611
 
-- openssl: adapt to 3.0.0, OpenSSL_version_num() is deprecated
+- runtests: detect "schannel" as an alias for "winssl"
   
-  OpenSSL_version() replaces OpenSSL_version_num()
+  Follow-up to 180501cb02
   
-  Closes #3462
-
-Sergei Nikulov (11 Jan 2019)
-- cmake: added checks for HAVE_VARIADIC_MACROS_C99 and HAVE_VARIADIC_MACROS_GCC
+  Reported-by: Marcel Raad
+  Fixes #3609
+  Closes #3620
 
-Daniel Stenberg (11 Jan 2019)
-- urldata: rename easy_conn to just conn
+Marcel Raad (26 Feb 2019)
+- AppVeyor: update to Visual Studio 2017
   
-  We use "conn" everywhere to be a pointer to the connection.
+  Switch all Visual Studio 2015 builds to Visual Studio 2017. It's not a
+  moving target anymore as the last update, Update 9, has been released.
   
-  Introduces two functions that "attaches" and "detaches" the connection
-  to and from the transfer.
+  Closes https://github.com/curl/curl/pull/3606
+
+- AppVeyor: switch VS 2015 builds to VS 2017 image
   
-  Going forward, we should favour using "data->conn" (since a transfer
-  always only has a single connection or none at all) to "conn->data"
-  (since a connection can have none, one or many transfers associated with
-  it and updating conn->data to be correct is error prone and a frequent
-  reason for internal issues).
+  The Visual Studio 2017 image has Visual Studio 2015 and 2017 installed.
   
-  Closes #3442
+  Closes https://github.com/curl/curl/pull/3606
 
-- tool_cb_prg: avoid integer overflow
+- AppVeyor: explicitly select worker image
   
-  When calculating the progress bar width.
+  Currently, we're using the default Visual Studio 2015 image for
+  everything.
   
-  Reported-by: Peng Li
-  Fixes #3456
-  Closes #3458
+  Closes https://github.com/curl/curl/pull/3606
 
-Daniel Gustafsson (11 Jan 2019)
-- travis: turn off copyright year checks in checksrc
+Daniel Stenberg (26 Feb 2019)
+- strerror: make the strerror function use local buffers
   
-  Invoking the maintainer intended COPYRIGHTYEAR check for everyone
-  in the PR pipeline is too invasive, especially at the turn of the
-  year when many files get affected. Remove and leave it as a tool
-  for maintainers to verify patches before commits.
+  Instead of using a fixed 256 byte buffer in the connectdata struct.
   
-  This reverts f7bdf4b2e1d81b2652b81b9b3029927589273b41.
+  In my build, this reduces the size of the connectdata struct by 11.8%,
+  from 2160 to 1904 bytes with no functionality or performance loss.
   
-  After discussion with: Daniel Stenberg
-
-Daniel Stenberg (10 Jan 2019)
-- KNOWN_BUGS: cmake makes unusable tool_hugehelp.c with MinGW
+  This also fixes a bug in schannel's Curl_verify_certificate where it
+  called Curl_sspi_strerror when it should have called Curl_strerror for
+  string from GetLastError. the only effect would have been no text or the
+  wrong text being shown for the error.
   
-  Closes #3125
-
-- KNOWN_BUGS: Improve --data-urlencode space encoding
+  Co-authored-by: Jay Satiro
   
-  Closes #3229
+  Closes #3612
 
-Patrick Monnerat (10 Jan 2019)
-- os400: add a missing closing bracket
+- [Michael Wallner brought this change]
+
+  cookies: fix NULL dereference if flushing cookies with no CookieInfo set
   
-  See https://github.com/curl/curl/issues/3453#issuecomment-453054458
+  Regression brought by a52e46f3900fb0 (shipped in 7.63.0)
   
-  Reported-by: jonrumsey on github
+  Closes #3613
 
-- os400: fix extra parameter syntax error.
+Marcel Raad (26 Feb 2019)
+- AppVeyor: re-enable test 500
   
-  Reported-by: jonrumsey on github
-  Closes #3453
+  It's passing now.
+  
+  Closes https://github.com/curl/curl/pull/3615
 
-Daniel Stenberg (10 Jan 2019)
-- test1558: verify CURLINFO_PROTOCOL on file:// transfer
+- AppVeyor: remove redundant builds
   
-  Attempt to reproduce issue #3444.
+  Remove the Visual Studio 2012 and 2013 builds as they add little value.
   
-  Closes #3447
+  Ref: https://github.com/curl/curl/pull/3606
+  Closes https://github.com/curl/curl/pull/3614
 
+Daniel Stenberg (25 Feb 2019)
 - RELEASE-NOTES: synced
 
-- xattr: strip credentials from any URL that is stored
+- [Bernd Mueller brought this change]
+
+  OpenSSL: add support for TLS ASYNC state
   
-  Both user and password are cleared uncondtitionally.
+  Closes #3591
+
+Jay Satiro (25 Feb 2019)
+- [Michael Felt brought this change]
+
+  acinclude: add additional libraries to check for LDAP support
   
-  Added unit test 1621 to verify.
+  - Add an additional check for LDAP that also checks for OpenSSL since
+    on AIX those libraries may be required to link LDAP properly.
   
-  Fixes #3423
-  Closes #3433
+  Fixes https://github.com/curl/curl/issues/3595
+  Closes https://github.com/curl/curl/pull/3596
 
-- cookies: allow secure override when done over HTTPS
+- [Giorgos Oikonomou brought this change]
+
+  schannel: support CALG_ECDH_EPHEM algorithm
   
-  Added test 1562 to verify.
+  Add support for Ephemeral elliptic curve Diffie-Hellman key exchange
+  algorithm option when selecting ciphers. This became available on the
+  Win10 SDK.
   
-  Reported-by: Jeroen Ooms
-  Fixes #3445
-  Closes #3450
+  Closes https://github.com/curl/curl/pull/3608
 
-- multi: multiplexing improvements
+Daniel Stenberg (24 Feb 2019)
+- multi: call multi_done on connect timeouts
   
-  Fixes #3436
-  Closes #3448
+  Failing to do so would make the CURLINFO_TOTAL_TIME timeout to not get
+  updated correctly and could end up getting reported to the application
+  completely wrong (way too small).
   
-   Problem 1
+  Reported-by: accountantM on github
+  Fixes #3602
+  Closes #3605
+
+- examples: remove recursive calls to curl_multi_socket_action
   
-  After LOTS of scratching my head, I eventually realized that even when doing
-  10 uploads in parallel, sometimes the socket callback to the application that
-  tells it what to wait for on the socket, looked like it would reflect the
-  status of just the single transfer that just changed state.
+  From within the timer callbacks. Recursive is problematic for several
+  reasons. They should still work, but this way the examples and the
+  documentation becomes simpler. I don't think we need to encourage
+  recursive calls.
   
-  Digging into the code revealed that this was indeed the truth. When multiple
-  transfers are using the same connection, the application did not correctly get
-  the *combined* flags for all transfers which then could make it switch to READ
-  (only) when in fact most transfers wanted to get told when the socket was
-  WRITEABLE.
+  Discussed in #3537
+  Closes #3601
+
+Marcel Raad (23 Feb 2019)
+- configure: remove CURL_CHECK_FUNC_FDOPEN call
   
-   Problem 1b
+  The macro itself has been removed in commit
+  11974ac859c5d82def59e837e0db56fef7f6794e.
   
-  A separate but related regression had also been introduced by me when I
-  cleared connection/transfer association better a while ago, as now the logic
-  couldn't find the connection and see if that was marked as used by more
-  transfers and then it would also prematurely remove the socket from the socket
-  hash table even in times other transfers were still using it!
+  Closes https://github.com/curl/curl/pull/3604
+
+Daniel Stenberg (23 Feb 2019)
+- wolfssl: stop custom-adding curves
   
-   Fix 1
+  since wolfSSL PR https://github.com/wolfSSL/wolfssl/pull/717 (shipped in
+  wolfSSL 3.10.2 and later) it sends these curves by default already.
   
-  Make sure that each socket stored in the socket hash has a "combined" action
-  field of what to ask the application to wait for, that is potentially the ORed
-  action of multiple parallel transfers. And remove that socket hash entry only
-  if there are no transfers left using it.
+  Pointed-out-by: David Garske
   
-   Problem 2
+  Closes #3599
+
+- configure: remove the unused fdopen macro
   
-  The socket hash entry stored an association to a single transfer using that
-  socket - and when curl_multi_socket_action() was called to tell libcurl about
-  activities on that specific socket only that transfer was "handled".
+  and the two remaining #ifdefs for it
   
-  This was WRONG, as a single socket/connection can be used by numerous parallel
-  transfers and not necessarily a single one.
+  Closes #3600
+
+Jay Satiro (22 Feb 2019)
+- url: change conn shutdown order to unlink data as last step
   
-   Fix 2
+  - Split off connection shutdown procedure from Curl_disconnect into new
+    function conn_shutdown.
   
-  We now store a list of handles in the socket hashtable entry and when libcurl
-  is told there's traffic for a particular socket, it now iterates over all
-  known transfers using that single socket.
-
-- test1561: improve test name
+  - Change the shutdown procedure to close the sockets before
+    disassociating the transfer.
   
-  [skip ci]
-
-- [Katsuhiko YOSHIDA brought this change]
-
-  cookies: skip custom cookies when redirecting cross-site
+  Prior to this change the sockets were closed after disassociating the
+  transfer so SOCKETFUNCTION wasn't called since the transfer was already
+  disassociated. That likely came about from recent work started in
+  Jan 2019 (#3442) to separate transfers from connections.
   
-  Closes #3417
-
-- THANKS: fixups and a dedupe
+  Bug: https://curl.haxx.se/mail/lib-2019-02/0101.html
+  Reported-by: Pavel Löbl
   
-  [skip ci]
+  Closes https://github.com/curl/curl/issues/3597
+  Closes https://github.com/curl/curl/pull/3598
 
-- timediff: fix math for unsigned time_t
-  
-  Bug: https://curl.haxx.se/mail/lib-2018-12/0088.html
+Marcel Raad (22 Feb 2019)
+- Fix strict-prototypes GCC warning
   
-  Closes #3449
+  As seen in the MinGW autobuilds. Caused by commit
+  f26bc29cfec0be84c67cf74065cf8e5e78fd68b7.
 
-- [Bernhard M. Wiedemann brought this change]
+Dan Fandrich (21 Feb 2019)
+- tests: Fixed XML validation errors in some test files.
 
-  tests: allow tests to pass by 2037-02-12
-  
-  similar to commit f508d29f3902104018
+Daniel Stenberg (20 Feb 2019)
+- TODO: Allow SAN names in HTTP/2 server push
   
-  Closes #3443
+  Suggested-by: Nicolas Grekas
 
 - RELEASE-NOTES: synced
 
-- [Brad Spencer brought this change]
-
-  curl_multi_remove_handle() don't block terminating c-ares requests
-  
-  Added Curl_resolver_kill() for all three resolver modes, which only
-  blocks when necessary, along with test 1592 to confirm
-  curl_multi_remove_handle() doesn't block unless it must.
+- curl: remove MANUAL from -M output
   
-  Closes #3428
-  Fixes #3371
-
-- Revert "http_negotiate: do not close connection until negotiation is completed"
+  ... and remove it from the dist tarball. It has served its time, it
+  barely gets updated anymore and "everything curl" is now convering all
+  this document once tried to include, and does it more and better.
   
-  This reverts commit 07ebaf837843124ee670e5b8c218b80b92e06e47.
+  In the compressed scenario, this removes ~15K data from the binary,
+  which is 25% of the -M output.
   
-  This also reopens PR #3275 which brought the change now reverted.
+  It remains in the git repo for now for as long as the web site builds a
+  page using that as source. It renders poorly on the site (especially for
+  mobile users) so its not even good there.
   
-  Fixes #3384
-  Closes #3439
+  Closes #3587
 
-- curl/urlapi.h: include "curl.h" first
+- http2: verify :athority in push promise requests
   
-  This allows programs to include curl/urlapi.h directly.
+  RFC 7540 says we should verify that the push is for an "authoritative"
+  server. We make sure of this by only allowing push with an :athority
+  header that matches the host that was asked for in the URL.
   
-  Reviewed-by: Daniel Gustafsson
-  Reported-by: Ben Kohler
-  Fixes #3438
-  Closes #3441
+  Fixes #3577
+  Reported-by: Nicolas Grekas
+  Bug: https://curl.haxx.se/mail/lib-2019-02/0057.html
+  Closes #3581
 
-Marcel Raad (6 Jan 2019)
-- VS projects: fix build warning
+- singlesocket: fix the 'sincebefore' placement
   
-  Starting with Visual Studio 2017 Update 9, Visual Studio doesn't like
-  the MinimalRebuild option anymore and warns:
+  The variable wasn't properly reset within the loop and thus could remain
+  set for sockets that hadn't been set before and miss notifying the app.
   
-  cl : Command line warning D9035: option 'Gm' has been deprecated and
-  will be removed in a future release
+  This is a follow-up to 4c35574 (shipped in curl 7.64.0)
   
-  The option can be safely removed so that the default is used.
-  
-  Closes https://github.com/curl/curl/pull/3425
+  Reported-by: buzo-ffm on github
+  Detected-by: Jan Alexander Steffens
+  Fixes #3585
+  Closes #3589
 
-- schannel: fix compiler warning
+- connection: never reuse CONNECT_ONLY conections
   
-  When building with Unicode on MSVC, the compiler warns about freeing a
-  pointer to const in Curl_unicodefree. Fix this by declaring it as
-  non-const and casting the argument to Curl_convert_UTF8_to_tchar to
-  non-const too, like we do in all other places.
+  and make CONNECT_ONLY conections never reuse any existing ones either.
   
-  Closes https://github.com/curl/curl/pull/3435
-
-Daniel Stenberg (4 Jan 2019)
-- [Rikard Falkeborn brought this change]
-
-  printf: introduce CURL_FORMAT_TIMEDIFF_T
-
-- [Rikard Falkeborn brought this change]
+  Reported-by: Pavel Löbl
+  Bug: https://curl.haxx.se/mail/lib-2019-02/0064.html
+  Closes #3586
 
-  printf: fix format specifiers
+Patrick Monnerat (19 Feb 2019)
+- cli tool: fix mime post with --disable-libcurl-option configure option
   
-  Closes #3426
+  Reported-by: Marcel Raad
+  Fixes #3576
+  Closes #3583
 
-- libtest/stub_gssapi: use "real" snprintf
+Daniel Stenberg (19 Feb 2019)
+- x509asn1: cleanup and unify code layout
   
-  ... since it doesn't link with libcurl.
+  - rename 'n' to buflen in functions, and use size_t for them. Don't pass
+    in negative buffer lengths.
   
-  Reverts the commit dcd6f81025 changes from this file.
+  - move most function comments to above the function starts like we use
+    to
   
-  Bug: https://curl.haxx.se/mail/lib-2019-01/0000.html
-  Reported-by: Shlomi Fish
-  Reviewed-by: Daniel Gustafsson
-  Reviewed-by: Kamil Dudka
+  - remove several unnecessary typecasts (especially of NULL)
   
-  Closes #3434
+  Reviewed-by: Patrick Monnerat
+  Closes #3582
 
-- INTERNALS: correct some outdated function names
+- curl_multi_remove_handle.3: use at any time, just not from within callbacks
   
-  Closes #3431
+  [ci skip]
 
-- docs/version.d: mention MultiSSL
+- http: make adding a blank header thread-safe
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #3432
-
-Daniel Gustafsson (2 Jan 2019)
-- [Rikard Falkeborn brought this change]
-
-  examples: Update .gitignore
+  Previously the function would edit the provided header in-place when a
+  semicolon is used to signify an empty header. This made it impossible to
+  use the same set of custom headers in multiple threads simultaneously.
   
-  Add a few missing examples to make `make examples` not leave the
-  workspace in a dirty state.
+  This approach now makes a local copy when it needs to edit the string.
   
-  Closes #3427
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Reported-by: d912e3 on github
+  Fixes #3578
+  Closes #3579
 
-- THANKS: add more missing names
+- unit1651: survive curl_easy_init() fails
+
+- [Frank Gevaerts brought this change]
+
+  rand: Fix a mismatch between comments in source and header.
   
-  Add Adrian Burcea who made the artwork for the curl://up 2018 event
-  which was held in Stockholm, Sweden.
+  Reported-by: Björn Stenberg <bjorn@haxx.se>
+  Closes #3584
 
-- docs: mention potential leak in curl_slist_append
+Patrick Monnerat (18 Feb 2019)
+- x509asn1: replace single char with an array
   
-  When a non-empty list is appended to, and used as the returnvalue,
-  the list pointer can leak in case of an allocation failure in the
-  curl_slist_append() call. This is correctly handled in curl code
-  usage but we weren't explicitly pointing it out in the API call
-  documentation. Fix by extending the RETURNVALUE manpage section
-  and example code.
+  Although safe in this context, using a single char as an array may
+  cause invalid accesses to adjacent memory locations.
   
-  Closes #3424
-  Reported-by: dnivras on github
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Detected by Coverity.
 
-Marcel Raad (1 Jan 2019)
-- tvnow: silence conversion warnings
+Daniel Stenberg (18 Feb 2019)
+- examples/http2-serverpush: add some sensible error checks
   
-  MinGW-w64 defaults to targeting Windows 7 now, so GetTickCount64 is
-  used and the milliseconds are represented as unsigned long long,
-  leading to a compiler warning when implicitly converting them to long.
-
-Daniel Stenberg (1 Jan 2019)
-- THANKS: dedupe more names
+  To avoid NULL pointer dereferences etc in the case of problems.
   
-  Researched-by: Tae Wong
-
-Marcel Raad (1 Jan 2019)
-- [Markus Moeller brought this change]
+  Closes #3580
 
-  ntlm: update selection of type 3 response
+Jay Satiro (18 Feb 2019)
+- easy: fix win32 init to work without CURL_GLOBAL_WIN32
   
-  NTLM2 did not work i.e. no NTLMv2 response was created. Changing the
-  check seems to work.
+  - Change the behavior of win32_init so that the required initialization
+    procedures are not affected by CURL_GLOBAL_WIN32 flag.
   
-  Ref: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NLMP/[MS-NLMP].pdf
+  libcurl via curl_global_init supports initializing for win32 with an
+  optional flag CURL_GLOBAL_WIN32, which if omitted was meant to stop
+  Winsock initialization. It did so internally by skipping win32_init()
+  when that flag was set. Since then win32_init() has been expanded to
+  include required initialization routines that are separate from
+  Winsock and therefore must be called in all cases. This commit fixes
+  it so that CURL_GLOBAL_WIN32 only controls the optional win32
+  initialization (which is Winsock initialization, according to our doc).
   
-  Fixes https://github.com/curl/curl/issues/3286
-  Closes https://github.com/curl/curl/pull/3287
-  Closes https://github.com/curl/curl/pull/3415
-
-Daniel Stenberg (31 Dec 2018)
-- THANKS: added missing names from year <= 2000
+  The only users affected by this change are those that don't pass
+  CURL_GLOBAL_WIN32 to curl_global_init. For them this commit removes the
+  risk of a potential crash.
   
-  Due to a report of a missing name in THANKS I manually went through an
-  old CHANGES.0 file and added many previously missing names here.
-
-Daniel Gustafsson (30 Dec 2018)
-- urlapi: fix parsing ipv6 with zone index
+  Ref: https://github.com/curl/curl/pull/3573
   
-  The previous fix for parsing IPv6 URLs with a zone index was a paddle
-  short for URLs without an explicit port. This patch fixes that case
-  and adds a unit test case.
+  Fixes https://github.com/curl/curl/issues/3313
+  Closes https://github.com/curl/curl/pull/3575
+
+Daniel Gustafsson (17 Feb 2019)
+- cookie: Add support for cookie prefixes
   
-  This bug was highlighted by issue #3408, and while it's not the full
-  fix for the problem there it is an isolated bug that should be fixed
-  regardless.
+  The draft-ietf-httpbis-rfc6265bis-02 draft, specify a set of prefixes
+  and how they should affect cookie initialization, which has been
+  adopted by the major browsers. This adds support for the two prefixes
+  defined, __Host- and __Secure, and updates the testcase with the
+  supplied examples from the draft.
   
-  Closes #3411
-  Reported-by: GitYuanQu on github
+  Closes #3554
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Daniel Stenberg (30 Dec 2018)
-- THANKS: dedupe Guenter Knauf
+- mbedtls: release sessionid resources on error
   
-  Reported-by: Tae Wong
+  If mbedtls_ssl_get_session() fails, it may still have allocated
+  memory that needs to be freed to avoid leaking. Call the library
+  API function to release session resources on this errorpath as
+  well as on Curl_ssl_addsessionid() errors.
+  
+  Closes: #3574
+  Reported-by: Michał Antoniak <M.Antoniak@posnet.com>
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- THANKS: missing name from the 6.3.1 release!
+Patrick Monnerat (16 Feb 2019)
+- cli tool: refactor encoding conversion sequence for switch case fallthrough.
 
-Daniel Gustafsson (27 Dec 2018)
-- RELEASE-NOTES: synced
+- version.c: silent scan-build even when librtmp is not enabled
 
-- [Claes Jakobsson brought this change]
+Daniel Stenberg (15 Feb 2019)
+- RELEASE-NOTES: synced
 
-  hostip: support wildcard hosts
-  
-  This adds support for wildcard hosts in CURLOPT_RESOLVE. These are
-  try-last so any non-wildcard entry is resolved first. If specified,
-  any host not matched by another CURLOPT_RESOLVE config will use this
-  as fallback.
+- Curl_now: figure out windows version in win32_init
   
-  Example send a.com to 10.0.0.1 and everything else to 10.0.0.2:
-    curl --resolve *:443:10.0.0.2 --resolve a.com:443:10.0.0.1 \
-         https://a.com https://b.com
+  ... and avoid use of static variables that aren't thread safe.
   
-  This is probably quite similar to using:
-    --connect-to a.com:443:10.0.0.1:443 --connect-to :443:10.0.0.2:443
+  Fixes regression from e9ababd4f5a (present in the 7.64.0 release)
   
-  Closes #3406
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: Paul Groke
+  Fixes #3572
+  Closes #3573
 
-- url: fix incorrect indentation
+Marcel Raad (15 Feb 2019)
+- unit1307: just fail without FTP support
+  
+  I missed to check this in with commit
+  71786c0505926aaf7e9b2477b2fb7ee16a915ec6, which only disabled the test.
+  This fixes the actual linker error.
+  
+  Closes https://github.com/curl/curl/pull/3568
 
-Patrick Monnerat (26 Dec 2018)
-- os400: upgrade ILE/RPG binding.
+Daniel Stenberg (15 Feb 2019)
+- travis: enable valgrind for the iconv tests too
   
-  - Trailer function support.
-  - http 0.9 option.
-  - curl_easy_upkeep.
+  Closes #3571
 
-Daniel Gustafsson (25 Dec 2018)
-- FAQ: remove mention of sourceforge for github
+- travis: add scan-build
   
-  The project bug tracker is no longer hosted at sourceforge but is now
-  hosted on the curl Github page. Update the FAQ to reflect.
+  Closes #3564
+
+- examples/sftpuploadresume: Value stored to 'result' is never read
   
-  Closes #3410
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Detected by scan-build
 
-- openvms: fix typos in documentation
+- examples/http2-upload: cleaned up
+  
+  Fix scan-build warnings, no globals, no silly handle scan. Also remove
+  handles from the multi before cleaning up.
 
-- openvms: fix OpenSSL discovery on VAX
+- examples/http2-download: cleaned up
   
-  The DCL code had a typo in one of the commands which would make the
-  OpenSSL discovery on VAX fail. The correct syntax is F$ENVIRONMENT.
+  To avoid scan-build warnings and global variables.
+
+- examples/postinmemory: Potential leak of memory pointed to by 'chunk.memory'
   
-  Closes #3407
-  Reviewed-by: Viktor Szakats <commit@vszakats.net>
+  Detected by scan-build
 
-Daniel Stenberg (24 Dec 2018)
-- [Ruslan Baratov brought this change]
+- examples/httpcustomheader: Value stored to 'res' is never read
+  
+  Detected by scan-build
 
-  cmake: use lowercase for function name like the rest of the code
+- examples: remove superfluous null-pointer checks
   
-  Reviewed-by: Sergei Nikulov
+  in ftpget, ftpsget and sftpget, so that scan-build stops warning for
+  potential NULL pointer dereference below!
   
-  closes #3196
+  Detected by scan-build
 
-- Revert "libssh: no data pointer == nothing to do"
+- strip_trailing_dot: make sure NULL is never used for strlen
   
-  This reverts commit c98ee5f67f497195c9 since commit f3ce38739fa fixed the
-  problem in a more generic way.
+  scan-build warning: Null pointer passed as an argument to a 'nonnull'
+  parameter
 
-- disconnect: set conn->data for protocol disconnect
+- [Jay Satiro brought this change]
+
+  connection_check: restore original conn->data after the check
   
-  Follow-up to fb445a1e18d: Set conn->data explicitly to point out the
-  current transfer when invoking the protocol-specific disconnect function
-  so that it can work correctly.
+  - Save the original conn->data before it's changed to the specified
+    data transfer for the connection check and then restore it afterwards.
   
-  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12173
-
-Jay Satiro (23 Dec 2018)
-- [Pavel Pavlov brought this change]
-
-  timeval: Use high resolution timestamps on Windows
+  This is a follow-up to 38d8e1b 2019-02-11.
   
-  - Use QueryPerformanceCounter on Windows Vista+
+  History:
   
-  There is confusing info floating around that QueryPerformanceCounter
-  can leap etc, which might have been true long time ago, but no longer
-  the case nowadays (perhaps starting from WinXP?). Also, boost and
-  std::chrono::steady_clock use QueryPerformanceCounter in a similar way.
+  It was discovered a month ago that before checking whether to extract a
+  dead connection that that connection should be associated with a "live"
+  transfer for the check (ie original conn->data ignored and set to the
+  passed in data). A fix was landed in 54b201b which did that and also
+  cleared conn->data after the check. The original conn->data was not
+  restored, so presumably it was thought that a valid conn->data was no
+  longer needed.
   
-  Prior to this change GetTickCount or GetTickCount64 was used, which has
-  lower resolution. That is still the case for <= XP.
+  Several days later it was discovered that a valid conn->data was needed
+  after the check and follow-up fix was landed in bbae24c which partially
+  reverted the original fix and attempted to limit the scope of when
+  conn->data was changed to only when pruning dead connections. In that
+  case conn->data was not cleared and the original conn->data not
+  restored.
   
-  Fixes https://github.com/curl/curl/issues/3309
-  Closes https://github.com/curl/curl/pull/3318
-
-Daniel Stenberg (22 Dec 2018)
-- libssh: no data pointer == nothing to do
-
-- conncache_unlock: avoid indirection by changing input argument type
-
-- disconnect: separate connections and easy handles better
+  A month later it was discovered that the original fix was somewhat
+  correct; a "live" transfer is needed for the check in all cases
+  because original conn->data could be null which could cause a bad deref
+  at arbitrary points in the check. A fix was landed in 38d8e1b which
+  expanded the scope to all cases. conn->data was not cleared and the
+  original conn->data not restored.
   
-  Do not assume/store assocation between a given easy handle and the
-  connection if it can be avoided.
+  A day later it was discovered that not restoring the original conn->data
+  may lead to busy loops in applications that use the event interface, and
+  given this observation it's a pretty safe assumption that there is some
+  code path that still needs the original conn->data. This commit is the
+  follow-up fix for that, it restores the original conn->data after the
+  connection check.
   
-  Long-term, the 'conn->data' pointer should probably be removed as it is a
-  little too error-prone. Still used very widely though.
+  Assisted-by: tholin@users.noreply.github.com
+  Reported-by: tholin@users.noreply.github.com
   
-  Reported-by: masbug on github
-  Fixes #3391
-  Closes #3400
+  Fixes https://github.com/curl/curl/issues/3542
+  Closes #3559
 
-- libssh: free sftp_canonicalize_path() data correctly
+- memdebug: bring back curl_mark_sclose
   
-  Assisted-by: Harry Sintonen
+  Used by debug builds with NSS.
   
-  Fixes #3402
-  Closes #3403
-
-- RELEASE-NOTES: synced
+  Reverted from 05b100aee247bb
 
-- http: added options for allowing HTTP/0.9 responses
+Patrick Monnerat (14 Feb 2019)
+- transfer.c: do not compute length of undefined hex buffer.
   
-  Added CURLOPT_HTTP09_ALLOWED and --http0.9 for this purpose.
+  On non-ascii platforms, the chunked hex header was measured for char code
+  conversion length, even for chunked trailers that do not have an hex header.
+  In addition, the efective length is already known: use it.
+  Since the hex length can be zero, only convert if needed.
   
-  For now, both the tool and library allow HTTP/0.9 by default.
-  docs/DEPRECATE.md lays out the plan for when to reverse that default: 6
-  months after the 7.64.0 release. The options are added already now so
-  that applications/scripts can start using them already now.
+  Reported by valgrind.
+
+Daniel Stenberg (14 Feb 2019)
+- KNOWN_BUGS: Cannot compile against a static build of OpenLDAP
   
-  Fixes #2873
-  Closes #3383
+  Closes #2367
 
-- if2ip: remove unused function Curl_if_is_interface_name
+Patrick Monnerat (14 Feb 2019)
+- x509asn1: "Dereference of null pointer"
   
-  Closes #3401
+  Detected by scan-build (false positive).
 
-- http2: clear pause stream id if it gets closed
+Daniel Stenberg (14 Feb 2019)
+- configure: show features as well in the final summary
   
-  Reported-by: Florian Pritz
+  Closes #3569
+
+- KNOWN_BUGS: curl compiled on OSX 10.13 failed to run on OSX 10.10
   
-  Fixes #3392
-  Closes #3399
+  Closes #2905
 
-Daniel Gustafsson (20 Dec 2018)
-- [David Garske brought this change]
+- KNOWN_BUGS: Deflate error after all content was received
+  
+  Closes #2719
 
-  wolfssl: Perform cleanup
+- gssapi: fix deprecated header warnings
   
-  This adds a cleanup callback for cyassl. Resolves possible memory leak
-  when using ECC fixed point cache.
+  Heimdal includes on FreeBSD spewed out lots of them. Less so now.
   
-  Closes #3395
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Closes #3566
 
-Daniel Stenberg (20 Dec 2018)
-- mbedtls: follow-up VERIFYHOST fix from f097669248
+- TODO: Upgrade to websockets
   
-  Fix-by: Eric Rosenquist
+  Closes #3523
+
+- TODO: cmake test suite improvements
   
-  Fixes #3376
-  Closes #3390
+  Closes #3109
 
-- curlver: bump to 7.64.0 for next release
+Patrick Monnerat (13 Feb 2019)
+- curl: "Dereference of null pointer"
+  
+  Rephrase to satisfy scan-build.
 
-Daniel Gustafsson (19 Dec 2018)
-- cookies: extend domain checks to non psl builds
+Marcel Raad (13 Feb 2019)
+- unit1307: require FTP support
   
-  Ensure to perform the checks we have to enforce a sane domain in
-  the cookie request. The check for non-PSL enabled builds is quite
-  basic but it's better than nothing.
+  This test doesn't link without FTP support after
+  fc7ab4835b5fd09d0a6f57000633bb6bb6edfda1, which made Curl_fnmatch
+  unavailable without FTP support.
   
-  Closes #2964
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes https://github.com/curl/curl/pull/3565
 
-Daniel Stenberg (19 Dec 2018)
-- [Matus Uzak brought this change]
+Daniel Stenberg (13 Feb 2019)
+- TODO: TFO support on Windows
+  
+  Nobody works on this now.
+  
+  Closes #3378
 
-  smb: fix incorrect path in request if connection reused
+- multi: Dereference of null pointer
   
-  Follow-up to 09e401e01bf9.  If connection gets reused, then data member
-  will be copied, but not the proto member.  As a result, in smb_do(),
-  path has been set from the original proto.share data.
+  Mostly a false positive, but this makes the code easier to read anyway.
   
-  Closes #3388
+  Detected by scan-build.
+  
+  Closes #3563
 
-- curl -J: do not append to the destination file
+- urlglob: Argument with 'nonnull' attribute passed null
   
-  Reported-by: Kamil Dudka
-  Fixes #3380
-  Closes #3381
+  Detected by scan-build.
 
-- mbedtls: use VERIFYHOST
+Jay Satiro (12 Feb 2019)
+- schannel: restore some debug output but only for debug builds
   
-  Previously, VERIFYPEER would enable/disable all checks.
+  Follow-up to 84c10dc from earlier today which wrapped a lot of the noisy
+  debug output in DEBUGF but omitted a few lines.
   
-  Reported-by: Eric Rosenquist
-  Fixes #3376
-  Closes #3380
+  Ref: https://github.com/curl/curl/commit/84c10dc#r32292900
 
-- pingpong: change default response timeout to 120 seconds
+- examples/crawler: Fix the Accept-Encoding setting
   
-  Previously it was 30 minutes
-
-- pingpong: ignore regular timeout in disconnect phase
+  - Pass an empty string to CURLOPT_ACCEPT_ENCODING to use the default
+    supported encodings.
   
-  The timeout set with CURLOPT_TIMEOUT is no longer used when
-  disconnecting from one of the pingpong protocols (FTP, IMAP, SMTP,
-  POP3).
+  Prior to this change the specific encodings of gzip and deflate were set
+  but there's no guarantee they'd be supported by the user's libcurl.
+
+Daniel Stenberg (12 Feb 2019)
+- mime: put the boundary buffer into the curl_mime struct
   
-  Reported-by: jasal82 on github
+  ... instead of allocating it separately and point to it. It is
+  fixed-size and always used for each part.
   
-  Fixes #3264
-  Closes #3374
+  Closes #3561
 
-- TODO: Windows: set attribute 'archive' for completed downloads
+- schannel: be quiet
   
-  Closes #3354
+  Convert numerous infof() calls into debug-build only messages since they
+  are annoyingly verbose for regular applications. Removed a few.
+  
+  Bug: https://curl.haxx.se/mail/lib-2019-02/0027.html
+  Reported-by: Volker Schmid
+  Closes #3552
 
-- RELEASE-NOTES: synced
+- [Romain Geissler brought this change]
 
-- http: minor whitespace cleanup from f464535b
+  Curl_resolv: fix a gcc -Werror=maybe-uninitialized warning
+  
+  Closes #3562
 
-- [Ayoub Boudhar brought this change]
+- http2: multi_connchanged() moved from multi.c, only used for h2
+  
+  Closes #3557
 
-  http: Implement trailing headers for chunked transfers
+- curl: "Function call argument is an uninitialized value"
   
-  This adds the CURLOPT_TRAILERDATA and CURLOPT_TRAILERFUNCTION
-  options that allow a callback based approach to sending trailing headers
-  with chunked transfers.
+  Follow-up to cac0e4a6ad14b42471eb
   
-  The test server (sws) was updated to take into account the detection of the
-  end of transfer in the case of trailing headers presence.
+  Detected by scan-build
+  Closes #3560
+
+- pretransfer: don't strlen() POSTFIELDS set for GET requests
   
-  Test 1591 checks that trailing headers can be sent using libcurl.
+  ... since that data won't be used in the request anyway.
   
-  Closes #3350
+  Fixes #3548
+  Reported-by: Renaud Allard
+  Close #3549
 
-- darwinssl: accept setting max-tls with default min-tls
+- multi: remove verbose "Expire in" ... messages
   
-  Reported-by: Andrei Neculau
-  Fixes #3367
-  Closes #3373
-
-- gopher: fix memory leak from 9026083ddb2a9
+  Reported-by: James Brown
+  Bug: https://curl.haxx.se/mail/archive-2019-02/0013.html
+  Closes #3558
 
-- [Leonardo Taccari brought this change]
+- mbedtls: make it build even if MBEDTLS_VERSION_C isn't set
+  
+  Reported-by: MAntoniak on github
+  Fixes #3553
+  Closes #3556
 
-  test1201: Add a trailing `?' to the selector
+Daniel Gustafsson (12 Feb 2019)
+- non-ascii.c: fix typos in comments
   
-  This verify that the `?' in the selector is kept as is.
+  Fix two occurrences of s/convers/converts/ spotted while reading code.
+
+Daniel Stenberg (12 Feb 2019)
+- fnmatch: disable if FTP is disabled
   
-  Verifies the fix in #3370
+  Closes #3551
 
-- [Leonardo Taccari brought this change]
+- curl_path: only enabled for SSH builds
 
-  gopher: always include the entire gopher-path in request
+- [Frank Gevaerts brought this change]
+
+  tests: add stderr comparison to the test suite
   
-  After the migration to URL API all octets in the selector after the
-  first `?' were interpreted as query and accidentally discarded and not
-  passed to the server.
+  The code is more or less copied from the stdout comparison code, maybe
+  some better reuse is possible.
   
-  Add a gopherpath to always concatenate possible path and query URL
-  pieces.
+  test 1457 is adjusted to make the output actually match (by using --silent)
+  test 506 used <stderr> without actually needing it, so that <stderr> block is removed
   
-  Fixes #3369
-  Closes #3370
-
-- [Leonardo Taccari brought this change]
+  Closes #3536
 
-  urlapi: distinguish possibly empty query
+Patrick Monnerat (11 Feb 2019)
+- cli tool: do not use mime.h private structures.
   
-  If just a `?' to indicate the query is passed always store a zero length
-  query instead of having a NULL query.
+  Option -F generates an intermediate representation of the mime structure
+  that is used later to create the libcurl mime structure and generate
+  the --libcurl statements.
   
-  This permits to distinguish URL with trailing `?'.
+  Reported-by: Daniel Stenberg
+  Fixes #3532
+  Closes #3546
+
+Daniel Stenberg (11 Feb 2019)
+- curlver: bump to 7.64.1-dev
+
+- RELEASE-NOTES: synced
   
-  Fixes #3369
-  Closes #3370
+  and bump the version in progress to 7.64.1. If we merge any "change"
+  before the cut-off date, we update again.
 
-Daniel Gustafsson (13 Dec 2018)
-- OS400: handle memory error in list conversion
+Daniel Gustafsson (11 Feb 2019)
+- curl: follow-up to 3f16990ec84
   
-  Curl_slist_append_nodup() returns NULL when it fails to create a new
-  item for the specified list, and since the coding here reassigned the
-  new list on top of the old list it would result in a dangling pointer
-  and lost memory. Also, in case we hit an allocation failure at some
-  point during the conversion, with allocation succeeding again on the
-  subsequent call(s) we will return a truncated list around the malloc
-  failure point. Fix by assigning to a temporary list pointer, which can
-  be checked (which is the common pattern for slist appending), and free
-  all the resources on allocation failure.
+  Commit 3f16990ec84cc4b followed-up a bug in b49652ac66cc0 but was
+  inadvertently introducing a new bug in the ternary expression.
   
-  Closes #3372
+  Close #3555
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- cookies: leave secure cookies alone
+- dns: release sharelock as soon as possible
   
-  Only allow secure origins to be able to write cookies with the
-  'secure' flag set. This reduces the risk of non-secure origins
-  to influence the state of secure origins. This implements IETF
-  Internet-Draft draft-ietf-httpbis-cookie-alone-01 which updates
-  RFC6265.
+  There is no benefit to holding the data sharelock when freeing the
+  addrinfo in case it fails, so ensure releaseing it as soon as we can
+  rather than holding on to it. This also aligns the code with other
+  consumers of sharelocks.
   
-  Closes #2956
+  Closes #3516
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Daniel Stenberg (13 Dec 2018)
-- docs: fix the --tls-max description
+Daniel Stenberg (11 Feb 2019)
+- curl: follow-up to b49652ac66cc0
   
-  Reported-by: Tobias Lindgren
-  Pointed out in #3367
+  On FreeBSD, return non-zero on error otherwise zero.
   
-  Closes #3368
+  Reported-by: Marcel Raad
 
-Daniel Gustafsson (12 Dec 2018)
-- urlapi: Fix port parsing of eol colon
-  
-  A URL with a single colon without a portnumber should use the default
-  port, discarding the colon. Fix, add a testcase and also do little bit
-  of comment wordsmithing.
+- multi: (void)-prefix when ignoring return values
   
-  Closes #3365
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Version 7.63.0 (12 Dec 2018)
-
-Daniel Stenberg (12 Dec 2018)
-- RELEASE-NOTES: 7.63.0
-
-- THANKS: from the curl 7.62.0 cycle
-
-- test1519: use lib1518 and test CURLINFO_REDIRECT_URL more
+  ... and added braces to two function calls which fixes warnings if they
+  are replace by empty macros at build-time.
 
-- Curl_follow: extract the Location: header field unvalidated
-  
-  ... when not actually following the redirect. Otherwise we return error
-  for this and an application can't extract the value.
-  
-  Test 1518 added to verify.
+- curl: fix FreeBSD compiler warning in the --xattr code
   
-  Reported-by: Pavel Pavlov
-  Fixes #3340
-  Closes #3364
+  Closes #3550
 
-- multi: convert two timeout variables to timediff_t
+- connection_check: set ->data to the transfer doing the check
   
-  The time_t type is unsigned on some systems and these variables are used
-  to hold return values from functions that return timediff_t
-  already. timediff_t is always a signed type.
+  The http2 code for connection checking needs a transfer to use. Make
+  sure a working one is set before handler->connection_check() is called.
   
-  Closes #3363
+  Reported-by: jnbr on github
+  Fixes #3541
+  Closes #3547
 
-- delta: use --diff-filter on the git diff-tree invokes
+- hostip: make create_hostcache_id avoid alloc + free
   
-  Suggested-by: Dave Reisner
+  Closes #3544
 
-Patrick Monnerat (11 Dec 2018)
-- documentation: curl_formadd field and file names are now escaped
+- scripts/singleuse: script to use to track single-use functions
   
-  Prior to 7.56.0, fieldnames and filenames were set in Content-Disposition
-  header without special processing: this may lead to invalid RFC 822
-  quoted-strings.
-  7.56.0 introduces escaping of backslashes and double quotes in these names:
-  mention it in the documentation.
+  That is functions that are declared global but are not used from outside
+  of the file in which it is declared. Such functions should be made
+  static or even at times be removed.
   
-  Reported-by: daboul on github
-  Closes #3361
-
-Daniel Stenberg (11 Dec 2018)
-- scripts/delta: show repo delta info from last release
+  It also verifies that all used curl_ prefixed functions are "blessed"
   
-  ... where "last release" should be the git tag in the repo.
+  Closes #3538
 
-Daniel Gustafsson (11 Dec 2018)
-- tests: add urlapi unittest
+- cleanup: make local functions static
   
-  This adds a new unittest intended to cover the internal functions in
-  the urlapi code, starting with parse_port(). In order to avoid name
-  collisions in debug builds, parse_port() is renamed Curl_parse_port()
-  since it will be exported.
+  urlapi: turn three local-only functions into statics
   
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-
-- urlapi: fix portnumber parsing for ipv6 zone index
+  conncache: make conncache_find_first_connection static
   
-  An IPv6 URL which contains a zone index includes a '%%25<zode id>'
-  string before the ending ']' bracket. The parsing logic wasn't set
-  up to cope with the zone index however, resulting in a malformed url
-  error being returned. Fix by breaking the parsing into two stages
-  to correctly handle the zone index.
+  multi: make detach_connnection static
   
-  Closes #3355
-  Closes #3319
-  Reported-by: tonystz on Github
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-
-Daniel Stenberg (11 Dec 2018)
-- [Jay Satiro brought this change]
-
-  http: fix HTTP auth to include query in URI
+  connect: make getaddressinfo static
   
-  - Include query in the path passed to generate HTTP auth.
+  curl_ntlm_core: make hmac_md5 static
   
-  Recent changes to use the URL API internally (46e1640, 7.62.0)
-  inadvertently broke authentication URIs by omitting the query.
+  http2: make two functions static
   
-  Fixes https://github.com/curl/curl/issues/3353
-  Closes #3356
-
-- [Michael Kaufmann brought this change]
-
-  http: don't set CURLINFO_CONDITION_UNMET for http status code 204
+  http: make http_setup_conn static
   
-  The http status code 204 (No Content) should not change the "condition
-  unmet" flag. Only the http status code 304 (Not Modified) should do
-  this.
+  connect: make tcpnodelay static
   
-  Closes #359
-
-- [Samuel Surtees brought this change]
-
-  ldap: fix LDAP URL parsing regressions
+  tests: make UNITTEST a thing to mark functions with, so they can be static for
+  normal builds and non-static for unit test builds
   
-  - Match URL scheme with LDAP and LDAPS
-  - Retrieve attributes, scope and filter from URL query instead
+  ... and mark Curl_shuffle_addr accordingly.
   
-  Regression brought in 46e164069d1a5230 (7.62.0)
+  url: make up_free static
   
-  Closes #3362
-
-- RELEASE-NOTES: synced
-
-- [Stefan Kanthak brought this change]
-
-  (lib)curl.rc: fixup for minor bugs
+  setopt: make vsetopt static
   
-  All resources defined in lib/libcurl.rc and curl.rc are language
-  neutral.
+  curl_endian: make write32_le static
   
-  winbuild/MakefileBuild.vc ALWAYS defines the macro DEBUGBUILD, so the
-  ifdef's in line 33 of lib/libcurl.rc and src/curl.rc are wrong.
+  rtsp: make rtsp_connisdead static
   
-  Replace the hard-coded constants in both *.rc files with #define'd
-  values.
+  warnless: remove unused functions
   
-  Thumbs-uped-by: Rod Widdowson, Johannes Schindelin
-  URL: https://curl.haxx.se/mail/lib-2018-11/0000.html
-  Closes #3348
-
-- test329: verify cookie max-age=0 immediate expiry
+  memdebug: remove one unused function, made another static
 
-- cookies: expire "Max-Age=0" immediately
+Dan Fandrich (10 Feb 2019)
+- cirrus: Added FreeBSD builds using Cirrus CI.
   
-  Reported-by: Jeroen Ooms
-  Fixes #3351
-  Closes #3352
-
-- [Johannes Schindelin brought this change]
-
-  Upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1
-  
-  This is a companion patch to cbea2fd2c (NTLM: force the connection to
-  HTTP/1.1, 2018-12-06): with NTLM, we can switch to HTTP/1.1
-  preemptively. However, with other (Negotiate) authentication it is not
-  clear to this developer whether there is a way to make it work with
-  HTTP/2, so let's try HTTP/2 first and fall back in case we encounter the
-  error HTTP_1_1_REQUIRED.
-  
-  Note: we will still keep the NTLM workaround, as it avoids an extra
-  round trip.
-  
-  Daniel Stenberg helped a lot with this patch, in particular by
-  suggesting to introduce the Curl_h2_http_1_1_error() function.
-  
-  Closes #3349
+  The build logs will be at https://cirrus-ci.com/github/curl/curl
   
-  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-
-- [Ben Greear brought this change]
+  Some tests are currently failing and so disabled for now. The SSH server
+  isn't starting for the SSH tests due to unsupported options used in its
+  config file. The DICT server also is failing on startup.
 
-  openssl: fix unused variable compiler warning with old openssl
+Daniel Stenberg (9 Feb 2019)
+- url/idnconvert: remove scan for <= 32 ascii values
   
-  URL: https://curl.haxx.se/mail/lib-2018-11/0055.html
+  The check was added back in fa939220df before the URL parser would catch
+  these problems and therefore these will never trigger now.
   
-  Closes #3347
-
-- [Johannes Schindelin brought this change]
+  Closes #3539
 
-  NTLM: force the connection to HTTP/1.1
-  
-  Since v7.62.0, cURL tries to use HTTP/2 whenever the server announces
-  the capability. However, NTLM authentication only works with HTTP/1.1,
-  and will likely remain in that boat (for details, see
-  https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported).
-  
-  When we just found out that we want to use NTLM, and when the current
-  connection runs in HTTP/2 mode, let's force the connection to be closed
-  and to be re-opened using HTTP/1.1.
+- urlapi: reduce variable scope, remove unreachable 'break'
   
-  Fixes https://github.com/curl/curl/issues/3341.
-  Closes #3345
+  Both nits pointed out by codacy.com
   
-  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-
-- [Johannes Schindelin brought this change]
+  Closes #3540
 
-  curl_global_sslset(): id == -1 is not necessarily an error
-  
-  It is allowed to call that function with id set to -1, specifying the
-  backend by the name instead. We should imitate what is done further down
-  in that function to allow for that.
-  
-  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+Alessandro Ghedini (7 Feb 2019)
+- zsh.pl: escape ':' character
   
-  Closes #3346
-
-Johannes Schindelin (6 Dec 2018)
-- .gitattributes: make tabs in indentation a visible error
+  ':' is interpreted as separator by zsh, so if used as part of the argument
+  or option's description it needs to be escaped.
   
-  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-
-Daniel Stenberg (6 Dec 2018)
-- RELEASE-NOTES: synced
-
-- doh: fix memory leak in OOM situation
+  The problem can be reproduced as follows:
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #3342
-
-- doh: make it work for h2-disabled builds too
+   % curl --reso<TAB>
+   % curl -E <TAB>
   
-  Reported-by: dtmsecurity at github
-  Fixes #3325
-  Closes #3336
+  Bug: https://bugs.debian.org/921452
 
-- packages: remove old leftover files and dirs
-  
-  This subdir has mostly become an attic of never-used cruft from the
-  past.
+- zsh.pl: update regex to better match curl -h output
   
-  Closes #3331
-
-- [Gergely Nagy brought this change]
-
-  openssl: do not use file BIOs if not requested
+  The current regex fails to match '<...>' arguments properly (e.g. those
+  with spaces in them), which causes an completion script with wrong
+  descriptions for some options.
   
-  Moves the file handling BIO calls to the branch of the code where they
-  are actually used.
+  Here's a diff of the generated completion script, comparing the previous
+  version to the one with this fix:
   
-  Closes #3339
-
-- [Paul Howarth brought this change]
-
-  nss: Fix compatibility with nss versions 3.14 to 3.15
-
-- [Paul Howarth brought this change]
-
-  nss: Improve info message when falling back SSL protocol
+  --- /usr/share/zsh/vendor-completions/_curl     2019-01-15 20:47:40.000000000 +0000
+  +++ _curl       2019-02-05 20:57:29.453349040 +0000
+  @@ -9,48 +9,48 @@
   
-  Use descriptive text strings rather than decimal numbers.
-
-- [Paul Howarth brought this change]
+   _arguments -C -S \
+     --happy-eyeballs-timeout-ms'[How long to wait in milliseconds for IPv6 before trying IPv4]':'<milliseconds>' \
+  +  --resolve'[Resolve the host+port to this address]':'<host:port:address[,address]...>' \
+     {-c,--cookie-jar}'[Write cookies to <filename> after operation]':'<filename>':_files \
+     {-D,--dump-header}'[Write the received headers to <filename>]':'<filename>':_files \
+     {-y,--speed-time}'[Trigger '\''speed-limit'\'' abort after this time]':'<seconds>' \
+     --proxy-cacert'[CA certificate to verify peer against for proxy]':'<file>':_files \
+  -  --tls13-ciphers'[of TLS 1.3 ciphersuites> TLS 1.3 cipher suites to use]':'<list' \
+  +  --tls13-ciphers'[TLS 1.3 cipher suites to use]':'<list of TLS 1.3 ciphersuites>' \
+     {-E,--cert}'[Client certificate file and password]':'<certificate[:password]>' \
+     --libcurl'[Dump libcurl equivalent code of this command line]':'<file>':_files \
+     --proxy-capath'[CA directory to verify peer against for proxy]':'<dir>':_files \
+  -  --proxy-negotiate'[HTTP Negotiate (SPNEGO) authentication on the proxy]':'Use' \
+     --proxy-pinnedpubkey'[FILE/HASHES public key to verify proxy with]':'<hashes>' \
+     --crlfile'[Get a CRL list in PEM format from the given file]':'<file>':_files \
+  -  --proxy-insecure'[HTTPS proxy connections without verifying the proxy]':'Do' \
+  -  --proxy-ssl-allow-beast'[security flaw for interop for HTTPS proxy]':'Allow' \
+  +  --proxy-negotiate'[Use HTTP Negotiate (SPNEGO) authentication on the proxy]' \
+     --abstract-unix-socket'[Connect via abstract Unix domain socket]':'<path>' \
+     --pinnedpubkey'[FILE/HASHES Public key to verify peer against]':'<hashes>' \
+  +  --proxy-insecure'[Do HTTPS proxy connections without verifying the proxy]' \
+     --proxy-pass'[Pass phrase for the private key for HTTPS proxy]':'<phrase>' \
+  +  --proxy-ssl-allow-beast'[Allow security flaw for interop for HTTPS proxy]' \
+     {-p,--proxytunnel}'[Operate through an HTTP proxy tunnel (using CONNECT)]' \
+     --socks5-hostname'[SOCKS5 proxy, pass host name to proxy]':'<host[:port]>' \
+     --proto-default'[Use PROTOCOL for any URL missing a scheme]':'<protocol>' \
+  -  --proxy-tls13-ciphers'[list> TLS 1.3 proxy cipher suites]':'<ciphersuite' \
+  +  --proxy-tls13-ciphers'[TLS 1.3 proxy cipher suites]':'<ciphersuite list>' \
+     --socks5-gssapi-service'[SOCKS5 proxy service name for GSS-API]':'<name>' \
+     --ftp-alternative-to-user'[String to replace USER \[name\]]':'<command>' \
+  -  --ftp-ssl-control'[SSL/TLS for FTP login, clear for transfer]':'Require' \
+     {-T,--upload-file}'[Transfer local FILE to destination]':'<file>':_files \
+     --local-port'[Force use of RANGE for local port numbers]':'<num/range>' \
+     --proxy-tlsauthtype'[TLS authentication type for HTTPS proxy]':'<type>' \
+     {-R,--remote-time}'[Set the remote file'\''s time on the local output]' \
+  -  --retry-connrefused'[on connection refused (use with --retry)]':'Retry' \
+  -  --suppress-connect-headers'[proxy CONNECT response headers]':'Suppress' \
+  -  {-j,--junk-session-cookies}'[session cookies read from file]':'Ignore' \
+  -  --location-trusted'[--location, and send auth to other hosts]':'Like' \
+  +  --ftp-ssl-control'[Require SSL/TLS for FTP login, clear for transfer]' \
+     --proxy-cert-type'[Client certificate type for HTTPS proxy]':'<type>' \
+     {-O,--remote-name}'[Write output to a file named as the remote file]' \
+  +  --retry-connrefused'[Retry on connection refused (use with --retry)]' \
+  +  --suppress-connect-headers'[Suppress proxy CONNECT response headers]' \
+     --trace-ascii'[Like --trace, but without hex output]':'<file>':_files \
+     --connect-timeout'[Maximum time allowed for connection]':'<seconds>' \
+     --expect100-timeout'[How long to wait for 100-continue]':'<seconds>' \
+     {-g,--globoff}'[Disable URL sequences and ranges using {} and \[\]]' \
+  +  {-j,--junk-session-cookies}'[Ignore session cookies read from file]' \
+     {-m,--max-time}'[Maximum time allowed for the transfer]':'<seconds>' \
+     --dns-ipv4-addr'[IPv4 address to use for DNS requests]':'<address>' \
+     --dns-ipv6-addr'[IPv6 address to use for DNS requests]':'<address>' \
+  -  --ignore-content-length'[the size of the remote resource]':'Ignore' \
+     {-k,--insecure}'[Allow insecure server connections when using SSL]' \
+  +  --location-trusted'[Like --location, and send auth to other hosts]' \
+     --mail-auth'[Originator address of the original email]':'<address>' \
+     --noproxy'[List of hosts which do not use proxy]':'<no-proxy-list>' \
+     --proto-redir'[Enable/disable PROTOCOLS on redirect]':'<protocols>' \
+  @@ -62,18 +62,19 @@
+     --socks5-basic'[Enable username/password auth for SOCKS5 proxies]' \
+     --cacert'[CA certificate to verify peer against]':'<file>':_files \
+     {-H,--header}'[Pass custom header(s) to server]':'<header/@file>' \
+  +  --ignore-content-length'[Ignore the size of the remote resource]' \
+     {-i,--include}'[Include protocol response headers in the output]' \
+     --proxy-header'[Pass custom header(s) to proxy]':'<header/@file>' \
+     --unix-socket'[Connect through this Unix domain socket]':'<path>' \
+     {-w,--write-out}'[Use output FORMAT after completion]':'<format>' \
+  -  --http2-prior-knowledge'[HTTP 2 without HTTP/1.1 Upgrade]':'Use' \
+     {-o,--output}'[Write to file instead of stdout]':'<file>':_files \
+  -  {-J,--remote-header-name}'[the header-provided filename]':'Use' \
+  +  --preproxy'[\[protocol://\]host\[:port\] Use this proxy first]' \
+     --socks4a'[SOCKS4a proxy on given host + port]':'<host[:port]>' \
+     {-Y,--speed-limit}'[Stop transfers slower than this]':'<speed>' \
+     {-z,--time-cond}'[Transfer based on a time condition]':'<time>' \
+     --capath'[CA directory to verify peer against]':'<dir>':_files \
+     {-f,--fail}'[Fail silently (no output at all) on HTTP errors]' \
+  +  --http2-prior-knowledge'[Use HTTP 2 without HTTP/1.1 Upgrade]' \
+     --proxy-tlspassword'[TLS password for HTTPS proxy]':'<string>' \
+     {-U,--proxy-user}'[Proxy user and password]':'<user:password>' \
+     --proxy1.0'[Use HTTP/1.0 proxy on given port]':'<host[:port]>' \
+  @@ -81,52 +82,49 @@
+     {-A,--user-agent}'[Send User-Agent <name> to server]':'<name>' \
+     --egd-file'[EGD socket path for random data]':'<file>':_files \
+     --fail-early'[Fail on first transfer error, do not continue]' \
+  -  --haproxy-protocol'[HAProxy PROXY protocol v1 header]':'Send' \
+  -  --preproxy'[Use this proxy first]':'[protocol://]host[:port]' \
+  +  {-J,--remote-header-name}'[Use the header-provided filename]' \
+     --retry-max-time'[Retry only within this period]':'<seconds>' \
+     --socks4'[SOCKS4 proxy on given host + port]':'<host[:port]>' \
+     --socks5'[SOCKS5 proxy on given host + port]':'<host[:port]>' \
+  -  --socks5-gssapi-nec'[with NEC SOCKS5 server]':'Compatibility' \
+  -  --ssl-allow-beast'[security flaw to improve interop]':'Allow' \
+     --cert-status'[Verify the status of the server certificate]' \
+  -  --ftp-create-dirs'[the remote dirs if not present]':'Create' \
+     {-:,--next}'[Make next URL use its separate set of options]' \
+     --proxy-key-type'[Private key file type for proxy]':'<type>' \
+  -  --remote-name-all'[the remote file name for all URLs]':'Use' \
+     {-X,--request}'[Specify request command to use]':'<command>' \
+     --retry'[Retry request if transient problems occur]':'<num>' \
+  -  --ssl-no-revoke'[cert revocation checks (WinSSL)]':'Disable' \
+     --cert-type'[Certificate file type (DER/PEM/ENG)]':'<type>' \
+     --connect-to'[Connect to host]':'<HOST1:PORT1:HOST2:PORT2>' \
+     --create-dirs'[Create necessary local directory hierarchy]' \
+  +  --haproxy-protocol'[Send HAProxy PROXY protocol v1 header]' \
+     --max-redirs'[Maximum number of redirects allowed]':'<num>' \
+     {-n,--netrc}'[Must read .netrc for user name and password]' \
+  +  {-x,--proxy}'[\[protocol://\]host\[:port\] Use this proxy]' \
+     --proxy-crlfile'[Set a CRL list for proxy]':'<file>':_files \
+     --sasl-ir'[Enable initial response in SASL authentication]' \
+  -  --socks5-gssapi'[GSS-API auth for SOCKS5 proxies]':'Enable' \
+  +  --socks5-gssapi-nec'[Compatibility with NEC SOCKS5 server]' \
+  +  --ssl-allow-beast'[Allow security flaw to improve interop]' \
+  +  --ftp-create-dirs'[Create the remote dirs if not present]' \
+     --interface'[Use network INTERFACE (or address)]':'<name>' \
+     --key-type'[Private key file type (DER/PEM/ENG)]':'<type>' \
+     --netrc-file'[Specify FILE for netrc]':'<filename>':_files \
+     {-N,--no-buffer}'[Disable buffering of the output stream]' \
+     --proxy-service-name'[SPNEGO proxy service name]':'<name>' \
+  -  --styled-output'[styled output for HTTP headers]':'Enable' \
+  +  --remote-name-all'[Use the remote file name for all URLs]' \
+  +  --ssl-no-revoke'[Disable cert revocation checks (WinSSL)]' \
+     --max-filesize'[Maximum file size to download]':'<bytes>' \
+     --negotiate'[Use HTTP Negotiate (SPNEGO) authentication]' \
+     --no-keepalive'[Disable TCP keepalive on the connection]' \
+     {-#,--progress-bar}'[Display transfer progress as a bar]' \
+  -  {-x,--proxy}'[Use this proxy]':'[protocol://]host[:port]' \
+  -  --proxy-anyauth'[any proxy authentication method]':'Pick' \
+     {-Q,--quote}'[Send command(s) to server before transfer]' \
+  -  --request-target'[the target for this request]':'Specify' \
+  +  --socks5-gssapi'[Enable GSS-API auth for SOCKS5 proxies]' \
+     {-u,--user}'[Server user and password]':'<user:password>' \
+     {-K,--config}'[Read config from a file]':'<file>':_files \
+     {-C,--continue-at}'[Resumed transfer offset]':'<offset>' \
+     --data-raw'[HTTP POST data, '\''@'\'' allowed]':'<data>' \
+  -  --disallow-username-in-url'[username in url]':'Disallow' \
+     --krb'[Enable Kerberos with security <level>]':'<level>' \
+     --proxy-ciphers'[SSL ciphers to use for proxy]':'<list>' \
+     --proxy-digest'[Use Digest authentication on the proxy]' \
+     --proxy-tlsuser'[TLS username for HTTPS proxy]':'<name>' \
+  +  --styled-output'[Enable styled output for HTTP headers]' \
+     {-b,--cookie}'[Send cookies from string/file]':'<data>' \
+     --data-urlencode'[HTTP POST data url encoded]':'<data>' \
+     --delegation'[GSS-API delegation permission]':'<LEVEL>' \
+  @@ -134,7 +132,10 @@
+     --post301'[Do not switch to GET after following a 301]' \
+     --post302'[Do not switch to GET after following a 302]' \
+     --post303'[Do not switch to GET after following a 303]' \
+  +  --proxy-anyauth'[Pick any proxy authentication method]' \
+  +  --request-target'[Specify the target for this request]' \
+     --trace-time'[Add time stamps to trace/verbose output]' \
+  +  --disallow-username-in-url'[Disallow username in url]' \
+     --dns-servers'[DNS server addrs to use]':'<addresses>' \
+     {-G,--get}'[Put the post data in the URL and use GET]' \
+     --limit-rate'[Limit transfer speed to RATE]':'<speed>' \
+  @@ -148,21 +149,21 @@
+     --metalink'[Process given URLs as metalink XML file]' \
+     --tr-encoding'[Request compressed transfer encoding]' \
+     --xattr'[Store metadata in extended file attributes]' \
+  -  --ftp-skip-pasv-ip'[the IP address for PASV]':'Skip' \
+     --pass'[Pass phrase for the private key]':'<phrase>' \
+     --proxy-ntlm'[Use NTLM authentication on the proxy]' \
+     {-S,--show-error}'[Show error even when -s is used]' \
+  -  --ciphers'[of ciphers> SSL ciphers to use]':'<list' \
+  +  --ciphers'[SSL ciphers to use]':'<list of ciphers>' \
+     --form-string'[Specify multipart MIME data]':'<name=string>' \
+     --login-options'[Server login options]':'<options>' \
+     --tftp-blksize'[Set TFTP BLKSIZE option]':'<value>' \
+  -  --tftp-no-options'[not send any TFTP options]':'Do' \
+     {-v,--verbose}'[Make the operation more talkative]' \
+  +  --ftp-skip-pasv-ip'[Skip the IP address for PASV]' \
+     --proxy-key'[Private key for HTTPS proxy]':'<key>' \
+     {-F,--form}'[Specify multipart MIME data]':'<name=content>' \
+     --mail-from'[Mail from this address]':'<address>' \
+     --oauth2-bearer'[OAuth 2 Bearer Token]':'<token>' \
+     --proto'[Enable/disable PROTOCOLS]':'<protocols>' \
+  +  --tftp-no-options'[Do not send any TFTP options]' \
+     --tlsauthtype'[TLS authentication type]':'<type>' \
+     --doh-url'[Resolve host names over DOH]':'<URL>' \
+     --no-sessionid'[Disable SSL session-ID reusing]' \
+  @@ -173,14 +174,13 @@
+     --ftp-ssl-ccc'[Send CCC after authenticating]' \
+     {-4,--ipv4}'[Resolve names to IPv4 addresses]' \
+     {-6,--ipv6}'[Resolve names to IPv6 addresses]' \
+  -  --netrc-optional'[either .netrc or URL]':'Use' \
+     --service-name'[SPNEGO service name]':'<name>' \
+     {-V,--version}'[Show version number and quit]' \
+     --data-ascii'[HTTP POST ASCII data]':'<data>' \
+     --ftp-account'[Account data string]':'<data>' \
+  -  --compressed-ssh'[SSH compression]':'Enable' \
+     --disable-eprt'[Inhibit using EPRT or LPRT]' \
+     --ftp-method'[Control CWD usage]':'<method>' \
+  +  --netrc-optional'[Use either .netrc or URL]' \
+     --pubkey'[SSH Public key file name]':'<key>' \
+     --raw'[Do HTTP "raw"; no transfer decoding]' \
+     --anyauth'[Pick any authentication method]' \
+  @@ -189,6 +189,7 @@
+     --no-alpn'[Disable the ALPN TLS extension]' \
+     --tcp-nodelay'[Use the TCP_NODELAY option]' \
+     {-B,--use-ascii}'[Use ASCII/text transfer]' \
+  +  --compressed-ssh'[Enable SSH compression]' \
+     --digest'[Use HTTP Digest Authentication]' \
+     --proxy-tlsv1'[Use TLSv1 for HTTPS proxy]' \
+     --engine'[Crypto engine to use]':'<name>' \
 
-  nss: Fall back to latest supported SSL version
-  
-  NSS may be built without support for the latest SSL/TLS versions,
-  leading to "SSL version range is not valid" errors when the library
-  code supports a recent version (e.g. TLS v1.3) but it has explicitly
-  been disabled.
+Marcel Raad (7 Feb 2019)
+- tool_operate: fix typecheck warning
   
-  This change adjusts the maximum SSL version requested by libcurl to
-  be the maximum supported version at runtime, as long as that version
-  is at least as high as the minimum version required by libcurl.
+  Use long for CURLOPT_HTTP09_ALLOWED to fix the following warning:
+  tool_operate.c: In function 'operate_do':
+  ../include/curl/typecheck-gcc.h:47:9: error: call to
+  '_curl_easy_setopt_err_long' declared with attribute warning:
+  curl_easy_setopt expects a long argument for this option [-Werror]
   
-  Fixes #3261
+  Closes https://github.com/curl/curl/pull/3534
 
-Daniel Gustafsson (3 Dec 2018)
-- travis: enable COPYRIGHTYEAR extended warning
-  
-  The extended warning for checking incorrect COPYRIGHTYEAR is quite
-  expensive to run, so rather than expecting every developer to do it
-  we ensure it's turned on locally for Travis.
+Jay Satiro (6 Feb 2019)
+- [Chris Araman brought this change]
 
-- checksrc: add COPYRIGHTYEAR check
-  
-  Forgetting to bump the year in the copyright clause when hacking has
-  been quite common among curl developers, but a traditional checksrc
-  check isn't a good fit as it would penalize anyone hacking on January
-  1st (among other things). This adds a more selective COPYRIGHTYEAR
-  check which intends to only cover the currently hacked on changeset.
+  url: close TLS before removing conn from cache
   
-  The check for updated copyright year is currently not enforced on all
-  files but only on files edited and/or committed locally. This is due to
-  the amount of files which aren't updated with their correct copyright
-  year at the time of their respective commit.
+  - Fix potential crashes in schannel shutdown.
   
-  To further avoid running this expensive check for every developer, it
-  adds a new local override mode for checksrc where a .checksrc file can
-  be used to turn on extended warnings locally.
+  Ensure any TLS shutdown messages are sent before removing the
+  association between the connection and the easy handle. Reverts
+  @bagder's previous partial fix for #3412.
   
-  Closes #3303
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Fixes https://github.com/curl/curl/issues/3412
+  Fixes https://github.com/curl/curl/issues/3505
+  Closes https://github.com/curl/curl/pull/3531
 
-Daniel Stenberg (3 Dec 2018)
-- CHECKSRC.md: document more warnings
+Daniel Gustafsson (6 Feb 2019)
+- INTERNALS.md: fix subsection depth and link
   
-  Closes #3335
-  [ci skip]
+  The Kerberos subsection was mistakenly a subsubsection under FTP, and
+  the curlx subsection was missing an anchor for the TOC link.
+  
+  Closes #3529
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- RELEASE-NOTES: synced
+Version 7.64.0 (6 Feb 2019)
 
-- SECURITY-PROCESS: bountygraph shuts down
-  
-  This backpedals back the documents to the state before bountygraph.
-  
-  Closes #3311
+Daniel Stenberg (6 Feb 2019)
+- RELEASE-NOTES: 7.64.0
 
-- curl: fix memory leak reading --writeout from file
-  
-  If another string had been set first, the writout function for reading
-  the syntax from file would leak the previously allocated memory.
-  
-  Reported-by: Brian Carpenter
-  Fixes #3322
-  Closes #3330
+- RELEASE-PROCEDURE: update the release calendar
 
-- tool_main: rename function to make it unique and better
-  
-  ... there's already another function in the curl tool named
-  free_config_fields!
+- THANKS: 7.64.0 status
 
-Daniel Gustafsson (29 Nov 2018)
-- TODO: remove CURLOPT_DNS_USE_GLOBAL_CACHE entry
+Daniel Gustafsson (5 Feb 2019)
+- ROADMAP: remove already performed item
   
-  Commit 7c5837e79280e6abb3ae143dfc49bca5e74cdd11 deprecated the option
-  making it a manual code-edit operation to turn it back on. The removal
-  process has thus started and is now documented in docs/DEPRECATE.md so
-  remove from the TODO to avoid anyone looking for something to pick up
-  spend cycles on an already in-progress entry.
+  Commit 7a09b52c98ac8d840a8a9907b1a1d9a9e684bcf5 introduced support
+  for the draft-ietf-httpbis-cookie-alone-01 cookie draft, and while
+  the entry was removed from the TODO it was mistakenly left here.
+  Fix by removing and rewording the entry slightly.
   
+  Closes #3530
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Jay Satiro (29 Nov 2018)
-- [Sevan Janiyan brought this change]
+- [Etienne Simard brought this change]
 
-  connect: fix building for recent versions of Minix
+  CONTRIBUTE.md: Fix grammatical errors
   
-  EBADIOCTL doesn't exist on more recent Minix.
-  There have also been substantial changes to the network stack.
-  Fixes build on Minix 3.4rc
+  Fix grammatical errors making the document read better. Also fixes
+  a typo.
   
-  Closes https://github.com/curl/curl/pull/3323
-
-- [Konstantin Kushnir brought this change]
+  Closes #3525
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-  CMake: fix MIT/Heimdal Kerberos detection
-  
-  - fix syntax error in FindGSS.cmake
-  - correct krb5 include directory. FindGSS exports
-    "GSS_INCLUDE_DIR" variable.
-  
-  Closes https://github.com/curl/curl/pull/3316
+Daniel Stenberg (4 Feb 2019)
+- [Julian Z brought this change]
 
-Daniel Stenberg (28 Nov 2018)
-- test328: verify Content-Encoding: none
-  
-  Because of issue #3315
+  docs: use $(INSTALL_DATA) to install man page
   
-  Closes #3317
+  Fixes #3518
+  Closes #3522
 
-- [James Knight brought this change]
+Jay Satiro (4 Feb 2019)
+- [Ladar Levison brought this change]
 
-  configure: include all libraries in ssl-libs fetch
+  runtests.pl: Fix perl call to include srcdir
   
-  When compiling a collection of SSL libraries to link against (SSL_LIBS),
-  ensure all libraries are included. The call `--libs-only-l` can produce
-  only a subset of found in a `--libs` call (e.x. pthread may be excluded).
-  Adding `--libs-only-other` ensures other libraries are also included in
-  the list. This corrects select build environments compiling against a
-  static version of OpenSSL. Before the change, the following could be
-  observed:
+  - Use explicit include opt for perl calls.
   
-      checking for openssl options with pkg-config... found
-      configure: pkg-config: SSL_LIBS: "-lssl -lz -ldl -lcrypto -lz -ldl "
-      configure: pkg-config: SSL_LDFLAGS: "-L/home/jdknight/<workdir>/staging/usr/lib -L/home/jdknight/<workdir>/staging/usr/lib "
-      configure: pkg-config: SSL_CPPFLAGS: "-I/home/jdknight/<workdir>/staging/usr/include "
-      checking for HMAC_Update in -lcrypto... no
-      checking for HMAC_Init_ex in -lcrypto... no
-      checking OpenSSL linking with -ldl... no
-      checking OpenSSL linking with -ldl and -lpthread... no
-      configure: WARNING: SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.
-      configure: WARNING: Use --with-ssl, --with-gnutls, --with-polarssl, --with-cyassl, --with-nss, --with-axtls, --with-winssl, or --with-darwinssl to address this.
-      ...
-      SSL support:      no      (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,axtls,winssl,darwinssl} )
-      ...
+  Prior to this change some scripts couldn't find their dependencies.
   
-  And include the other libraries when compiling SSL_LIBS succeeds with:
+  At the top, perl is called using with the "-Isrcdir" option, and it
+  works:
   
-      checking for openssl options with pkg-config... found
-      configure: pkg-config: SSL_LIBS: "-lssl -lz -ldl -pthread -lcrypto -lz -ldl -pthread "
-      configure: pkg-config: SSL_LDFLAGS: "-L/home/jdknight/<workdir>/staging/usr/lib -L/home/jdknight/<workdir>/staging/usr/lib "
-      configure: pkg-config: SSL_CPPFLAGS: "-I/home/jdknight/<workdir>/staging/usr/include "
-      checking for HMAC_Update in -lcrypto... yes
-      checking for SSL_connect in -lssl... yes
-      ...
-      SSL support:      enabled (OpenSSL)
-      ...
+  https://github.com/curl/curl/blob/curl-7_63_0/tests/runtests.pl#L183
   
-  Signed-off-by: James Knight <james.d.knight@live.com>
-  Closes #3193
-
-Daniel Gustafsson (26 Nov 2018)
-- doh: fix typo in infof call
+  But on line 3868, that option is omitted. This caused problems for me,
+  as the symbol-scan.pl script in particular couldn't find its
+  dependencies properly:
   
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-- cmdline-opts/gen.pl: define the correct varname
+  https://github.com/curl/curl/blob/curl-7_63_0/tests/runtests.pl#L3868
   
-  The variable definition had a small typo making it declare another
-  variable then the intended.
+  This patch fixes that oversight by making calls to perl sub-shells
+  uniform.
   
-  Closes #3304
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes https://github.com/curl/curl/pull/3496
 
-Daniel Stenberg (25 Nov 2018)
-- RELEASE-NOTES: synced
+Daniel Stenberg (4 Feb 2019)
+- [Daniel Gustafsson brought this change]
 
-- curl_easy_perform: fix timeout handling
+  smtp: avoid risk of buffer overflow in strtol
   
-  curl_multi_wait() was erroneously used from within
-  curl_easy_perform(). It could lead to it believing there was no socket
-  to wait for and then instead sleep for a while instead of monitoring the
-  socket and then miss acting on that activity as swiftly as it should
-  (causing an up to 1000 ms delay).
+  If the incoming len 5, but the buffer does not have a termination
+  after 5 bytes, the strtol() call may keep reading through the line
+  buffer until is exceeds its boundary. Fix by ensuring that we are
+  using a bounded read with a temporary buffer on the stack.
   
-  Reported-by: Antoni Villalonga
-  Fixes #3305
-  Closes #3306
-  Closes #3308
+  Bug: https://curl.haxx.se/docs/CVE-2019-3823.html
+  Reported-by: Brian Carpenter (Geeknik Labs)
+  CVE-2019-3823
 
-- CURLOPT_WRITEFUNCTION.3: spell out that it gets called many times
+- ntlm: fix *_type3_message size check to avoid buffer overflow
+  
+  Bug: https://curl.haxx.se/docs/CVE-2019-3822.html
+  Reported-by: Wenxiang Qian
+  CVE-2019-3822
 
-- cookies: create the cookiejar even if no cookies to save
+- NTLM: fix size check condition for type2 received data
   
-  Important for when the file is going to be read again and thus must not
-  contain old contents!
+  Bug: https://curl.haxx.se/docs/CVE-2018-16890.html
+  Reported-by: Wenxiang Qian
+  CVE-2018-16890
+
+Marcel Raad (1 Feb 2019)
+- [Giorgos Oikonomou brought this change]
+
+  spnego_sspi: add support for channel binding
   
-  Adds test 327 to verify.
+  Attempt to add support for Secure Channel binding when negotiate
+  authentication is used. The problem to solve is that by default IIS
+  accepts channel binding and curl doesn't utilise them. The result was a
+  401 response. Scope affects only the Schannel(winssl)-SSPI combination.
   
-  Reported-by: daboul on github
-  Fixes #3299
-  Closes #3300
+  Fixes https://github.com/curl/curl/issues/3503
+  Closes https://github.com/curl/curl/pull/3509
 
-- checksrc: ban snprintf use, add command line flag to override warns
+Daniel Stenberg (1 Feb 2019)
+- RELEASE-NOTES: synced
 
-- snprintf: renamed and we now only use msnprintf()
+- schannel: stop calling it "winssl"
   
-  The function does not return the same value as snprintf() normally does,
-  so readers may be mislead into thinking the code works differently than
-  it actually does. A different function name makes this easier to detect.
+  Stick to "Schannel" everywhere. The configure option --with-winssl is
+  kept to allow existing builds to work but --with-schannel is added as an
+  alias.
   
-  Reported-by: Tomas Hoger
-  Assisted-by: Daniel Gustafsson
-  Fixes #3296
-  Closes #3297
-
-- [Tobias Hintze brought this change]
+  Closes #3504
 
-  test: update test20/1322 for eglibc bug workaround
+- multi: set the EXPIRE_*TIMEOUT timers at TIMER_STARTSINGLE time
   
-  The tests 20 and 1322 are using getaddrinfo of libc for resolving. In
-  eglibc-2.19 there is a memory leakage and invalid free bug which
-  surfaces in some special circumstances (PF_UNSPEC hint with invalid or
-  non-existent names). The valgrind runs in testing fail in these
-  situations.
+  To make sure Curl_timeleft() also thinks the timeout has been reached
+  when one of the EXPIRE_*TIMEOUTs expires.
   
-  As the tests 20/1322 are not specific on either protocol (IPv4/IPv6)
-  this commit changes the hints to IPv4 protocol by passing `--ipv4` flag
-  on the tests' command line.  This prevents the valgrind failures.
+  Bug: https://curl.haxx.se/mail/lib-2019-01/0073.html
+  Reported-by: Zhao Yisha
+  Closes #3501
 
-- [Tobias Hintze brought this change]
+- [John Marshall brought this change]
 
-  host names: allow trailing dot in name resolve, then strip it
+  doc: use meaningless port number in CURLOPT_LOCALPORT example
   
-  Delays stripping of trailing dots to after resolving the hostname.
+  Use an ephemeral port number here; previously the example had 8080
+  which could be confusing as the common web server port number might
+  be misinterpreted as suggesting this option affects the remote port.
   
-  Fixes #3022
-  Closes #3222
+  URL: https://curl.haxx.se/mail/lib-2019-01/0084.html
+  Closes #3513
 
-- [UnknownShadow200 brought this change]
+GitHub (29 Jan 2019)
+- [Gisle Vanem brought this change]
 
-  CURLOPT_HEADERFUNCTION.3: match 'nitems' name in synopsis and description
+  Escape the '\'
   
-  Closes #3295
-
-Daniel Gustafsson (21 Nov 2018)
-- configure: Fix typo in comment
+  A backslash should be escaped in Roff / Troff.
 
-Michael Kaufmann (21 Nov 2018)
-- openssl: support session resume with TLS 1.3
-  
-  Session resumption information is not available immediately after a TLS 1.3
-  handshake. The client must wait until the server has sent a session ticket.
+Jay Satiro (29 Jan 2019)
+- TODO: WinSSL: 'Add option to disable client cert auto-send'
   
-  Use OpenSSL's "new session" callback to get the session information and put it
-  into curl's session cache. For TLS 1.3 sessions, this callback will be invoked
-  after the server has sent a session ticket.
+  By default WinSSL selects and send a client certificate automatically,
+  but for privacy and consistency we should offer an option to disable the
+  default auto-send behavior.
   
-  The "new session" callback is invoked only if OpenSSL's session cache is
-  enabled, so enable it and use the "external storage" mode which lets curl manage
-  the contents of the session cache.
+  Reported-by: Jeroen Ooms
   
-  A pointer to the connection data and the sockindex are now saved as "SSL extra
-  data" to make them available to the callback.
+  Closes https://github.com/curl/curl/issues/2262
+
+Daniel Stenberg (28 Jan 2019)
+- [Jeremie Rapin brought this change]
+
+  sigpipe: if mbedTLS is used, ignore SIGPIPE
   
-  This approach also works for old SSL/TLS versions and old OpenSSL versions.
+  mbedTLS doesn't have a sigpipe management. If a write/read occurs when
+  the remote closes the socket, the signal is raised and kills the
+  application.  Use the curl mecanisms fix this behavior.
   
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Signed-off-by: Jeremie Rapin <j.rapin@overkiz.com>
   
-  Fixes #3202
-  Closes #3271
+  Closes #3502
 
-- ssl: fix compilation with OpenSSL 0.9.7
+- unit1653: make it survive torture tests
+
+Jay Satiro (28 Jan 2019)
+- [Michael Kujawa brought this change]
+
+  timeval: Disable MSVC Analyzer GetTickCount warning
   
-  - ENGINE_cleanup() was used without including "openssl/engine.h"
-  - enable engine support for OpenSSL 0.9.7
+  Compiling with msvc /analyze and a recent Windows SDK warns against
+  using GetTickCount (Suggests to use GetTickCount64 instead.)
   
-  Closes #3266
+  Since GetTickCount is only being used when GetTickCount64 isn't
+  available, I am disabling that warning.
+  
+  Fixes https://github.com/curl/curl/issues/3437
+  Closes https://github.com/curl/curl/pull/3440
 
-Daniel Stenberg (21 Nov 2018)
-- openssl: disable TLS renegotiation with BoringSSL
+Daniel Stenberg (26 Jan 2019)
+- configure: rewrite --enable-code-coverage
   
-  Since we're close to feature freeze, this change disables this feature
-  with an #ifdef. Define ALLOW_RENEG at build-time to enable.
+  The previously used ax_code_coverage.m4 is not license compatible and
+  must not be used.
   
-  This could be converted to a bit for CURLOPT_SSL_OPTIONS to let
-  applications opt-in this.
+  Reported-by: William A. Rowe Jr
+  Fixes #3497
+  Closes #3499
+
+- [Felix Hädicke brought this change]
+
+  setopt: enable CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION for libssh
   
-  Concern-raised-by: David Benjamin
-  Fixes #3283
-  Closes #3293
+  CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION are supported for
+  libssh as well. So accepting these options only when compiling with
+  libssh2 is wrong here.
+  
+  Fixes #3493
+  Closes #3494
 
-- [Romain Fliedel brought this change]
+- [Felix Hädicke brought this change]
 
-  ares: remove fd from multi fd set when ares is about to close the fd
+  libssh: do not let libssh create socket
   
-  When using c-ares for asyn dns, the dns socket fd was silently closed
-  by c-ares without curl being aware. curl would then 'realize' the fd
-  has been removed at next call of Curl_resolver_getsock, and only then
-  notify the CURLMOPT_SOCKETFUNCTION to remove fd from its poll set with
-  CURL_POLL_REMOVE. At this point the fd is already closed.
+  By default, libssh creates a new socket, instead of using the socket
+  created by curl for SSH connections.
   
-  By using ares socket state callback (ARES_OPT_SOCK_STATE_CB), this
-  patch allows curl to be notified that the fd is not longer needed
-  for neither for write nor read. At this point by calling
-  Curl_multi_closed we are able to notify multi with CURL_POLL_REMOVE
-  before the fd is actually closed by ares.
+  Pass the socket created by curl to libssh using ssh_options_set() with
+  SSH_OPTIONS_FD directly after ssh_new(). So libssh uses our socket
+  instead of creating a new one.
   
-  In asyn-ares.c Curl_resolver_duphandle we can't use ares_dup anymore
-  since it does not allow passing a different sock_state_cb_data
+  This approach is very similar to what is done in the libssh2 code, where
+  the socket created by curl is passed to libssh2 when
+  libssh2_session_startup() is called.
   
-  Closes #3238
-
-- [Romain Fliedel brought this change]
+  Fixes #3491
+  Closes #3495
 
-  examples/ephiperfifo: report error when epoll_ctl fails
+- RELEASE-NOTES: synced
 
-Daniel Gustafsson (20 Nov 2018)
-- [pkubaj brought this change]
+- [Archangel_SDY brought this change]
 
-  ntlm: Remove redundant ifdef USE_OPENSSL
+  schannel: preserve original certificate path parameter
   
-  lib/curl_ntlm.c had code that read as follows:
+  Fixes #3480
+  Closes #3487
+
+- KNOWN_BUGS: tests not compatible with python3
   
-    #ifdef USE_OPENSSL
-    # ifdef USE_OPENSSL
-    # else
-    # ..
-    # endif
-    #endif
+  Closes #3289
+  [skip ci]
+
+Daniel Gustafsson (20 Jan 2019)
+- memcmp: avoid doing single char memcmp
   
-  Remove the redundant USE_OPENSSL along with #else (it's not possible to
-  reach it anyway). The removed construction is a leftover from when the
-  SSLeay support was removed.
+  There is no real gain in performing memcmp() comparisons on single
+  characters, so change these to array subscript inspections which
+  saves a call and makes the code clearer.
   
-  Closes #3269
-  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Closes #3486
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
 
-Daniel Stenberg (20 Nov 2018)
-- [Han Han brought this change]
-
-  ssl: replace all internal uses of CURLE_SSL_CACERT
+Daniel Stenberg (19 Jan 2019)
+- COPYING: it's 2019
   
-  Closes #3291
-
-Han Han (19 Nov 2018)
-- docs: add more description to unified ssl error codes
-
-- curle: move deprecated error code to ifndef block
-
-Patrick Monnerat (19 Nov 2018)
-- os400: add CURLOPT_CURLU to ILE/RPG binding.
-
-- os400: Add curl_easy_conn_upkeep() to ILE/RPG binding.
-
-- os400: fix return type of curl_easy_pause() in ILE/RPG binding.
+  [skip ci]
 
-Daniel Stenberg (19 Nov 2018)
-- RELEASE-NOTES: synced
+- [hhb brought this change]
 
-- impacket: add LICENSE
+  configure: fix recv/send/select detection on Android
   
-  The license for the impacket package was not in our tree.
+  This reverts commit d4f25201fb7da03fc88f90d51101beb3d0026db9.
   
-  Imported now from upstream's
-  https://github.com/SecureAuthCorp/impacket/blob/master/LICENSE
+  The overloadable attribute is removed again starting from
+  NDK17. Actually they only exist in two NDK versions (15 and 16). With
+  overloadable, the first condition tried will succeed. Results in wrong
+  detection result.
   
-  Reported-by: infinnovation-dev on github
-  Fixes #3276
-  Closes #3277
+  Closes #3484
 
-Daniel Gustafsson (18 Nov 2018)
-- tool_doswin: Fix uninitialized field warning
-  
-  The partial struct initialization in 397664a065abffb7c3445ca9 caused
-  a warning on uninitialized MODULEENTRY32 struct members:
+Marcel Raad (19 Jan 2019)
+- [Giorgos Oikonomou brought this change]
+
+  ntlm_sspi: add support for channel binding
   
-    /src/tool_doswin.c:681:3: warning: missing initializer for field
-    'th32ModuleID' of 'MODULEENTRY32 {aka struct tagMODULEENTRY32}'
-    [-Wmissing-field-initializers]
+  Windows extended potection (aka ssl channel binding) is required
+  to login to ntlm IIS endpoint, otherwise the server returns 401
+  responses.
   
-  This is sort of a bogus warning as the remaining members will be set
-  to zero by the compiler, as all omitted members are. Nevertheless,
-  remove the warning by omitting all members and setting the dwSize
-  members explicitly.
+  Fixes #3280
+  Closes #3321
+
+Daniel Stenberg (18 Jan 2019)
+- schannel: on connection close there might not be a transfer
   
-  Closes #3254
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
+  Reported-by: Marcel Raad
+  Fixes #3412
+  Closes #3483
 
-- openssl: Remove SSLEAY leftovers
+- [Joel Depooter brought this change]
+
+  ssh: log the libssh2 error message when ssh session startup fails
   
-  Commit 709cf76f6bb7dbac deprecated USE_SSLEAY, as curl since long isn't
-  compatible with the SSLeay library. This removes the few leftovers that
-  were omitted in the less frequently used platform targets.
+  When a ssh session startup fails, it is useful to know why it has
+  failed. This commit changes the message from:
+     "Failure establishing ssh session"
+  to something like this, for example:
+     "Failure establishing ssh session: -5, Unable to exchange encryption keys"
   
-  Closes #3270
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #3481
 
-Daniel Stenberg (16 Nov 2018)
-- [Elia Tufarolo brought this change]
+Alessandro Ghedini (16 Jan 2019)
+- Fix typo in manpage
+
+Daniel Stenberg (16 Jan 2019)
+- RELEASE-NOTES: synced
+
+Sergei Nikulov (16 Jan 2019)
+- cmake: updated check for HAVE_POLL_FINE to match autotools
+
+Daniel Stenberg (16 Jan 2019)
+- curl-compilers.m4: check for __ibmxl__ to detect xlclang
+  
+  Follow-up to 2fa0d57e2e3. The __xlc__ symbol is only defined there if a
+  particular flag is used for legacy macros.
+  
+  Fixes #3474
+  Closes #3479
 
-  http_negotiate: do not close connection until negotiation is completed
+- openssl: fix the SSL_get_tlsext_status_ocsp_resp call
   
-  Fix HTTP POST using CURLAUTH_NEGOTIATE.
+  .... to not pass in a const in the second argument as that's not how it
+  is supposed to be used and might cause compiler warnings.
   
-  Closes #3275
+  Reported-by: Pavel Pavlov
+  Fixes #3477
+  Closes #3478
 
-- pop3: only do APOP with a valid timestamp
+- curl-compilers.m4: detect xlclang
   
-  Brought-by: bobmitchell1956 on github
-  Fixes #3278
-  Closes #3279
+  Since it isn't totally clang compatible, we detect this IBM clang
+  front-end and if detected, avoids some clang specific magic.
+  
+  Reported-by: Kees Dekker
+  Fixes #3474
+  Closes #3476
 
-Jay Satiro (16 Nov 2018)
-- [Peter Wu brought this change]
+- README: add codacy code quality badge
+  
+  [skip ci]
 
-  openssl: do not log excess "TLS app data" lines for TLS 1.3
+- extract_if_dead: follow-up to 54b201b48c90a
   
-  The SSL_CTX_set_msg_callback callback is not just called for the
-  Handshake or Alert protocols, but also for the raw record header
-  (SSL3_RT_HEADER) and the decrypted inner record type
-  (SSL3_RT_INNER_CONTENT_TYPE). Be sure to ignore the latter to avoid
-  excess debug spam when using `curl -v` against a TLSv1.3-enabled server:
+  extract_if_dead() dead is called from two functions, and only one of
+  them should get conn->data updated and now neither call path clears it.
   
-      * TLSv1.3 (IN), TLS app data, [no content] (0):
+  scan-build found a case where conn->data would be NULL dereferenced in
+  ConnectionExists() otherwise.
   
-  (Following this message, another callback for the decrypted
-  handshake/alert messages will be be present anyway.)
+  Closes #3473
+
+- multi: remove "Dead assignment"
   
-  Closes https://github.com/curl/curl/pull/3281
+  Found by scan-build. Follow-up to 4c35574bb785ce.
+  
+  Closes #3471
 
-Marc Hoersken (15 Nov 2018)
-- tests: disable SO_EXCLUSIVEADDRUSE for stunnel on Windows
+- tests: move objnames-* from lib into tests
   
-  SO_EXCLUSIVEADDRUSE is on by default on Vista or newer,
-  but does not work together with SO_REUSEADDR being on.
+  Since they're used purely for testing purposes, I think they should
+  rather be stored there.
   
-  The default changes were made with stunnel 5.34 and 5.35.
+  Closes #3470
 
-Daniel Stenberg (13 Nov 2018)
-- [Kamil Dudka brought this change]
+Sergei Nikulov (15 Jan 2019)
+- travis: added cmake build for osx
 
-  nss: remove version selecting dead code
-  
-  Closes #3262
+Daniel Stenberg (14 Jan 2019)
+- [Frank Gevaerts brought this change]
 
-- nss: set default max-tls to 1.3/1.2
+  cookie: fix comment typo (url_path_len -> uri_path_len)
   
-  Fixes #3261
+  Closes #3469
 
-Daniel Gustafsson (13 Nov 2018)
-- tool_cb_wrt: Silence function cast compiler warning
-  
-  Commit 5bfaa86ceb3c2a9ac474a928e748c4a86a703b33 introduced a new
-  compiler warning on Windows cross compilation with GCC. See below
-  for an example of the warning from the autobuild logs (whitespace
-  edited to fit):
-  
-  /src/tool_cb_wrt.c:175:9: warning: cast from function call of type
-      'intptr_t {aka long long int}' to non-matching type 'void *'
-      [-Wbad-function-cast]
-  (HANDLE) _get_osfhandle(fileno(outs->stream)),
-  ^
+Marcel Raad (14 Jan 2019)
+- winbuild: conditionally use /DZLIB_WINAPI
   
-  Store the return value from _get_osfhandle() in an intermediate
-  variable and cast the variable in WriteConsoleW() rather than the
-  function call directly to avoid a compiler warning.
+  zlibwapi.lib (dynamic library) and zlibstat.lib (static library) have
+  the ZLIB_WINAPI define set by default. Using them requires that define
+  too.
   
-  In passing, also add inspection of the MultiByteToWideChar() return
-  value and return failure in case an error is reported.
+  Ref: https://zlib.net/DLL_FAQ.txt
   
-  Closes #3263
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-  Reviewed-by: Viktor Szakats <commit@vszakats.net>
-
-Daniel Stenberg (12 Nov 2018)
-- nss: fix fallthrough comment to fix picky compiler warning
-
-- docs: expanded on some CURLU details
+  Fixes https://github.com/curl/curl/issues/3133
+  Closes https://github.com/curl/curl/pull/3460
 
-- [Tim Rühsen brought this change]
+Daniel Stenberg (14 Jan 2019)
+- src/Makefile: make 'tidy' target work for metalink builds
 
-  ftp: avoid two unsigned int overflows in FTP listing parser
-  
-  Curl_ftp_parselist: avoid unsigned integer overflows
+- extract_if_dead: use a known working transfer when checking connections
   
-  The overflow has no real world impact, just avoid it for "best
-  practice".
+  Make sure that this function sets a proper "live" transfer for the
+  connection before calling the protocol-specific connection check
+  function, and then clear it again afterward as a non-used connection has
+  no current transfer.
   
-  Closes #3225
+  Reported-by: Jeroen Ooms
+  Reviewed-by: Marcel Raad
+  Reviewed-by: Daniel Gustafsson
+  Fixes #3463
+  Closes #3464
 
-- curl: --local-port range was not "including"
+- openssl: adapt to 3.0.0, OpenSSL_version_num() is deprecated
   
-  The end port number in a given range was not included in the range used,
-  as it is documented to be.
+  OpenSSL_version() replaces OpenSSL_version_num()
   
-  Reported-by: infinnovation-dev on github
-  Fixes #3251
-  Closes #3255
+  Closes #3462
 
-- [Jérémy Rocher brought this change]
+Sergei Nikulov (11 Jan 2019)
+- cmake: added checks for HAVE_VARIADIC_MACROS_C99 and HAVE_VARIADIC_MACROS_GCC
 
-  openssl: support BoringSSL TLS renegotiation
-  
-  As per BoringSSL porting documentation [1], BoringSSL rejects peer
-  renegotiations by default.
+Daniel Stenberg (11 Jan 2019)
+- urldata: rename easy_conn to just conn
   
-  curl fails when trying to authenticate to server through client
-  certificate if it is requested by server after the initial TLS
-  handshake.
+  We use "conn" everywhere to be a pointer to the connection.
   
-  Enable renegotiation by default with BoringSSL to get same behavior as
-  with OpenSSL. This is done by calling SSL_set_renegotiate_mode [2]
-  which was introduced in commit 1d5ef3bb1eb9 [3].
+  Introduces two functions that "attaches" and "detaches" the connection
+  to and from the transfer.
   
-  1 - https://boringssl.googlesource.com/boringssl/+/HEAD/PORTING.md#tls-renegotiation
-  2 - https://boringssl.googlesource.com/boringssl/+/master/include/openssl/ssl.h#3482
-  3 - https://boringssl.googlesource.com/boringssl/+/1d5ef3bb1eb97848617db5e7d633d735a401df86
+  Going forward, we should favour using "data->conn" (since a transfer
+  always only has a single connection or none at all) to "conn->data"
+  (since a connection can have none, one or many transfers associated with
+  it and updating conn->data to be correct is error prone and a frequent
+  reason for internal issues).
   
-  Signed-off-by: Jérémy Rocher <rocher.jeremy@gmail.com>
-  Fixes #3258
-  Closes #3259
+  Closes #3442
 
-- HISTORY: add some milestones
+- tool_cb_prg: avoid integer overflow
   
-  Added a few of the more notable milestones in curl history that were
-  missing. Primarily more recent ones but I also noted some older that
-  could be worth mentioning.
+  When calculating the progress bar width.
   
-  [ci skip]
-  Closes #3257
+  Reported-by: Peng Li
+  Fixes #3456
+  Closes #3458
 
-Daniel Gustafsson (9 Nov 2018)
-- KNOWN_BUGS: add --proxy-any connection issue
+Daniel Gustafsson (11 Jan 2019)
+- travis: turn off copyright year checks in checksrc
   
-  Add the identified issue with --proxy-any and proxy servers which
-  advertise authentication schemes other than the supported one.
+  Invoking the maintainer intended COPYRIGHTYEAR check for everyone
+  in the PR pipeline is too invasive, especially at the turn of the
+  year when many files get affected. Remove and leave it as a tool
+  for maintainers to verify patches before commits.
   
-  Closes #876
-  Closes #3250
-  Reported-by: NTMan on Github
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Daniel Stenberg (9 Nov 2018)
-- [Jim Fuller brought this change]
-
-  setopt: add CURLOPT_CURLU
+  This reverts f7bdf4b2e1d81b2652b81b9b3029927589273b41.
   
-  Allows an application to pass in a pre-parsed URL via a URL handle.
+  After discussion with: Daniel Stenberg
+
+Daniel Stenberg (10 Jan 2019)
+- KNOWN_BUGS: cmake makes unusable tool_hugehelp.c with MinGW
   
-  Closes #3227
+  Closes #3125
 
-- [Gisle Vanem brought this change]
+- KNOWN_BUGS: Improve --data-urlencode space encoding
+  
+  Closes #3229
 
-  docs: ESCape "\n" codes
+Patrick Monnerat (10 Jan 2019)
+- os400: add a missing closing bracket
   
-  Groff / Troff will display a:
-   printaf("Errno: %ld\n", error);
-  as:
-    printf("Errno: %ld0, error);
+  See https://github.com/curl/curl/issues/3453#issuecomment-453054458
   
-  when a "\n" is not escaped. Use "\\n" instead.
+  Reported-by: jonrumsey on github
+
+- os400: fix extra parameter syntax error.
   
-  Closes #3246
+  Reported-by: jonrumsey on github
+  Closes #3453
 
-- curl: --local-port fix followup
+Daniel Stenberg (10 Jan 2019)
+- test1558: verify CURLINFO_PROTOCOL on file:// transfer
   
-  Regression by 52db54869e6.
+  Attempt to reproduce issue #3444.
   
-  Reported-by: infinnovation-dev on github
-  Fixes #3248
-  Closes #3249
-
-GitHub (7 Nov 2018)
-- [Gisle Vanem brought this change]
-
-  More "\n" ESCaping
+  Closes #3447
 
-Daniel Stenberg (7 Nov 2018)
 - RELEASE-NOTES: synced
 
-- curl: fix --local-port integer overflow
+- xattr: strip credentials from any URL that is stored
   
-  The tool's local port command line range parser didn't check for integer
-  overflows and could pass "weird" data to libcurl for this option.
-  libcurl however, has a strict range check for the values so it rejects
-  anything outside of the accepted range.
+  Both user and password are cleared uncondtitionally.
   
-  Reported-by: Brian Carpenter
-  Closes #3242
+  Added unit test 1621 to verify.
+  
+  Fixes #3423
+  Closes #3433
 
-- curl: correct the switch() logic in ourWriteOut
+- cookies: allow secure override when done over HTTPS
   
-  Follow-up to e431daf013, as I did the wrong correction for a compiler
-  warning. It should be a break and not a fall-through.
+  Added test 1562 to verify.
   
-  Pointed-out-by: Frank Gevaerts
-
-- [Frank Gevaerts brought this change]
+  Reported-by: Jeroen Ooms
+  Fixes #3445
+  Closes #3450
 
-  curl: add %{stderr} and %{stdout} for --write-out
+- multi: multiplexing improvements
   
-  Closes #3115
-
-Daniel Gustafsson (7 Nov 2018)
-- winssl: be consistent in Schannel capitalization
+  Fixes #3436
+  Closes #3448
   
-  The productname from Microsoft is "Schannel", but in infof/failf
-  reporting we use "schannel". This removes different versions.
+   Problem 1
   
-  Closes #3243
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Daniel Stenberg (7 Nov 2018)
-- TODO: Have the URL API offer IDN decoding
+  After LOTS of scratching my head, I eventually realized that even when doing
+  10 uploads in parallel, sometimes the socket callback to the application that
+  tells it what to wait for on the socket, looked like it would reflect the
+  status of just the single transfer that just changed state.
   
-  Similar to how URL decoding/encoding is done, we could have URL
-  functions to convert IDN host names to punycode.
+  Digging into the code revealed that this was indeed the truth. When multiple
+  transfers are using the same connection, the application did not correctly get
+  the *combined* flags for all transfers which then could make it switch to READ
+  (only) when in fact most transfers wanted to get told when the socket was
+  WRITEABLE.
   
-  Suggested-by: Alexey Melnichuk
-  Closes #3232
-
-- urlapi: only skip encoding the first '=' with APPENDQUERY set
+   Problem 1b
   
-  APPENDQUERY + URLENCODE would skip all equals signs but now it only skip
-  encoding the first to better allow "name=content" for any content.
+  A separate but related regression had also been introduced by me when I
+  cleared connection/transfer association better a while ago, as now the logic
+  couldn't find the connection and see if that was marked as used by more
+  transfers and then it would also prematurely remove the socket from the socket
+  hash table even in times other transfers were still using it!
   
-  Reported-by: Alexey Melnichuk
-  Fixes #3231
-  Closes #3231
-
-- url: a short host name + port is not a scheme
+   Fix 1
   
-  The function identifying a leading "scheme" part of the URL considered a
-  few letters ending with a colon to be a scheme, making something like
-  "short:80" to become an unknown scheme instead of a short host name and
-  a port number.
+  Make sure that each socket stored in the socket hash has a "combined" action
+  field of what to ask the application to wait for, that is potentially the ORed
+  action of multiple parallel transfers. And remove that socket hash entry only
+  if there are no transfers left using it.
   
-  Extended test 1560 to verify.
+   Problem 2
   
-  Also fixed test203 to use file_pwd to make it get the correct path on
-  windows. Removed test 2070 since it was a duplicate of 203.
+  The socket hash entry stored an association to a single transfer using that
+  socket - and when curl_multi_socket_action() was called to tell libcurl about
+  activities on that specific socket only that transfer was "handled".
   
-  Assisted-by: Marcel Raad
-  Reported-by: Hagai Auro
-  Fixes #3220
-  Fixes #3233
-  Closes #3223
-  Closes #3235
-
-- [Sangamkar brought this change]
-
-  libcurl: stop reading from paused transfers
+  This was WRONG, as a single socket/connection can be used by numerous parallel
+  transfers and not necessarily a single one.
   
-  In the transfer loop it would previously not acknwledge the pause bit
-  and continue until drained or loop ended.
+   Fix 2
   
-  Closes #3240
+  We now store a list of handles in the socket hashtable entry and when libcurl
+  is told there's traffic for a particular socket, it now iterates over all
+  known transfers using that single socket.
 
-Jay Satiro (6 Nov 2018)
-- tool: add undocumented option --dump-module-paths for win32
-  
-  - Add an undocumented diagnostic option for Windows to show the full
-    paths of all loaded modules regardless of whether or not libcurl
-    initialization succeeds.
+- test1561: improve test name
   
-  This is needed so that in the CI we can get a list of all DLL
-  dependencies after initialization (when they're most likely to have
-  finished loading) and then package them as artifacts so that a
-  functioning build can be downloaded. Also I imagine it may have some use
-  as a diagnostic for help requests.
+  [skip ci]
+
+- [Katsuhiko YOSHIDA brought this change]
+
+  cookies: skip custom cookies when redirecting cross-site
   
-  Ref: https://github.com/curl/curl/pull/3103
+  Closes #3417
+
+- THANKS: fixups and a dedupe
   
-  Closes https://github.com/curl/curl/pull/3208
+  [skip ci]
 
-- curl_multibyte: fix a malloc overcalculation
+- timediff: fix math for unsigned time_t
   
-  Prior to this change twice as many bytes as necessary were malloc'd when
-  converting wchar to UTF8. To allay confusion in the future I also
-  changed the variable name for the amount of bytes from len to bytes.
+  Bug: https://curl.haxx.se/mail/lib-2018-12/0088.html
   
-  Closes https://github.com/curl/curl/pull/3209
+  Closes #3449
+
+- [Bernhard M. Wiedemann brought this change]
 
-Michael Kaufmann (5 Nov 2018)
-- netrc: don't ignore the login name specified with "--user"
+  tests: allow tests to pass by 2037-02-12
   
-  - for "--netrc", don't ignore the login/password specified with "--user",
-    only ignore the login/password in the URL.
-    This restores the netrc behaviour of curl 7.61.1 and earlier.
-  - fix the documentation of CURL_NETRC_REQUIRED
-  - improve the detection of login/password changes when reading .netrc
-  - don't read .netrc if both login and password are already set
+  similar to commit f508d29f3902104018
   
-  Fixes #3213
-  Closes #3224
+  Closes #3443
 
-Patrick Monnerat (5 Nov 2018)
-- OS400: add URL API ccsid wrappers and sync ILE/RPG bindings
+- RELEASE-NOTES: synced
 
-Daniel Stenberg (5 Nov 2018)
-- [Yasuhiro Matsumoto brought this change]
+- [Brad Spencer brought this change]
 
-  curl: fixed UTF-8 in current console code page (Windows)
+  curl_multi_remove_handle() don't block terminating c-ares requests
   
-  Fixes #3211
-  Fixes #3175
-  Closes #3212
-
-- TODO: 2.6 multi upkeep
+  Added Curl_resolver_kill() for all three resolver modes, which only
+  blocks when necessary, along with test 1592 to confirm
+  curl_multi_remove_handle() doesn't block unless it must.
   
-  Closes #3199
+  Closes #3428
+  Fixes #3371
 
-Daniel Gustafsson (5 Nov 2018)
-- unittest: make 1652 stable across collations
+- Revert "http_negotiate: do not close connection until negotiation is completed"
   
-  The previous coding used a format string whose output depended on the
-  current locale of the environment running the test. Since the gist of
-  the test is to have a format string, with the actual formatting being
-  less important, switch to a more stable formatstring with decimals.
+  This reverts commit 07ebaf837843124ee670e5b8c218b80b92e06e47.
   
-  Reported-by: Marcel Raad
-  Closes #3234
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  This also reopens PR #3275 which brought the change now reverted.
+  
+  Fixes #3384
+  Closes #3439
 
-Daniel Stenberg (5 Nov 2018)
-- Revert "url: a short host name + port is not a scheme"
+- curl/urlapi.h: include "curl.h" first
   
-  This reverts commit 226cfa8264cd979eff3fd52c0f3585ef095e7cf2.
+  This allows programs to include curl/urlapi.h directly.
   
-  This commit caused test failures on appveyor/windows. Work on fixing them is
-  in #3235.
+  Reviewed-by: Daniel Gustafsson
+  Reported-by: Ben Kohler
+  Fixes #3438
+  Closes #3441
 
-- symbols-in-versions: add missing CURLU_ symbols
+Marcel Raad (6 Jan 2019)
+- VS projects: fix build warning
   
-  ...and fix symbol-scan.pl to also scan urlapi.h
+  Starting with Visual Studio 2017 Update 9, Visual Studio doesn't like
+  the MinimalRebuild option anymore and warns:
   
-  Reported-by: Alexey Melnichuk
-  Fixes #3226
-  Closes #3230
-
-Daniel Gustafsson (3 Nov 2018)
-- infof: clearly indicate truncation
+  cl : Command line warning D9035: option 'Gm' has been deprecated and
+  will be removed in a future release
   
-  The internal buffer in infof() is limited to 2048 bytes of payload plus
-  an additional byte for NULL termination. Servers with very long error
-  messages can however cause truncation of the string, which currently
-  isn't very clear, and leads to badly formatted output.
+  The option can be safely removed so that the default is used.
   
-  This appends a "...\n" (or just "..." in case the format didn't with a
-  newline char) marker to the end of the string to clearly show
-  that it has been truncated.
+  Closes https://github.com/curl/curl/pull/3425
+
+- schannel: fix compiler warning
   
-  Also include a unittest covering infof() to try and catch any bugs
-  introduced in this quite important function.
+  When building with Unicode on MSVC, the compiler warns about freeing a
+  pointer to const in Curl_unicodefree. Fix this by declaring it as
+  non-const and casting the argument to Curl_convert_UTF8_to_tchar to
+  non-const too, like we do in all other places.
   
-  Closes #3216
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  Closes https://github.com/curl/curl/pull/3435
+
+Daniel Stenberg (4 Jan 2019)
+- [Rikard Falkeborn brought this change]
 
-Michael Kaufmann (3 Nov 2018)
-- tool_getparam: fix some comments
+  printf: introduce CURL_FORMAT_TIMEDIFF_T
+
+- [Rikard Falkeborn brought this change]
 
-Daniel Stenberg (3 Nov 2018)
-- url: a short host name + port is not a scheme
+  printf: fix format specifiers
   
-  The function identifying a leading "scheme" part of the URL considered a few
-  letters ending with a colon to be a scheme, making something like "short:80"
-  to become an unknown scheme instead of a short host name and a port number.
+  Closes #3426
+
+- libtest/stub_gssapi: use "real" snprintf
   
-  Extended test 1560 to verify.
+  ... since it doesn't link with libcurl.
   
-  Reported-by: Hagai Auro
-  Fixes #3220
-  Closes #3223
-
-- URL: fix IPv6 numeral address parser
+  Reverts the commit dcd6f81025 changes from this file.
   
-  Regression from 46e164069d1a52. Extended test 1560 to verify.
+  Bug: https://curl.haxx.se/mail/lib-2019-01/0000.html
+  Reported-by: Shlomi Fish
+  Reviewed-by: Daniel Gustafsson
+  Reviewed-by: Kamil Dudka
   
-  Reported-by: tpaukrt on github
-  Fixes #3218
-  Closes #3219
+  Closes #3434
 
-- travis: remove curl before a normal build
+- INTERNALS: correct some outdated function names
   
-  on Linux. To make sure the test suite runs with its newly build tool and
-  doesn't require an external one present.
+  Closes #3431
+
+- docs/version.d: mention MultiSSL
   
-  Bug: #3198
-  Closes #3200
+  Reviewed-by: Daniel Gustafsson
+  Closes #3432
 
-- [Tim Rühsen brought this change]
+Daniel Gustafsson (2 Jan 2019)
+- [Rikard Falkeborn brought this change]
 
-  mprintf: avoid unsigned integer overflow warning
+  examples: Update .gitignore
   
-  The overflow has no real world impact.
-  Just avoid it for "best practice".
+  Add a few missing examples to make `make examples` not leave the
+  workspace in a dirty state.
   
-  Code change suggested by "The Infinnovation Team" and Daniel Stenberg.
-  Closes #3184
+  Closes #3427
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-- Curl_follow: accept non-supported schemes for "fake" redirects
-  
-  When not actually following the redirect and the target URL is only
-  stored for later retrieval, curl always accepted "non-supported"
-  schemes. This was a regression from 46e164069d1a5230.
+- THANKS: add more missing names
   
-  Reported-by: Brad King
-  Fixes #3210
-  Closes #3215
+  Add Adrian Burcea who made the artwork for the curl://up 2018 event
+  which was held in Stockholm, Sweden.
 
-Daniel Gustafsson (2 Nov 2018)
-- openvms: fix example name
+- docs: mention potential leak in curl_slist_append
   
-  Commit efc696a2e09225bfeab4 renamed persistant.c to persistent.c to
-  fix the typo in the name, but missed to update the OpenVMS package
-  files which still looked for the old name.
+  When a non-empty list is appended to, and used as the returnvalue,
+  the list pointer can leak in case of an allocation failure in the
+  curl_slist_append() call. This is correctly handled in curl code
+  usage but we weren't explicitly pointing it out in the API call
+  documentation. Fix by extending the RETURNVALUE manpage section
+  and example code.
   
-  Closes #3217
+  Closes #3424
+  Reported-by: dnivras on github
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Viktor Szakats <commit@vszakats.net>
 
-Daniel Stenberg (1 Nov 2018)
-- configure: show CFLAGS, LDFLAGS etc in summary
-  
-  To make it easier to understand other people's and remote builds etc.
+Marcel Raad (1 Jan 2019)
+- tvnow: silence conversion warnings
   
-  Closes #3207
-
-- version: bump for next cycle
+  MinGW-w64 defaults to targeting Windows 7 now, so GetTickCount64 is
+  used and the milliseconds are represented as unsigned long long,
+  leading to a compiler warning when implicitly converting them to long.
 
-- axtls: removed
-  
-  As has been outlined in the DEPRECATE.md document, the axTLS code has
-  been disabled for 6 months and is hereby removed.
-  
-  Use a better supported TLS library!
+Daniel Stenberg (1 Jan 2019)
+- THANKS: dedupe more names
   
-  Assisted-by: Daniel Gustafsson
-  Closes #3194
+  Researched-by: Tae Wong
 
-- [marcosdiazr brought this change]
+Marcel Raad (1 Jan 2019)
+- [Markus Moeller brought this change]
 
-  schannel: make CURLOPT_CERTINFO support using Issuer chain
+  ntlm: update selection of type 3 response
   
-  Closes #3197
-
-- travis: build with sanitize=address,undefined,signed-integer-overflow
+  NTLM2 did not work i.e. no NTLMv2 response was created. Changing the
+  check seems to work.
   
-  ... using clang
+  Ref: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-NLMP/[MS-NLMP].pdf
   
-  Closes #3190
+  Fixes https://github.com/curl/curl/issues/3286
+  Closes https://github.com/curl/curl/pull/3287
+  Closes https://github.com/curl/curl/pull/3415
 
-- schannel: use Curl_ prefix for global private symbols
-  
-  Curl_verify_certificate() must use the Curl_ prefix since it is globally
-  available in the lib and otherwise steps outside of our namespace!
+Daniel Stenberg (31 Dec 2018)
+- THANKS: added missing names from year <= 2000
   
-  Closes #3201
+  Due to a report of a missing name in THANKS I manually went through an
+  old CHANGES.0 file and added many previously missing names here.
 
-Kamil Dudka (1 Nov 2018)
-- tests: drop http_pipe.py script no longer used
-  
-  It is unused since commit f7208df7d9d5cd5e15e2d89237e828f32b63f135.
+Daniel Gustafsson (30 Dec 2018)
+- urlapi: fix parsing ipv6 with zone index
   
-  Closes #3204
-
-Daniel Stenberg (31 Oct 2018)
-- runtests: use the local curl for verifying
+  The previous fix for parsing IPv6 URLs with a zone index was a paddle
+  short for URLs without an explicit port. This patch fixes that case
+  and adds a unit test case.
   
-  ... revert the mistaken change brought in commit 8440616f53.
+  This bug was highlighted by issue #3408, and while it's not the full
+  fix for the problem there it is an isolated bug that should be fixed
+  regardless.
   
-  Reported-by: Alessandro Ghedini
-  Bug: https://curl.haxx.se/mail/lib-2018-10/0118.html
+  Closes #3411
+  Reported-by: GitYuanQu on github
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+
+Daniel Stenberg (30 Dec 2018)
+- THANKS: dedupe Guenter Knauf
   
-  Closes #3198
+  Reported-by: Tae Wong
 
-Version 7.62.0 (30 Oct 2018)
+- THANKS: missing name from the 6.3.1 release!
 
-Daniel Stenberg (30 Oct 2018)
-- RELEASE-NOTES: 7.62.0
+Daniel Gustafsson (27 Dec 2018)
+- RELEASE-NOTES: synced
 
-- THANKS: 7.62.0 status
+- [Claes Jakobsson brought this change]
 
-Daniel Gustafsson (30 Oct 2018)
-- vtls: add MesaLink to curl_sslbackend enum
+  hostip: support wildcard hosts
+  
+  This adds support for wildcard hosts in CURLOPT_RESOLVE. These are
+  try-last so any non-wildcard entry is resolved first. If specified,
+  any host not matched by another CURLOPT_RESOLVE config will use this
+  as fallback.
+  
+  Example send a.com to 10.0.0.1 and everything else to 10.0.0.2:
+    curl --resolve *:443:10.0.0.2 --resolve a.com:443:10.0.0.1 \
+         https://a.com https://b.com
   
-  MesaLink support was added in commit 57348eb97d1b8fc3742e02c but the
-  backend was never added to the curl_sslbackend enum in curl/curl.h.
-  This adds the new backend to the enum and updates the relevant docs.
+  This is probably quite similar to using:
+    --connect-to a.com:443:10.0.0.1:443 --connect-to :443:10.0.0.2:443
   
-  Closes #3195
+  Closes #3406
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Daniel Stenberg (30 Oct 2018)
-- [Ruslan Baratov brought this change]
+- url: fix incorrect indentation
 
-  cmake: Remove unused CURL_CONFIG_HAS_BEEN_RUN_BEFORE variable
+Patrick Monnerat (26 Dec 2018)
+- os400: upgrade ILE/RPG binding.
   
-  Closes #3191
-
-- test2080: verify the fix for CVE-2018-16842
+  - Trailer function support.
+  - http 0.9 option.
+  - curl_easy_upkeep.
 
-- voutf: fix bad arethmetic when outputting warnings to stderr
+Daniel Gustafsson (25 Dec 2018)
+- FAQ: remove mention of sourceforge for github
   
-  CVE-2018-16842
-  Reported-by: Brian Carpenter
-  Bug: https://curl.haxx.se/docs/CVE-2018-16842.html
-
-- [Tuomo Rinne brought this change]
-
-  cmake: uniform ZLIB to use USE_ variable and clean curl-config.cmake.in
+  The project bug tracker is no longer hosted at sourceforge but is now
+  hosted on the curl Github page. Update the FAQ to reflect.
   
-  Closes #3123
-
-- [Tuomo Rinne brought this change]
-
-  cmake: add find_dependency call for ZLIB to CMake config file
-
-- [Tuomo Rinne brought this change]
+  Closes #3410
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-  cmake: add support for transitive ZLIB target
+- openvms: fix typos in documentation
 
-- unit1650: fix "null pointer passed as argument 1 to memcmp"
+- openvms: fix OpenSSL discovery on VAX
   
-  Detected by UndefinedBehaviorSanitizer
+  The DCL code had a typo in one of the commands which would make the
+  OpenSSL discovery on VAX fail. The correct syntax is F$ENVIRONMENT.
   
-  Closes #3187
+  Closes #3407
+  Reviewed-by: Viktor Szakats <commit@vszakats.net>
 
-- travis: add a "make tidy" build that runs clang-tidy
-  
-  Closes #3182
+Daniel Stenberg (24 Dec 2018)
+- [Ruslan Baratov brought this change]
 
-- unit1300: fix stack-use-after-scope AddressSanitizer warning
+  cmake: use lowercase for function name like the rest of the code
+  
+  Reviewed-by: Sergei Nikulov
   
-  Closes #3186
+  closes #3196
 
-- Curl_auth_create_plain_message: fix too-large-input-check
+- Revert "libssh: no data pointer == nothing to do"
   
-  CVE-2018-16839
-  Reported-by: Harry Sintonen
-  Bug: https://curl.haxx.se/docs/CVE-2018-16839.html
+  This reverts commit c98ee5f67f497195c9 since commit f3ce38739fa fixed the
+  problem in a more generic way.
 
-- Curl_close: clear data->multi_easy on free to avoid use-after-free
+- disconnect: set conn->data for protocol disconnect
   
-  Regression from b46cfbc068 (7.59.0)
-  CVE-2018-16840
-  Reported-by: Brian Carpenter (Geeknik Labs)
+  Follow-up to fb445a1e18d: Set conn->data explicitly to point out the
+  current transfer when invoking the protocol-specific disconnect function
+  so that it can work correctly.
   
-  Bug: https://curl.haxx.se/docs/CVE-2018-16840.html
+  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12173
 
-- [randomswdev brought this change]
+Jay Satiro (23 Dec 2018)
+- [Pavel Pavlov brought this change]
 
-  system.h: use proper setting with Sun C++ as well
+  timeval: Use high resolution timestamps on Windows
   
-  system.h selects the proper Sun settings when __SUNPRO_C is defined. The
-  Sun compiler does not define it when compiling C++ files.  I'm adding a
-  check also on __SUNPRO_CC to allow curl to work properly also when used
-  in a C++ project on Sun Solaris.
+  - Use QueryPerformanceCounter on Windows Vista+
   
-  Closes #3181
-
-- rand: add comment to skip a clang-tidy false positive
-
-- test1651: unit test Curl_extract_certinfo()
+  There is confusing info floating around that QueryPerformanceCounter
+  can leap etc, which might have been true long time ago, but no longer
+  the case nowadays (perhaps starting from WinXP?). Also, boost and
+  std::chrono::steady_clock use QueryPerformanceCounter in a similar way.
+  
+  Prior to this change GetTickCount or GetTickCount64 was used, which has
+  lower resolution. That is still the case for <= XP.
   
-  The version used for Gskit, NSS, GnuTLS, WolfSSL and schannel.
+  Fixes https://github.com/curl/curl/issues/3309
+  Closes https://github.com/curl/curl/pull/3318
 
-- x509asn1: always check return code from getASN1Element()
+Daniel Stenberg (22 Dec 2018)
+- libssh: no data pointer == nothing to do
 
-- Makefile: add 'tidy' target that runs clang-tidy
-  
-  Available in the root, src and lib dirs.
-  
-  Closes #3163
+- conncache_unlock: avoid indirection by changing input argument type
 
-- RELEASE-PROCEDURE: adjust the release dates
+- disconnect: separate connections and easy handles better
   
-  See: https://curl.haxx.se/mail/lib-2018-10/0107.html
-
-Patrick Monnerat (27 Oct 2018)
-- x509asn1: suppress left shift on signed value
+  Do not assume/store assocation between a given easy handle and the
+  connection if it can be avoided.
   
-  Use an unsigned variable: as the signed operation behavior is undefined,
-  this change silents clang-tidy about it.
+  Long-term, the 'conn->data' pointer should probably be removed as it is a
+  little too error-prone. Still used very widely though.
   
-  Ref: https://github.com/curl/curl/pull/3163
-  Reported-By: Daniel Stenberg
+  Reported-by: masbug on github
+  Fixes #3391
+  Closes #3400
 
-Michael Kaufmann (27 Oct 2018)
-- multi: Fix error handling in the SENDPROTOCONNECT state
+- libssh: free sftp_canonicalize_path() data correctly
   
-  If Curl_protocol_connect() returns an error code,
-  handle the error instead of switching to the next state.
+  Assisted-by: Harry Sintonen
   
-  Closes #3170
+  Fixes #3402
+  Closes #3403
 
-Daniel Stenberg (27 Oct 2018)
 - RELEASE-NOTES: synced
 
-- openssl: output the correct cipher list on TLS 1.3 error
-  
-  When failing to set the 1.3 cipher suite, the wrong string pointer would
-  be used in the error message. Most often saying "(nil)".
+- http: added options for allowing HTTP/0.9 responses
   
-  Reported-by: Ricky-Tigg on github
-  Fixes #3178
-  Closes #3180
-
-- docs/CIPHERS: fix the TLS 1.3 cipher names
+  Added CURLOPT_HTTP09_ALLOWED and --http0.9 for this purpose.
   
-  ... picked straight from the OpenSSL man page:
-  https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html
+  For now, both the tool and library allow HTTP/0.9 by default.
+  docs/DEPRECATE.md lays out the plan for when to reverse that default: 6
+  months after the 7.64.0 release. The options are added already now so
+  that applications/scripts can start using them already now.
   
-  Reported-by: Ricky-Tigg on github
-  Bug: #3178
+  Fixes #2873
+  Closes #3383
 
-Marcel Raad (27 Oct 2018)
-- travis: install gnutls-bin package
-  
-  This is required for gnutls-serv, which enables a few more tests.
+- if2ip: remove unused function Curl_if_is_interface_name
   
-  Closes https://github.com/curl/curl/pull/2958
+  Closes #3401
 
-Daniel Gustafsson (26 Oct 2018)
-- ssh: free the session on init failures
-  
-  Ensure to clear the session object in case the libssh2 initialization
-  fails.
-  
-  It could be argued that the libssh2 error function should be called to
-  get a proper error message in this case. But since the only error path
-  in libssh2_knownhost_init() is memory a allocation failure it's safest
-  to avoid since the libssh2 error handling allocates memory.
+- http2: clear pause stream id if it gets closed
   
-  Closes #3179
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Daniel Stenberg (26 Oct 2018)
-- docs/RELEASE-PROCEDURE: remove old entries, modify the Dec 2018 date
+  Reported-by: Florian Pritz
   
-  ... I'm moving it up one week due to travels. The rest stays.
+  Fixes #3392
+  Closes #3399
 
-- [Daniel Gustafsson brought this change]
+Daniel Gustafsson (20 Dec 2018)
+- [David Garske brought this change]
 
-  openssl: make 'done' a proper boolean
+  wolfssl: Perform cleanup
+  
+  This adds a cleanup callback for cyassl. Resolves possible memory leak
+  when using ECC fixed point cache.
   
-  Closes #3176
+  Closes #3395
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
 
-- gtls: Values stored to but never read
+Daniel Stenberg (20 Dec 2018)
+- mbedtls: follow-up VERIFYHOST fix from f097669248
   
-  Detected by clang-tidy
+  Fix-by: Eric Rosenquist
   
-  Closes #3176
-
-- [Alexey Eremikhin brought this change]
+  Fixes #3376
+  Closes #3390
 
-  curl.1: --ipv6 mutexes ipv4 (fixed typo)
-  
-  Fixes #3171
-  Closes #3172
+- curlver: bump to 7.64.0 for next release
 
-- tool_main: make TerminalSettings static
+Daniel Gustafsson (19 Dec 2018)
+- cookies: extend domain checks to non psl builds
   
-  Reported-by: Gisle Vanem
-  Bug: https://github.com/curl/curl/commit/becfe1233ff2b6b0c3e1b6a10048b55b68c2539f#commitcomment-31008819
-  Closes #3161
-
-- curl-config.in: remove dependency on bc
+  Ensure to perform the checks we have to enforce a sane domain in
+  the cookie request. The check for non-PSL enabled builds is quite
+  basic but it's better than nothing.
   
-  Reported-by: Dima Pasechnik
-  Fixes #3143
-  Closes #3174
-
-- [Gisle Vanem brought this change]
+  Closes #2964
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-  rtmp: fix for compiling with lwIP
-  
-  Compiling on _WIN32 and with USE_LWIPSOCK, causes this error:
-    curl_rtmp.c(223,3):  error: use of undeclared identifier 'setsockopt'
-      setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
-      ^
-    curl_rtmp.c(41,32):  note: expanded from macro 'setsockopt'
-    #define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
-                                   ^
-  Closes #3155
+Daniel Stenberg (19 Dec 2018)
+- [Matus Uzak brought this change]
 
-- configure: remove CURL_CONFIGURE_CURL_SOCKLEN_T
+  smb: fix incorrect path in request if connection reused
   
-  Follow-up to #3166 which did the cmake part of this. This type/define is
-  not used.
+  Follow-up to 09e401e01bf9.  If connection gets reused, then data member
+  will be copied, but not the proto member.  As a result, in smb_do(),
+  path has been set from the original proto.share data.
   
-  Closes #3168
+  Closes #3388
 
-- [Ruslan Baratov brought this change]
+- curl -J: do not append to the destination file
+  
+  Reported-by: Kamil Dudka
+  Fixes #3380
+  Closes #3381
 
-  cmake: remove unused variables
+- mbedtls: use VERIFYHOST
   
-  Remove variables:
-  * HAVE_SOCKLEN_T
-  * CURL_SIZEOF_CURL_SOCKLEN_T
-  * CURL_TYPEOF_CURL_SOCKLEN_T
+  Previously, VERIFYPEER would enable/disable all checks.
   
-  Closes #3166
+  Reported-by: Eric Rosenquist
+  Fixes #3376
+  Closes #3380
 
-Michael Kaufmann (25 Oct 2018)
-- urldata: Fix comment in header
+- pingpong: change default response timeout to 120 seconds
   
-  The "connecting" function is used by multiple protocols, not only FTP
+  Previously it was 30 minutes
 
-- netrc: free temporary strings if memory allocation fails
+- pingpong: ignore regular timeout in disconnect phase
   
-  - Change the inout parameters after all needed memory has been
-    allocated. Do not change them if something goes wrong.
-  - Free the allocated temporary strings if strdup() fails.
+  The timeout set with CURLOPT_TIMEOUT is no longer used when
+  disconnecting from one of the pingpong protocols (FTP, IMAP, SMTP,
+  POP3).
   
-  Closes #3122
-
-Daniel Stenberg (24 Oct 2018)
-- [Ruslan Baratov brought this change]
+  Reported-by: jasal82 on github
+  
+  Fixes #3264
+  Closes #3374
 
-  config: Remove unused SIZEOF_VOIDP
+- TODO: Windows: set attribute 'archive' for completed downloads
   
-  Closes #3162
+  Closes #3354
 
 - RELEASE-NOTES: synced
 
-GitHub (23 Oct 2018)
-- [Gisle Vanem brought this change]
+- http: minor whitespace cleanup from f464535b
 
-  Fix for compiling with lwIP (3)
-  
-  lwIP on Windows does not have a WSAIoctl() function.
-  But it do have a SO_SNDBUF option to lwip_setsockopt(). But it currently does nothing.
+- [Ayoub Boudhar brought this change]
 
-Daniel Stenberg (23 Oct 2018)
-- Curl_follow: return better errors on URL problems
+  http: Implement trailing headers for chunked transfers
   
-  ... by making the converter function global and accessible.
+  This adds the CURLOPT_TRAILERDATA and CURLOPT_TRAILERFUNCTION
+  options that allow a callback based approach to sending trailing headers
+  with chunked transfers.
   
-  Closes #3153
-
-- Curl_follow: remove remaining free(newurl)
+  The test server (sws) was updated to take into account the detection of the
+  end of transfer in the case of trailing headers presence.
   
-  Follow-up to 05564e750e8f0c. This function no longer frees the passed-in
-  URL.
+  Test 1591 checks that trailing headers can be sent using libcurl.
   
-  Reported-by: Michael Kaufmann
-  Bug: https://github.com/curl/curl/commit/05564e750e8f0c79016c680f301ce251e6e86155#commitcomm
-  ent-30985666
+  Closes #3350
 
-Daniel Gustafsson (23 Oct 2018)
-- headers: end all headers with guard comment
-  
-  Most headerfiles end with a /* <headerguard> */ comment, but it was
-  missing from some. The comment isn't the most important part of our
-  code documentation but consistency has an intrinsic value in itself.
-  This adds header guard comments to the files that were lacking it.
+- darwinssl: accept setting max-tls with default min-tls
   
-  Closes #3158
-  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: Andrei Neculau
+  Fixes #3367
+  Closes #3373
 
-Jay Satiro (23 Oct 2018)
-- CIPHERS.md: Mention the options used to set TLS 1.3 ciphers
-  
-  Closes https://github.com/curl/curl/pull/3159
+- gopher: fix memory leak from 9026083ddb2a9
 
-Daniel Stenberg (20 Oct 2018)
-- docs/BUG-BOUNTY: the sponsors actually decide the amount
-  
-  Retract the previous approach as the sponsors will be the ones to set the
-  final amounts.
-  
-  Closes #3152
-  [ci skip]
+- [Leonardo Taccari brought this change]
 
-- multi: avoid double-free
-  
-  Curl_follow() no longer frees the string. Make sure it happens in the
-  caller function, like we normally handle allocations.
+  test1201: Add a trailing `?' to the selector
   
-  This bug was introduced with the use of the URL API internally, it has
-  never been in a release version
+  This verify that the `?' in the selector is kept as is.
   
-  Reported-by: Dario Weißer
-  Closes #3149
+  Verifies the fix in #3370
 
-- multi: make the closure handle "inherit" CURLOPT_NOSIGNAL
-  
-  Otherwise, closing that handle can still cause surprises!
-  
-  Reported-by: Martin Ankerl
-  Fixes #3138
-  Closes #3147
+- [Leonardo Taccari brought this change]
 
-Marcel Raad (19 Oct 2018)
-- VS projects: add USE_IPV6
+  gopher: always include the entire gopher-path in request
+  
+  After the migration to URL API all octets in the selector after the
+  first `?' were interpreted as query and accidentally discarded and not
+  passed to the server.
   
-  The Visual Studio builds didn't use IPv6. Add it to all projects since
-  Visual Studio 2008, which is verified to build via AppVeyor.
+  Add a gopherpath to always concatenate possible path and query URL
+  pieces.
   
-  Closes https://github.com/curl/curl/pull/3137
+  Fixes #3369
+  Closes #3370
+
+- [Leonardo Taccari brought this change]
 
-- config_win32: enable LDAPS
+  urlapi: distinguish possibly empty query
   
-  As done in the autotools and CMake builds by default.
+  If just a `?' to indicate the query is passed always store a zero length
+  query instead of having a NULL query.
   
-  Closes https://github.com/curl/curl/pull/3137
-
-Daniel Stenberg (18 Oct 2018)
-- travis: add build for "configure --disable-verbose"
+  This permits to distinguish URL with trailing `?'.
   
-  Closes #3144
+  Fixes #3369
+  Closes #3370
 
-Kamil Dudka (17 Oct 2018)
-- tool_cb_hdr: handle failure of rename()
+Daniel Gustafsson (13 Dec 2018)
+- OS400: handle memory error in list conversion
   
-  Detected by Coverity.
+  Curl_slist_append_nodup() returns NULL when it fails to create a new
+  item for the specified list, and since the coding here reassigned the
+  new list on top of the old list it would result in a dangling pointer
+  and lost memory. Also, in case we hit an allocation failure at some
+  point during the conversion, with allocation succeeding again on the
+  subsequent call(s) we will return a truncated list around the malloc
+  failure point. Fix by assigning to a temporary list pointer, which can
+  be checked (which is the common pattern for slist appending), and free
+  all the resources on allocation failure.
   
-  Closes #3140
-  Reviewed-by: Jay Satiro
-
-Daniel Stenberg (17 Oct 2018)
-- RELEASE-NOTES: synced
+  Closes #3372
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- docs/SECURITY-PROCESS: the hackerone IBB program drops curl
+- cookies: leave secure cookies alone
   
-  ... now there's only BountyGraph.
-
-Jay Satiro (16 Oct 2018)
-- [Matthew Whitehead brought this change]
-
-  x509asn1: Fix SAN IP address verification
+  Only allow secure origins to be able to write cookies with the
+  'secure' flag set. This reduces the risk of non-secure origins
+  to influence the state of secure origins. This implements IETF
+  Internet-Draft draft-ietf-httpbis-cookie-alone-01 which updates
+  RFC6265.
   
-  For IP addresses in the subject alternative name field, the length
-  of the IP address (and hence the number of bytes to perform a
-  memcmp on) is incorrectly calculated to be zero. The code previously
-  subtracted q from name.end. where in a successful case q = name.end
-  and therefore addrlen equalled 0. The change modifies the code to
-  subtract name.beg from name.end to calculate the length correctly.
+  Closes #2956
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+
+Daniel Stenberg (13 Dec 2018)
+- docs: fix the --tls-max description
   
-  The issue only affects libcurl with GSKit SSL, not other SSL backends.
-  The issue is not a security issue as IP verification would always fail.
+  Reported-by: Tobias Lindgren
+  Pointed out in #3367
   
-  Fixes #3102
-  Closes #3141
+  Closes #3368
 
-Daniel Gustafsson (15 Oct 2018)
-- INSTALL: mention mesalink in TLS section
+Daniel Gustafsson (12 Dec 2018)
+- urlapi: Fix port parsing of eol colon
   
-  Commit 57348eb97d1b8fc3742e02c6587d2d02ff592da5 added support for the
-  MesaLink vtls backend, but missed updating the TLS section containing
-  supported backends in the docs.
+  A URL with a single colon without a portnumber should use the default
+  port, discarding the colon. Fix, add a testcase and also do little bit
+  of comment wordsmithing.
   
-  Closes #3134
+  Closes #3365
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Marcel Raad (14 Oct 2018)
-- nonblock: fix unused parameter warning
-  
-  If USE_BLOCKING_SOCKETS is defined, curlx_nonblock's arguments are not
-  used.
+Version 7.63.0 (12 Dec 2018)
 
-Michael Kaufmann (13 Oct 2018)
-- Curl_follow: Always free the passed new URL
-  
-  Closes #3124
+Daniel Stenberg (12 Dec 2018)
+- RELEASE-NOTES: 7.63.0
 
-Viktor Szakats (12 Oct 2018)
-- replace rawgit links [ci skip]
-  
-  Ref: https://rawgit.com/ "RawGit has reached the end of its useful life"
-  Ref: https://news.ycombinator.com/item?id=18202481
-  Closes https://github.com/curl/curl/pull/3131
+- THANKS: from the curl 7.62.0 cycle
 
-Daniel Stenberg (12 Oct 2018)
-- docs/BUG-BOUNTY.md: for vulns published since Aug 1st 2018
-  
-  [ci skip]
+- test1519: use lib1518 and test CURLINFO_REDIRECT_URL more
 
-- travis: make distcheck scan for BOM markers
+- Curl_follow: extract the Location: header field unvalidated
+  
+  ... when not actually following the redirect. Otherwise we return error
+  for this and an application can't extract the value.
   
-  and remove BOM from projects/wolfssl_override.props
+  Test 1518 added to verify.
   
-  Closes #3126
+  Reported-by: Pavel Pavlov
+  Fixes #3340
+  Closes #3364
 
-Marcel Raad (11 Oct 2018)
-- CMake: remove BOM
+- multi: convert two timeout variables to timediff_t
   
-  Accidentally aded in commit 1bb86057ff07083deeb0b00f8ad35879ec4d03ea.
+  The time_t type is unsigned on some systems and these variables are used
+  to hold return values from functions that return timediff_t
+  already. timediff_t is always a signed type.
   
-  Reported-by: Viktor Szakats
-  Ref: https://github.com/curl/curl/pull/3120#issuecomment-428673136
+  Closes #3363
 
-Daniel Gustafsson (10 Oct 2018)
-- transfer: fix typo in comment
+- delta: use --diff-filter on the git diff-tree invokes
+  
+  Suggested-by: Dave Reisner
 
-Michael Kaufmann (10 Oct 2018)
-- docs: add "see also" links for SSL options
+Patrick Monnerat (11 Dec 2018)
+- documentation: curl_formadd field and file names are now escaped
   
-  - link TLS 1.2 and TLS 1.3 options
-  - link proxy and non-proxy options
+  Prior to 7.56.0, fieldnames and filenames were set in Content-Disposition
+  header without special processing: this may lead to invalid RFC 822
+  quoted-strings.
+  7.56.0 introduces escaping of backslashes and double quotes in these names:
+  mention it in the documentation.
   
-  Closes #3121
+  Reported-by: daboul on github
+  Closes #3361
 
-Marcel Raad (10 Oct 2018)
-- AppVeyor: remove BDIR variable that sneaked in again
+Daniel Stenberg (11 Dec 2018)
+- scripts/delta: show repo delta info from last release
   
-  Removed in ae762e1abebe3a5fe75658583c85059a0957ef6e, accidentally added
-  again in 9f3be5672dc4dda30ab43e0152e13d714a84d762.
+  ... where "last release" should be the git tag in the repo.
 
-- CMake: disable -Wpedantic-ms-format
+Daniel Gustafsson (11 Dec 2018)
+- tests: add urlapi unittest
   
-  As done in the autotools build. This is required for MinGW, which
-  supports only %I64 for printing 64-bit values, but warns about it.
+  This adds a new unittest intended to cover the internal functions in
+  the urlapi code, starting with parse_port(). In order to avoid name
+  collisions in debug builds, parse_port() is renamed Curl_parse_port()
+  since it will be exported.
   
-  Closes https://github.com/curl/curl/pull/3120
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
 
-Viktor Szakats (9 Oct 2018)
-- ldap: show precise LDAP call in error message on Windows
+- urlapi: fix portnumber parsing for ipv6 zone index
   
-  Also add a unique but common text ('bind via') to make it
-  easy to grep this specific failure regardless of platform.
+  An IPv6 URL which contains a zone index includes a '%%25<zode id>'
+  string before the ending ']' bracket. The parsing logic wasn't set
+  up to cope with the zone index however, resulting in a malformed url
+  error being returned. Fix by breaking the parsing into two stages
+  to correctly handle the zone index.
   
-  Ref: https://github.com/curl/curl/pull/878/files#diff-7a636f08047c4edb53a240f540b4ecf6R468
-  Closes https://github.com/curl/curl/pull/3118
+  Closes #3355
+  Closes #3319
+  Reported-by: tonystz on Github
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
   Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
 
-Daniel Stenberg (9 Oct 2018)
-- docs/DEPRECATE: minor reformat to render nicer on web
+Daniel Stenberg (11 Dec 2018)
+- [Jay Satiro brought this change]
 
-Daniel Gustafsson (9 Oct 2018)
-- CURLOPT_SSL_VERIFYSTATUS: Fix typo
+  http: fix HTTP auth to include query in URI
   
-  Changes s/OSCP/OCSP/ and bumps the copyright year due to the change.
-
-Marcel Raad (9 Oct 2018)
-- curl_setup: define NOGDI on Windows
+  - Include query in the path passed to generate HTTP auth.
   
-  This avoids an ERROR macro clash between <wingdi.h> and <arpa/tftp.h>
-  on MinGW.
+  Recent changes to use the URL API internally (46e1640, 7.62.0)
+  inadvertently broke authentication URIs by omitting the query.
   
-  Closes https://github.com/curl/curl/pull/3113
+  Fixes https://github.com/curl/curl/issues/3353
+  Closes #3356
+
+- [Michael Kaufmann brought this change]
 
-- Windows: fixes for MinGW targeting Windows Vista
+  http: don't set CURLINFO_CONDITION_UNMET for http status code 204
   
-  Classic MinGW has neither InitializeCriticalSectionEx nor
-  GetTickCount64, independent of the target Windows version.
+  The http status code 204 (No Content) should not change the "condition
+  unmet" flag. Only the http status code 304 (Not Modified) should do
+  this.
   
-  Closes https://github.com/curl/curl/pull/3113
+  Closes #359
 
-Daniel Stenberg (8 Oct 2018)
-- TODO: fixed 'API for URL parsing/splitting'
+- [Samuel Surtees brought this change]
 
-Daniel Gustafsson (8 Oct 2018)
-- KNOWN_BUGS: Fix various typos
+  ldap: fix LDAP URL parsing regressions
   
-  Closes #3112
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-
-Viktor Szakats (8 Oct 2018)
-- spelling fixes [ci skip]
+  - Match URL scheme with LDAP and LDAPS
+  - Retrieve attributes, scope and filter from URL query instead
   
-  as detected by codespell 1.14.0
+  Regression brought in 46e164069d1a5230 (7.62.0)
   
-  Closes https://github.com/curl/curl/pull/3114
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  Closes #3362
 
-Daniel Stenberg (8 Oct 2018)
 - RELEASE-NOTES: synced
 
-- curl_ntlm_wb: check aprintf() return codes
+- [Stefan Kanthak brought this change]
+
+  (lib)curl.rc: fixup for minor bugs
   
-  ... when they return NULL we're out of memory and MUST return failure.
+  All resources defined in lib/libcurl.rc and curl.rc are language
+  neutral.
   
-  closes #3111
-
-- docs/BUG-BOUNTY: proposed additional docs
+  winbuild/MakefileBuild.vc ALWAYS defines the macro DEBUGBUILD, so the
+  ifdef's in line 33 of lib/libcurl.rc and src/curl.rc are wrong.
   
-  Bug bounty explainer. See https://bountygraph.com/programs/curl
+  Replace the hard-coded constants in both *.rc files with #define'd
+  values.
   
-  Closes #3067
+  Thumbs-uped-by: Rod Widdowson, Johannes Schindelin
+  URL: https://curl.haxx.se/mail/lib-2018-11/0000.html
+  Closes #3348
 
-- [Rick Deist brought this change]
+- test329: verify cookie max-age=0 immediate expiry
 
-  hostip: fix check on Curl_shuffle_addr return value
+- cookies: expire "Max-Age=0" immediately
   
-  Closes #3110
+  Reported-by: Jeroen Ooms
+  Fixes #3351
+  Closes #3352
 
-- FILE: fix CURLOPT_NOBODY and CURLOPT_HEADER output
-  
-  Now FILE transfers send headers to the header callback like HTTP and
-  other protocols. Also made curl_easy_getinfo(...CURLINFO_PROTOCOL...)
-  work for FILE in the callbacks.
-  
-  Makes "curl -i file://.." and "curl -I file://.." work like before
-  again. Applied the bold header logic to them too.
+- [Johannes Schindelin brought this change]
+
+  Upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1
   
-  Regression from c1c2762 (7.61.0)
+  This is a companion patch to cbea2fd2c (NTLM: force the connection to
+  HTTP/1.1, 2018-12-06): with NTLM, we can switch to HTTP/1.1
+  preemptively. However, with other (Negotiate) authentication it is not
+  clear to this developer whether there is a way to make it work with
+  HTTP/2, so let's try HTTP/2 first and fall back in case we encounter the
+  error HTTP_1_1_REQUIRED.
   
-  Reported-by: Shaun Jackman
-  Fixes #3083
-  Closes #3101
-
-Daniel Gustafsson (7 Oct 2018)
-- gskit: make sure to terminate version string
+  Note: we will still keep the NTLM workaround, as it avoids an extra
+  round trip.
   
-  In case a very small buffer was passed to the version function, it could
-  result in the buffer not being NULL-terminated since strncpy() doesn't
-  guarantee a terminator on an overflowed buffer. Rather than adding code
-  to terminate (and handle zero-sized buffers), move to using snprintf()
-  instead like all the other vtls backends.
+  Daniel Stenberg helped a lot with this patch, in particular by
+  suggesting to introduce the Curl_h2_http_1_1_error() function.
   
-  Closes #3105
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Viktor Szakats <commit@vszakats.net>
-
-- TODO: add LD_PRELOAD support on macOS
+  Closes #3349
   
-  Add DYLD_INSERT_LIBRARIES support to the TODO list. Reported in #2394.
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
 
-- runtests: skip ld_preload tests on macOS
-  
-  The LD_PRELOAD functionality doesn't exist on macOS, so skip any tests
-  requiring it.
-  
-  Fixes #2394
-  Closes #3106
-  Reported-by: Github user @jakirkham
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+- [Ben Greear brought this change]
 
-Marcel Raad (7 Oct 2018)
-- AppVeyor: use Debug builds to run tests
+  openssl: fix unused variable compiler warning with old openssl
   
-  This enables more tests.
+  URL: https://curl.haxx.se/mail/lib-2018-11/0055.html
   
-  Closes https://github.com/curl/curl/pull/3104
+  Closes #3347
 
-- AppVeyor: add HTTP_ONLY build
-  
-  Closes https://github.com/curl/curl/pull/3104
+- [Johannes Schindelin brought this change]
 
-- AppVeyor: add WinSSL builds
+  NTLM: force the connection to HTTP/1.1
   
-  Use the oldest and latest Windows SDKs for them.
-  Also, remove all but one OpenSSL build.
+  Since v7.62.0, cURL tries to use HTTP/2 whenever the server announces
+  the capability. However, NTLM authentication only works with HTTP/1.1,
+  and will likely remain in that boat (for details, see
+  https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported).
   
-  Closes https://github.com/curl/curl/pull/3104
-
-- AppVeyor: add remaining Visual Studio versions
+  When we just found out that we want to use NTLM, and when the current
+  connection runs in HTTP/2 mode, let's force the connection to be closed
+  and to be re-opened using HTTP/1.1.
   
-  This adds Visual Studio 9 and 10 builds.
-  There's no 64-bit VC9 compiler on AppVeyor, so use it as the Win32
-  build. Also, VC9 cannot be used for running the test suite.
+  Fixes https://github.com/curl/curl/issues/3341.
+  Closes #3345
   
-  Closes https://github.com/curl/curl/pull/3104
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
 
-- AppVeyor: break long line
-  
-  Closes https://github.com/curl/curl/pull/3104
+- [Johannes Schindelin brought this change]
 
-- AppVeyor: remove unused BDIR variable
+  curl_global_sslset(): id == -1 is not necessarily an error
   
-  Closes https://github.com/curl/curl/pull/3104
-
-Daniel Stenberg (6 Oct 2018)
-- test2100: test DoH using IPv4-only
+  It is allowed to call that function with id set to -1, specifying the
+  backend by the name instead. We should imitate what is done further down
+  in that function to allow for that.
   
-  To make it only send one DoH request and avoid the race condition that
-  could lead to the requests getting sent in reversed order and thus
-  making it hard to compare in the test case.
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
   
-  Fixes #3107
-  Closes #3108
+  Closes #3346
 
-- tests/FILEFORMAT: mention how to use <fileN> and <stripfileN> too
+Johannes Schindelin (6 Dec 2018)
+- .gitattributes: make tabs in indentation a visible error
   
-  [ci skip]
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
 
+Daniel Stenberg (6 Dec 2018)
 - RELEASE-NOTES: synced
 
-- [Dmitry Kostjuchenko brought this change]
-
-  timeval: fix use of weak symbol clock_gettime() on Apple platforms
+- doh: fix memory leak in OOM situation
   
-  Closes #3048
+  Reviewed-by: Daniel Gustafsson
+  Closes #3342
 
-- doh: keep the IPv4 address in (original) network byte order
-  
-  Ideally this will fix the reversed order shown in SPARC tests:
-  
-    resp 8: Expected 127.0.0.1 got 1.0.0.127
+- doh: make it work for h2-disabled builds too
   
-  Closes #3091
-
-Jay Satiro (5 Oct 2018)
-- INTERNALS.md: wrap lines longer than 79
+  Reported-by: dtmsecurity at github
+  Fixes #3325
+  Closes #3336
 
-Daniel Gustafsson (5 Oct 2018)
-- INTERNALS: escape reference to parameter
+- packages: remove old leftover files and dirs
   
-  The parameter reference <string> was causing rendering issues in the
-  generated HTML page, as <string> isn't a valid HTML tag. Fix by back-
-  tick escaping it.
+  This subdir has mostly become an attic of never-used cruft from the
+  past.
   
-  Closes #3099
-  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #3331
 
-- checksrc: handle zero scoped ignore commands
-  
-  If a !checksrc! disable command specified to ignore zero errors, it was
-  still added to the ignore block even though nothing was ignored. While
-  there were no blocks ignored that shouldn't be ignored, the processing
-  ended with with a warning:
-  
-  <filename>:<line>:<col>: warning: Unused ignore: LONGLINE (UNUSEDIGNORE)
-   /* !checksrc! disable LONGLINE 0 */
-                      ^
-  Fix by instead treating a zero ignore as a a badcommand and throw a
-  warning for that one.
-  
-  Closes #3096
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+- [Gergely Nagy brought this change]
 
-- checksrc: enable strict mode and warnings
-  
-  Enable strict and warnings mode for checksrc to ensure we aren't missing
-  anything due to bugs in the checking code. This uncovered a few things
-  which are all fixed in this commit:
+  openssl: do not use file BIOs if not requested
   
-  * several variables were used uninitialized
-  * several variables were not defined in the correct scope
-  * the whitelist filehandle was read even if the file didn't exist
-  * the enable_warn() call when a disable counter had expired was passing
-    incorrect variables, but since the checkwarn() call is unlikely to hit
-    (the counter is only decremented to zero on actual ignores) it didn't
-    manifest a problem.
+  Moves the file handling BIO calls to the branch of the code where they
+  are actually used.
   
-  Closes #3090
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  Closes #3339
 
-Marcel Raad (5 Oct 2018)
-- CMake: suppress MSVC warning C4127 for libtest
-  
-  It's issued by older Windows SDKs (prior to version 8.0).
+- [Paul Howarth brought this change]
 
-Sergei Nikulov (5 Oct 2018)
-- Merge branch 'dmitrykos-fix_missing_CMake_defines'
+  nss: Fix compatibility with nss versions 3.14 to 3.15
 
-- [Dmitry Kostjuchenko brought this change]
+- [Paul Howarth brought this change]
 
-  cmake: test and set missed defines during configuration
-  
-  Added configuration checks for HAVE_BUILTIN_AVAILABLE and HAVE_CLOCK_GETTIME_MONOTONIC.
+  nss: Improve info message when falling back SSL protocol
   
-  Closes #3097
+  Use descriptive text strings rather than decimal numbers.
 
-Marcel Raad (5 Oct 2018)
-- AppVeyor: disable test 500
-  
-  It almost always results in
-  "starttransfer vs total: 0.000001 0.000000".
-  I cannot reproduce this locally, so disable it for now.
-  
-  Closes https://github.com/curl/curl/pull/3100
+- [Paul Howarth brought this change]
 
-- AppVeyor: set custom install prefix
-  
-  CMake's default has spaces and in 32-bit mode parentheses, which result
-  in syntax errors in curl-config.
+  nss: Fall back to latest supported SSL version
   
-  Closes https://github.com/curl/curl/pull/3100
-
-- AppVeyor: Remove non-SSL non-test builds
+  NSS may be built without support for the latest SSL/TLS versions,
+  leading to "SSL version range is not valid" errors when the library
+  code supports a recent version (e.g. TLS v1.3) but it has explicitly
+  been disabled.
   
-  They don't add much value.
+  This change adjusts the maximum SSL version requested by libcurl to
+  be the maximum supported version at runtime, as long as that version
+  is at least as high as the minimum version required by libcurl.
   
-  Closes https://github.com/curl/curl/pull/3100
+  Fixes #3261
 
-- AppVeyor: run test suite
-  
-  Use the preinstalled MSYS2 bash for that.
-  Disable test 1139 as the CMake build doesn't generate curl.1.
+Daniel Gustafsson (3 Dec 2018)
+- travis: enable COPYRIGHTYEAR extended warning
   
-  Ref: https://github.com/curl/curl/issues/3070#issuecomment-425922224
-  Closes https://github.com/curl/curl/pull/3100
+  The extended warning for checking incorrect COPYRIGHTYEAR is quite
+  expensive to run, so rather than expecting every developer to do it
+  we ensure it's turned on locally for Travis.
 
-- AppVeyor: use in-tree build
-  
-  Required to run the tests.
+- checksrc: add COPYRIGHTYEAR check
   
-  Closes https://github.com/curl/curl/pull/3100
-
-Daniel Stenberg (4 Oct 2018)
-- doh: make sure TTL isn't re-inited by second (discarded?) response
+  Forgetting to bump the year in the copyright clause when hacking has
+  been quite common among curl developers, but a traditional checksrc
+  check isn't a good fit as it would penalize anyone hacking on January
+  1st (among other things). This adds a more selective COPYRIGHTYEAR
+  check which intends to only cover the currently hacked on changeset.
   
-  Closes #3092
-
-- test320: strip out more HTML when comparing
+  The check for updated copyright year is currently not enforced on all
+  files but only on files edited and/or committed locally. This is due to
+  the amount of files which aren't updated with their correct copyright
+  year at the time of their respective commit.
   
-  To make the test case work with different gnutls-serv versions better.
+  To further avoid running this expensive check for every developer, it
+  adds a new local override mode for checksrc where a .checksrc file can
+  be used to turn on extended warnings locally.
   
-  Reported-by: Kamil Dudka
-  Fixes #3093
-  Closes #3094
+  Closes #3303
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Marcel Raad (4 Oct 2018)
-- runtests: use Windows paths for Windows curl
+Daniel Stenberg (3 Dec 2018)
+- CHECKSRC.md: document more warnings
   
-  curl generated by CMake's Visual Studio generator has "Windows" in the
-  version number.
-
-Daniel Stenberg (4 Oct 2018)
-- [Colin Hogben brought this change]
+  Closes #3335
+  [ci skip]
 
-  tests/negtelnetserver.py: fix Python2-ism in neg TELNET server
-  
-  Fix problems caused by differences in treatment of bytes objects between
-  python2 and python3.
-  
-  Fixes #2929
-  Closes #3080
+- RELEASE-NOTES: synced
 
-Daniel Gustafsson (3 Oct 2018)
-- memory: ensure to check allocation results
-  
-  The result of a memory allocation should always be checked, as we may
-  run under memory pressure where even a small allocation can fail. This
-  adds checking and error handling to a few cases where the allocation
-  wasn't checked for success. In the ftp case, the freeing of the path
-  variable is moved ahead of the allocation since there is little point
-  in keeping it around across the strdup, and the separation makes for
-  more readable code. In nwlib, the lock is aslo freed in the error path.
+- SECURITY-PROCESS: bountygraph shuts down
   
-  Also bumps the copyright years on affected files.
+  This backpedals back the documents to the state before bountygraph.
   
-  Closes #3084
-  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Closes #3311
 
-- comment: Fix multiple typos in function parameters
+- curl: fix memory leak reading --writeout from file
   
-  Ensure that the parameters in the comment match the actual names in the
-  prototype.
+  If another string had been set first, the writout function for reading
+  the syntax from file would leak the previously allocated memory.
   
-  Closes #3079
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Reported-by: Brian Carpenter
+  Fixes #3322
+  Closes #3330
 
-- CURLOPT_SSLVERSION.3: fix typos and consistent spelling
-  
-  Use TLS vX.Y throughout the document, instead of TLS X.Y, as that was
-  already done in all but a few cases. Also fix a few typos.
+- tool_main: rename function to make it unique and better
   
-  Closes #3076
-  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  ... there's already another function in the curl tool named
+  free_config_fields!
 
-- SECURITY-PROCESS: make links into hyperlinks
+Daniel Gustafsson (29 Nov 2018)
+- TODO: remove CURLOPT_DNS_USE_GLOBAL_CACHE entry
   
-  Use proper Markdown hyperlink format for the Bountygraph links in order
-  for the generated website page to be more user friendly. Also link to
-  the sponsors to give them a little extra credit.
+  Commit 7c5837e79280e6abb3ae143dfc49bca5e74cdd11 deprecated the option
+  making it a manual code-edit operation to turn it back on. The removal
+  process has thus started and is now documented in docs/DEPRECATE.md so
+  remove from the TODO to avoid anyone looking for something to pick up
+  spend cycles on an already in-progress entry.
   
-  Closes #3082
   Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Jay Satiro (3 Oct 2018)
-- CURLOPT_HEADER.3: fix typo
-
-- nss: fix nssckbi module loading on Windows
-  
-  - Use .DLL extension instead of .so to load modules on Windows.
-  
-  Bug: https://curl.haxx.se/mail/lib-2018-09/0077.html
-  Reported-by: Maxime Legros
-  
-  Ref: https://github.com/curl/curl/pull/3016/#issuecomment-423069442
-  
-  Closes https://github.com/curl/curl/pull/3086
+Jay Satiro (29 Nov 2018)
+- [Sevan Janiyan brought this change]
 
-- data-binary.d: clarify default content-type is x-www-form-urlencoded
-  
-  - Advise user that --data-binary sends a default content type of
-    x-www-form-urlencoded, and to have the data treated as arbitrary
-    binary data by the server set the content-type header to octet-stream.
-  
-  Ref: https://github.com/curl/curl/pull/2852#issuecomment-426465094
+  connect: fix building for recent versions of Minix
   
-  Closes https://github.com/curl/curl/pull/3085
-
-Marcel Raad (2 Oct 2018)
-- test1299: use single quotes around asterisk
+  EBADIOCTL doesn't exist on more recent Minix.
+  There have also been substantial changes to the network stack.
+  Fixes build on Minix 3.4rc
   
-  Ref: https://github.com/curl/curl/issues/1751#issuecomment-321522580
+  Closes https://github.com/curl/curl/pull/3323
 
-Daniel Stenberg (2 Oct 2018)
-- docs/CIPHERS: mention the colon separation for OpenSSL
-  
-  Bug: #3077
+- [Konstantin Kushnir brought this change]
 
-- runtests: ignore disabled even when ranges are given
-  
-  runtests.pl support running a range of tests, like "44 to 127". Starting
-  now, the code makes sure that even such given ranges will ignore tests
-  that are marked as disabled.
+  CMake: fix MIT/Heimdal Kerberos detection
   
-  Disabled tests can still be run by explictly specifying that test
-  number.
+  - fix syntax error in FindGSS.cmake
+  - correct krb5 include directory. FindGSS exports
+    "GSS_INCLUDE_DIR" variable.
   
-  Closes #3075
+  Closes https://github.com/curl/curl/pull/3316
 
-- urlapi: starting with a drive letter on win32 is not an abs url
-  
-  ... and libcurl doesn't support any single-letter URL schemes (if there
-  even exist any) so it should be fairly risk-free.
-  
-  Reported-by: Marcel Raad
+Daniel Stenberg (28 Nov 2018)
+- test328: verify Content-Encoding: none
   
-  Fixes #3070
-  Closes #3071
-
-Marcel Raad (2 Oct 2018)
-- doh: fix curl_easy_setopt argument type
+  Because of issue #3315
   
-  CURLOPT_POSTFIELDSIZE is long. Fixes a compiler warning on 64-bit
-  MinGW.
-
-Daniel Stenberg (2 Oct 2018)
-- RELEASE-NOTES: synced
+  Closes #3317
 
-Jay Satiro (1 Oct 2018)
-- [Ruslan Baratov brought this change]
+- [James Knight brought this change]
 
-  CMake: Improve config installation
-  
-  Use 'GNUInstallDirs' standard module to set destinations of installed
-  files.
-  
-  Use uppercase "CURL" names instead of lowercase "curl" to match standard
-  'FindCURL.cmake' CMake module:
-  * https://cmake.org/cmake/help/latest/module/FindCURL.html
+  configure: include all libraries in ssl-libs fetch
   
-  Meaning:
-  * Install 'CURLConfig.cmake' instead of 'curl-config.cmake'
-  * User should call 'find_package(CURL)' instead of 'find_package(curl)'
+  When compiling a collection of SSL libraries to link against (SSL_LIBS),
+  ensure all libraries are included. The call `--libs-only-l` can produce
+  only a subset of found in a `--libs` call (e.x. pthread may be excluded).
+  Adding `--libs-only-other` ensures other libraries are also included in
+  the list. This corrects select build environments compiling against a
+  static version of OpenSSL. Before the change, the following could be
+  observed:
   
-  Use 'configure_package_config_file' function to generate
-  'CURLConfig.cmake' file. This will make 'curl-config.cmake.in' template
-  file smaller and handle components better.  E.g.  current configuration
-  report no error if user specified unknown components (note: new
-  configuration expects no components, report error if user will try to
-  specify any).
+      checking for openssl options with pkg-config... found
+      configure: pkg-config: SSL_LIBS: "-lssl -lz -ldl -lcrypto -lz -ldl "
+      configure: pkg-config: SSL_LDFLAGS: "-L/home/jdknight/<workdir>/staging/usr/lib -L/home/jdknight/<workdir>/staging/usr/lib "
+      configure: pkg-config: SSL_CPPFLAGS: "-I/home/jdknight/<workdir>/staging/usr/include "
+      checking for HMAC_Update in -lcrypto... no
+      checking for HMAC_Init_ex in -lcrypto... no
+      checking OpenSSL linking with -ldl... no
+      checking OpenSSL linking with -ldl and -lpthread... no
+      configure: WARNING: SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.
+      configure: WARNING: Use --with-ssl, --with-gnutls, --with-polarssl, --with-cyassl, --with-nss, --with-axtls, --with-winssl, or --with-darwinssl to address this.
+      ...
+      SSL support:      no      (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,axtls,winssl,darwinssl} )
+      ...
   
-  Closes https://github.com/curl/curl/pull/2849
-
-Daniel Stenberg (1 Oct 2018)
-- test1650: make it depend on http/2
+  And include the other libraries when compiling SSL_LIBS succeeds with:
   
-  Follow-up to 570008c99da0ccbb as it gets link errors.
+      checking for openssl options with pkg-config... found
+      configure: pkg-config: SSL_LIBS: "-lssl -lz -ldl -pthread -lcrypto -lz -ldl -pthread "
+      configure: pkg-config: SSL_LDFLAGS: "-L/home/jdknight/<workdir>/staging/usr/lib -L/home/jdknight/<workdir>/staging/usr/lib "
+      configure: pkg-config: SSL_CPPFLAGS: "-I/home/jdknight/<workdir>/staging/usr/include "
+      checking for HMAC_Update in -lcrypto... yes
+      checking for SSL_connect in -lssl... yes
+      ...
+      SSL support:      enabled (OpenSSL)
+      ...
   
-  Reported-by: Michael Kaufmann
-  Closes #3068
-
-- [Nate Prewitt brought this change]
+  Signed-off-by: James Knight <james.d.knight@live.com>
+  Closes #3193
 
-  MANUAL: minor grammar fix
-  
-  Noticed a typo reading through the docs.
+Daniel Gustafsson (26 Nov 2018)
+- doh: fix typo in infof call
   
-  Closes #3069
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- doh: only build if h2 enabled
-  
-  The DoH spec says "HTTP/2 [RFC7540] is the minimum RECOMMENDED version
-  of HTTP for use with DoH".
+- cmdline-opts/gen.pl: define the correct varname
   
-  Reported-by: Marcel Raad
-  Closes #3066
-
-- test2100: require http2 to run
+  The variable definition had a small typo making it declare another
+  variable then the intended.
   
-  Reported-by: Marcel Raad
-  Fixes #3064
-  Closes #3065
+  Closes #3304
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- multi: fix memory leak in content encoding related error path
-  
-  ... a missing multi_done() call.
-  
-  Credit to OSS-Fuzz
-  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10728
-  Closes #3063
+Daniel Stenberg (25 Nov 2018)
+- RELEASE-NOTES: synced
 
-- travis: bump the Secure Transport build to use xcode 10
+- curl_easy_perform: fix timeout handling
   
-  Due to an issue with travis
-  (https://github.com/travis-ci/travis-ci/issues/9956) we've been using
-  Xcode 9.2 for darwinssl builds for a while. Now xcode 10 is offered as
-  an alternative and as it builds curl+darwinssl fine that seems like a
-  better choice.
+  curl_multi_wait() was erroneously used from within
+  curl_easy_perform(). It could lead to it believing there was no socket
+  to wait for and then instead sleep for a while instead of monitoring the
+  socket and then miss acting on that activity as swiftly as it should
+  (causing an up to 1000 ms delay).
   
-  Closes #3062
+  Reported-by: Antoni Villalonga
+  Fixes #3305
+  Closes #3306
+  Closes #3308
 
-- [Rich Turner brought this change]
+- CURLOPT_WRITEFUNCTION.3: spell out that it gets called many times
 
-  curl: enabled Windows VT Support and UTF-8 output
+- cookies: create the cookiejar even if no cookies to save
   
-  Enabled Console VT support (if running OS supports VT) in tool_main.c.
+  Important for when the file is going to be read again and thus must not
+  contain old contents!
   
-  Fixes #3008
-  Closes #3011
-
-- multi: fix location URL memleak in error path
+  Adds test 327 to verify.
   
-  Follow-up to #3044 - fix a leak OSS-Fuzz detected
-  Closes #3057
-
-Sergei Nikulov (28 Sep 2018)
-- cmake: fixed path used in generation of docs/tests during curl build through add_subdicectory(...)
+  Reported-by: daboul on github
+  Fixes #3299
+  Closes #3300
 
-- [Brad King brought this change]
+- checksrc: ban snprintf use, add command line flag to override warns
 
-  cmake: Backport to work with CMake 3.0 again
+- snprintf: renamed and we now only use msnprintf()
   
-  Changes in commit 7867aaa9a0 (cmake: link curl to the OpenSSL targets
-  instead of lib absolute paths, 2018-07-17) and commit f826b4ce98 (cmake:
-  bumped minimum version to 3.4, 2018-07-19) required CMake 3.4 to fix
-  issue #2746.  This broke support for users on older versions of CMake
-  even if they just want to build curl and do not care whether transitive
-  dependencies work.
+  The function does not return the same value as snprintf() normally does,
+  so readers may be mislead into thinking the code works differently than
+  it actually does. A different function name makes this easier to detect.
   
-  Backport the logic to work with CMake 3.0 again by implementing the
-  fix only when the version of CMake is at least 3.4.
+  Reported-by: Tomas Hoger
+  Assisted-by: Daniel Gustafsson
+  Fixes #3296
+  Closes #3297
 
-Marcel Raad (27 Sep 2018)
-- curl_threads: fix classic MinGW compile break
-  
-  Classic MinGW still has _beginthreadex's return type as unsigned long
-  instead of uintptr_t [0]. uintptr_t is not even defined because of [1].
-  
-  [0] https://sourceforge.net/p/mingw/mingw-org-wsl/ci/wsl-5.1-release/tree/mingwrt/include/process.h#l167
-  [1] https://sourceforge.net/p/mingw/mingw-org-wsl/ci/wsl-5.1-release/tree/mingwrt/include/process.h#l90
-  
-  Bug: https://github.com/curl/curl/issues/2924#issuecomment-424334807
-  Closes https://github.com/curl/curl/pull/3051
+- [Tobias Hintze brought this change]
 
-Daniel Stenberg (26 Sep 2018)
-- configure: s/AC_RUN_IFELSE/CURL_RUN_IFELSE
+  test: update test20/1322 for eglibc bug workaround
   
-  fix a few leftovers
+  The tests 20 and 1322 are using getaddrinfo of libc for resolving. In
+  eglibc-2.19 there is a memory leakage and invalid free bug which
+  surfaces in some special circumstances (PF_UNSPEC hint with invalid or
+  non-existent names). The valgrind runs in testing fail in these
+  situations.
   
-  Fixes #3006
-  Closes #3049
+  As the tests 20/1322 are not specific on either protocol (IPv4/IPv6)
+  this commit changes the hints to IPv4 protocol by passing `--ipv4` flag
+  on the tests' command line.  This prevents the valgrind failures.
 
-- [Doron Behar brought this change]
+- [Tobias Hintze brought this change]
 
-  example/htmltidy: fix include paths of tidy libraries
+  host names: allow trailing dot in name resolve, then strip it
+  
+  Delays stripping of trailing dots to after resolving the hostname.
   
-  Closes #3050
+  Fixes #3022
+  Closes #3222
 
-- RELEASE-NOTES: synced
+- [UnknownShadow200 brought this change]
 
-- Curl_http2_done: fix memleak in error path
-  
-  Free 'header_recvbuf' unconditionally even if 'h2' isn't (yet) set, for
-  early failures.
-  
-  Detected by OSS-Fuzz
+  CURLOPT_HEADERFUNCTION.3: match 'nitems' name in synopsis and description
   
-  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10669
-  Closes #3046
+  Closes #3295
+
+Daniel Gustafsson (21 Nov 2018)
+- configure: Fix typo in comment
 
-- http: fix memleak in rewind error path
+Michael Kaufmann (21 Nov 2018)
+- openssl: support session resume with TLS 1.3
   
-  If the rewind would fail, a strdup() would not get freed.
+  Session resumption information is not available immediately after a TLS 1.3
+  handshake. The client must wait until the server has sent a session ticket.
   
-  Detected by OSS-Fuzz
+  Use OpenSSL's "new session" callback to get the session information and put it
+  into curl's session cache. For TLS 1.3 sessions, this callback will be invoked
+  after the server has sent a session ticket.
   
-  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10665
-  Closes #3044
-
-Viktor Szakats (24 Sep 2018)
-- test320: fix regression in [ci skip]
+  The "new session" callback is invoked only if OpenSSL's session cache is
+  enabled, so enable it and use the "external storage" mode which lets curl manage
+  the contents of the session cache.
   
-  The value in question is coming directly from `gnutls-serv`, so it cannot
-  be modified freely.
+  A pointer to the connection data and the sockindex are now saved as "SSL extra
+  data" to make them available to the callback.
   
-  Reported-by: Marcel Raad
-  Ref: https://github.com/curl/curl/commit/6ae6b2a533e8630afbb21f570305bd4ceece6348#commitcomment-30621004
-
-Daniel Stenberg (24 Sep 2018)
-- Curl_retry_request: fix memory leak
+  This approach also works for old SSL/TLS versions and old OpenSSL versions.
   
-  Detected by OSS-Fuzz
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
   
-  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10648
-  Closes #3042
+  Fixes #3202
+  Closes #3271
 
-- openssl: load built-in engines too
+- ssl: fix compilation with OpenSSL 0.9.7
   
-  Regression since 38203f1
+  - ENGINE_cleanup() was used without including "openssl/engine.h"
+  - enable engine support for OpenSSL 0.9.7
   
-  Reported-by: Jean Fabrice
-  Fixes #3023
-  Closes #3040
-
-- [Christian Heimes brought this change]
+  Closes #3266
 
-  OpenSSL: enable TLS 1.3 post-handshake auth
-  
-  OpenSSL 1.1.1 requires clients to opt-in for post-handshake
-  authentication.
+Daniel Stenberg (21 Nov 2018)
+- openssl: disable TLS renegotiation with BoringSSL
   
-  Fixes: https://github.com/curl/curl/issues/3026
-  Signed-off-by: Christian Heimes <christian@python.org>
+  Since we're close to feature freeze, this change disables this feature
+  with an #ifdef. Define ALLOW_RENEG at build-time to enable.
   
-  Closes https://github.com/curl/curl/pull/3027
-
-- [Even Rouault brought this change]
-
-  Curl_dedotdotify(): always nul terminate returned string.
-  
-  This fixes potential out-of-buffer access on "file:./" URL
-  
-  $ valgrind curl "file:./"
-  ==24516== Memcheck, a memory error detector
-  ==24516== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
-  ==24516== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
-  ==24516== Command: /home/even/install-curl-git/bin/curl file:./
-  ==24516==
-  ==24516== Conditional jump or move depends on uninitialised value(s)
-  ==24516==    at 0x4C31F9C: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
-  ==24516==    by 0x4EBB315: seturl (urlapi.c:801)
-  ==24516==    by 0x4EBB568: parseurl (urlapi.c:861)
-  ==24516==    by 0x4EBC509: curl_url_set (urlapi.c:1199)
-  ==24516==    by 0x4E644C6: parseurlandfillconn (url.c:2044)
-  ==24516==    by 0x4E67AEF: create_conn (url.c:3613)
-  ==24516==    by 0x4E68A4F: Curl_connect (url.c:4119)
-  ==24516==    by 0x4E7F0A4: multi_runsingle (multi.c:1440)
-  ==24516==    by 0x4E808E5: curl_multi_perform (multi.c:2173)
-  ==24516==    by 0x4E7558C: easy_transfer (easy.c:686)
-  ==24516==    by 0x4E75801: easy_perform (easy.c:779)
-  ==24516==    by 0x4E75868: curl_easy_perform (easy.c:798)
-  
-  Was originally spotted by
-  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10637
-  Credit to OSS-Fuzz
+  This could be converted to a bit for CURLOPT_SSL_OPTIONS to let
+  applications opt-in this.
   
-  Closes #3039
+  Concern-raised-by: David Benjamin
+  Fixes #3283
+  Closes #3293
 
-Viktor Szakats (23 Sep 2018)
-- update URLs in tests
-  
-  - and one in docs/MANUAL as well
-  
-  Closes https://github.com/curl/curl/pull/3038
+- [Romain Fliedel brought this change]
 
-- whitespace fixes
-  
-  - replace tabs with spaces where possible
-  - remove line ending spaces
-  - remove double/triple newlines at EOF
-  - fix a non-UTF-8 character
-  - cleanup a few indentations/line continuations
-    in manual examples
+  ares: remove fd from multi fd set when ares is about to close the fd
   
-  Closes https://github.com/curl/curl/pull/3037
-
-Daniel Stenberg (23 Sep 2018)
-- http: add missing return code check
+  When using c-ares for asyn dns, the dns socket fd was silently closed
+  by c-ares without curl being aware. curl would then 'realize' the fd
+  has been removed at next call of Curl_resolver_getsock, and only then
+  notify the CURLMOPT_SOCKETFUNCTION to remove fd from its poll set with
+  CURL_POLL_REMOVE. At this point the fd is already closed.
   
-  Detected by Coverity. CID 1439610.
+  By using ares socket state callback (ARES_OPT_SOCK_STATE_CB), this
+  patch allows curl to be notified that the fd is not longer needed
+  for neither for write nor read. At this point by calling
+  Curl_multi_closed we are able to notify multi with CURL_POLL_REMOVE
+  before the fd is actually closed by ares.
   
-  Follow-up from 46e164069d1a523
+  In asyn-ares.c Curl_resolver_duphandle we can't use ares_dup anymore
+  since it does not allow passing a different sock_state_cb_data
   
-  Closes #3034
+  Closes #3238
 
-- ftp: don't access pointer before NULL check
-  
-  Detected by Coverity. CID 1439611.
-  
-  Follow-up from 46e164069d1a523
+- [Romain Fliedel brought this change]
 
-- unit1650: fix out of boundary access
-  
-  Fixes #2987
-  Closes #3035
+  examples/ephiperfifo: report error when epoll_ctl fails
 
-Viktor Szakats (23 Sep 2018)
-- docs/examples: URL updates
-  
-  - also update two URLs outside of docs/examples
-  - fix spelling of filename persistant.c
-  - fix three long lines that started failing checksrc.pl
-  
-  Closes https://github.com/curl/curl/pull/3036
+Daniel Gustafsson (20 Nov 2018)
+- [pkubaj brought this change]
 
-- examples/Makefile.m32: sync with core [ci skip]
+  ntlm: Remove redundant ifdef USE_OPENSSL
   
-  also:
-  - fix two warnings in synctime.c (one of them Windows-specific)
-  - upgrade URLs in synctime.c and remove a broken one
+  lib/curl_ntlm.c had code that read as follows:
   
-  Closes https://github.com/curl/curl/pull/3033
-
-Daniel Stenberg (22 Sep 2018)
-- examples/parseurl.c: show off the URL API a bit
+    #ifdef USE_OPENSSL
+    # ifdef USE_OPENSSL
+    # else
+    # ..
+    # endif
+    #endif
   
-  Closes #3030
-
-- SECURITY-PROCESS: mention the bountygraph program [ci skip]
+  Remove the redundant USE_OPENSSL along with #else (it's not possible to
+  reach it anyway). The removed construction is a leftover from when the
+  SSLeay support was removed.
   
-  Closes #3032
+  Closes #3269
+  Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-- url: use the URL API internally as well
-  
-  ... to make it a truly unified URL parser.
-  
-  Closes #3017
+Daniel Stenberg (20 Nov 2018)
+- [Han Han brought this change]
 
-Viktor Szakats (22 Sep 2018)
-- URL and mailmap updates, remove an obsolete directory [ci skip]
+  ssl: replace all internal uses of CURLE_SSL_CACERT
   
-  Closes https://github.com/curl/curl/pull/3031
+  Closes #3291
 
-Daniel Stenberg (22 Sep 2018)
-- RELEASE-NOTES: synced
+Han Han (19 Nov 2018)
+- docs: add more description to unified ssl error codes
 
-- configure: force-use -lpthreads on HPUX
-  
-  When trying to detect pthreads use on HPUX the checks will succeed
-  without the correct -l option but then end up failing at run-time.
-  
-  Reported-by: Eason-Yu on github
-  Fixes #2697
-  Closes #3025
+- curle: move deprecated error code to ifndef block
 
-- [Erik Minekus brought this change]
+Patrick Monnerat (19 Nov 2018)
+- os400: add CURLOPT_CURLU to ILE/RPG binding.
 
-  Curl_saferealloc: Fixed typo in docblock
-  
-  Closes #3029
+- os400: Add curl_easy_conn_upkeep() to ILE/RPG binding.
 
-- urlapi: fix support for address scope in IPv6 numerical addresses
-  
-  Closes #3024
+- os400: fix return type of curl_easy_pause() in ILE/RPG binding.
 
-- [Loganaden Velvindron brought this change]
+Daniel Stenberg (19 Nov 2018)
+- RELEASE-NOTES: synced
 
-  GnutTLS: TLS 1.3 support
+- impacket: add LICENSE
   
-  Closes #2971
-
-- TODO: c-ares and CURLOPT_OPENSOCKETFUNCTION
+  The license for the impacket package was not in our tree.
   
-  Removed DoH.
+  Imported now from upstream's
+  https://github.com/SecureAuthCorp/impacket/blob/master/LICENSE
   
-  Closes #2734
+  Reported-by: infinnovation-dev on github
+  Fixes #3276
+  Closes #3277
 
-Jay Satiro (20 Sep 2018)
-- vtls: fix ssl version "or later" behavior change for many backends
+Daniel Gustafsson (18 Nov 2018)
+- tool_doswin: Fix uninitialized field warning
   
-  - Treat CURL_SSLVERSION_MAX_NONE the same as
-    CURL_SSLVERSION_MAX_DEFAULT. Prior to this change NONE would mean use
-    the minimum version also as the maximum.
+  The partial struct initialization in 397664a065abffb7c3445ca9 caused
+  a warning on uninitialized MODULEENTRY32 struct members:
   
-  This is a follow-up to 6015cef which changed the behavior of setting
-  the SSL version so that the requested version would only be the minimum
-  and not the maximum. It appears it was (mostly) implemented in OpenSSL
-  but not other backends. In other words CURL_SSLVERSION_TLSv1_0 used to
-  mean use just TLS v1.0 and now it means use TLS v1.0 *or later*.
+    /src/tool_doswin.c:681:3: warning: missing initializer for field
+    'th32ModuleID' of 'MODULEENTRY32 {aka struct tagMODULEENTRY32}'
+    [-Wmissing-field-initializers]
   
-  - Fix CURL_SSLVERSION_MAX_DEFAULT for OpenSSL.
+  This is sort of a bogus warning as the remaining members will be set
+  to zero by the compiler, as all omitted members are. Nevertheless,
+  remove the warning by omitting all members and setting the dwSize
+  members explicitly.
   
-  Prior to this change CURL_SSLVERSION_MAX_DEFAULT with OpenSSL was
-  erroneously treated as always TLS 1.3, and would cause an error if
-  OpenSSL was built without TLS 1.3 support.
+  Closes #3254
+  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  Reviewed-by: Jay Satiro <raysatiro@yahoo.com>
+
+- openssl: Remove SSLEAY leftovers
   
-  Co-authored-by: Daniel Gustafsson
+  Commit 709cf76f6bb7dbac deprecated USE_SSLEAY, as curl since long isn't
+  compatible with the SSLeay library. This removes the few leftovers that
+  were omitted in the less frequently used platform targets.
   
-  Fixes https://github.com/curl/curl/issues/2969
-  Closes https://github.com/curl/curl/pull/3012
+  Closes #3270
+  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
 
-Daniel Stenberg (20 Sep 2018)
-- certs: generate tests certs with sha256 digest algorithm
-  
-  As OpenSSL 1.1.1 starts to complain and fail on sha1 CAs:
+Daniel Stenberg (16 Nov 2018)
+- [Elia Tufarolo brought this change]
+
+  http_negotiate: do not close connection until negotiation is completed
   
-  "SSL certificate problem: CA signature digest algorithm too weak"
+  Fix HTTP POST using CURLAUTH_NEGOTIATE.
   
-  Closes #3014
+  Closes #3275
 
-- urlapi: document the error codes, remove two unused ones
+- pop3: only do APOP with a valid timestamp
   
-  Assisted-by: Daniel Gustafsson
-  Closes #3019
+  Brought-by: bobmitchell1956 on github
+  Fixes #3278
+  Closes #3279
+
+Jay Satiro (16 Nov 2018)
+- [Peter Wu brought this change]
 
-- urlapi: add CURLU_GUESS_SCHEME and fix hostname acceptance
+  openssl: do not log excess "TLS app data" lines for TLS 1.3
   
-  In order for this API to fully work for libcurl itself, it now offers a
-  CURLU_GUESS_SCHEME flag that makes it "guess" scheme based on the host
-  name prefix just like libcurl always did. If there's no known prefix, it
-  will guess "http://".
+  The SSL_CTX_set_msg_callback callback is not just called for the
+  Handshake or Alert protocols, but also for the raw record header
+  (SSL3_RT_HEADER) and the decrypted inner record type
+  (SSL3_RT_INNER_CONTENT_TYPE). Be sure to ignore the latter to avoid
+  excess debug spam when using `curl -v` against a TLSv1.3-enabled server:
   
-  Separately, it relaxes the check of the host name so that IDN host names
-  can be passed in as well.
+      * TLSv1.3 (IN), TLS app data, [no content] (0):
   
-  Both these changes are necessary for libcurl itself to use this API.
+  (Following this message, another callback for the decrypted
+  handshake/alert messages will be be present anyway.)
   
-  Assisted-by: Daniel Gustafsson
-  Closes #3018
+  Closes https://github.com/curl/curl/pull/3281
 
-Kamil Dudka (19 Sep 2018)
-- nss: try to connect even if libnssckbi.so fails to load
-  
-  One can still use CA certificates stored in NSS database.
+Marc Hoersken (15 Nov 2018)
+- tests: disable SO_EXCLUSIVEADDRUSE for stunnel on Windows
   
-  Reported-by: Maxime Legros
-  Bug: https://curl.haxx.se/mail/lib-2018-09/0077.html
+  SO_EXCLUSIVEADDRUSE is on by default on Vista or newer,
+  but does not work together with SO_REUSEADDR being on.
   
-  Closes #3016
+  The default changes were made with stunnel 5.34 and 5.35.
+
+Daniel Stenberg (13 Nov 2018)
+- [Kamil Dudka brought this change]
 
-Daniel Gustafsson (19 Sep 2018)
-- urlapi: don't set value which is never read
+  nss: remove version selecting dead code
   
-  In the CURLUPART_URL case, there is no codepath which invokes url
-  decoding so remove the assignment of the urldecode variable. This
-  fixes the deadstore bug-report from clang static analysis.
+  Closes #3262
+
+- nss: set default max-tls to 1.3/1.2
   
-  Closes #3015
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Fixes #3261
 
-- todo: Update reference to already done item
+Daniel Gustafsson (13 Nov 2018)
+- tool_cb_wrt: Silence function cast compiler warning
+  
+  Commit 5bfaa86ceb3c2a9ac474a928e748c4a86a703b33 introduced a new
+  compiler warning on Windows cross compilation with GCC. See below
+  for an example of the warning from the autobuild logs (whitespace
+  edited to fit):
   
-  TODO item 1.1 was implemented in commit 946ce5b61f, update reference
-  to it with instead referencing the implemented option.
+  /src/tool_cb_wrt.c:175:9: warning: cast from function call of type
+      'intptr_t {aka long long int}' to non-matching type 'void *'
+      [-Wbad-function-cast]
+  (HANDLE) _get_osfhandle(fileno(outs->stream)),
+  ^
   
-  Closes #3013
-  Reviewed-by: Daniel Stenberg <daniel@haxx.se>
+  Store the return value from _get_osfhandle() in an intermediate
+  variable and cast the variable in WriteConsoleW() rather than the
+  function call directly to avoid a compiler warning.
+  
+  In passing, also add inspection of the MultiByteToWideChar() return
+  value and return failure in case an error is reported.
+  
+  Closes #3263
+  Reviewed-by: Marcel Raad <Marcel.Raad@teamviewer.com>
+  Reviewed-by: Viktor Szakats <commit@vszakats.net>
 
-Daniel Stenberg (18 Sep 2018)
-- RELEASE-NOTES: synced
+Daniel Stenberg (12 Nov 2018)
+- nss: fix fallthrough comment to fix picky compiler warning
 
-- [slodki brought this change]
+- docs: expanded on some CURLU details
 
-  cmake: don't require OpenSSL if USE_OPENSSL=OFF
-  
-  User must have OpenSSL installed even if not used by libcurl at all
-  since 7.61.1 release.  Broken at
-  7867aaa9a01decf93711428462335be8cef70212
-  
-  Reviewed-by: Sergei Nikulov
-  Closes #3001
+- [Tim Rühsen brought this change]
 
-- curl_multi_wait: call getsock before figuring out timeout
+  ftp: avoid two unsigned int overflows in FTP listing parser
   
-  .... since getsock may update the expiry timer.
+  Curl_ftp_parselist: avoid unsigned integer overflows
   
-  Fixes #2996
-  Closes #3000
-
-- examples/http2-pushinmemory: receive HTTP/2 pushed files in memory
+  The overflow has no real world impact, just avoid it for "best
+  practice".
   
-  Closes #3004
+  Closes #3225
diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS
index 385ecd8518..73b84cfdb3 100644
--- a/libs/libcurl/docs/THANKS
+++ b/libs/libcurl/docs/THANKS
@@ -52,6 +52,7 @@ Alex Fishman
 Alex Grebenschikov
 Alex Gruz
 Alex Malinovich
+Alex Mayorga
 Alex McLellan
 Alex Neblett
 Alex Nichols
@@ -84,6 +85,7 @@ Alfonso Martone
 Alfred Gebert
 Allen Pulsifer
 Alona Rossen
+Amit Katyal
 Amol Pattekar
 Amr Shahin
 Anatol Belski
@@ -172,6 +174,7 @@ Ayoub Boudhar
 Balaji Parasuram
 Balaji S Rao
 Balaji Salunke
+Balazs Kovacsics
 Balint Szilakszi
 Barry Abrahamson
 Bart Whiteley
@@ -230,6 +233,7 @@ Brad King
 Brad Spencer
 Bradford Bruce
 Brandon Casey
+Brandon Dong
 Brandon Wang
 Brendan Jurd
 Brent Beardsley
@@ -261,6 +265,7 @@ Camille Moncelier
 Caolan McNamara
 Carie Pointer
 Carlo Cannas
+Carlo Marcelo Arenas Belón
 Carlo Teubner
 Carlo Wood
 Carlos ORyan
@@ -315,6 +320,7 @@ Clemens Gruber
 Cliff Crosland
 Clifford Wolf
 Clint Clayton
+Clément Notin
 Cody Jones
 Cody Mack
 Colby Ranger
@@ -714,6 +720,7 @@ Ian Wilkes
 Ignacio Vazquez-Abrams
 Igor Franchuk
 Igor Khristophorov
+Igor Makarov
 Igor Novoseltsev
 Igor Polyakov
 Ihor Karpenko
@@ -726,6 +733,7 @@ Ingmar Runge
 Ingo Ralf Blum
 Ingo Wilken
 Irfan Adilovic
+Ironbars13 on github
 Irving Wolfe
 Isaac Boukris
 Isaiah Norton
@@ -775,6 +783,7 @@ Jari Sundell
 Jason Baietto
 Jason Glasgow
 Jason Juang
+Jason Lee
 Jason Liu
 Jason McDonald
 Jason S. Priebe
@@ -809,6 +818,7 @@ Jens Schleusener
 Jeremie Rapin
 Jeremy Friesner
 Jeremy Huddleston
+Jeremy Lainé
 Jeremy Lin
 Jeremy Pearson
 Jeremy Tan
@@ -929,6 +939,7 @@ Julien Chaffraix
 Julien Nabet
 Julien Royer
 Jun-ichiro itojun Hagino
+Junho Choi
 Jurij Smakov
 Juro Bystricky
 Justin Clift
@@ -996,13 +1007,16 @@ Kristiyan Tsaklev
 Kristoffer Gleditsch
 Kunal Ekawde
 Kurt Fankhauser
+Kyle Abramowitz
 Kyle Edwards
 Kyle J. McKay
 Kyle L. Huff
 Kyle Sallee
+Kyohei Kadota
 Kyselgov E.N
 Lachlan O'Dea
 Ladar Levison
+Lance Ware
 Larry Campbell
 Larry Fahnoe
 Larry Lin
@@ -1207,6 +1221,7 @@ Michael Kaufmann
 Michael Kilburn
 Michael Kujawa
 Michael König
+Michael Lee
 Michael Maltese
 Michael Mealling
 Michael Mueller
@@ -1220,6 +1235,7 @@ Michael Wallner
 Michal Bonino
 Michal Marek
 Michal Trybus
+Michal Čaplygin
 Michał Antoniak
 Michał Fita
 Michał Górny
@@ -1549,6 +1565,7 @@ Roger Leigh
 Roland Blom
 Roland Krikava
 Roland Zimmermann
+Rolf Eike Beer
 Rolland Dudemaine
 Romain Coltel
 Romain Fliedel
@@ -1682,7 +1699,6 @@ Stephen Kick
 Stephen More
 Stephen Toub
 Sterling Hughes
-Steve Brokenshire
 Steve Green
 Steve H Truong
 Steve Havelka
@@ -1723,6 +1739,7 @@ Teemu Yli-Elsila
 Temprimus
 Terri Oda
 Terry Wu
+The Infinnovation team
 TheAssassin on github
 Theodore Dubois
 Thomas Braun
@@ -1736,6 +1753,7 @@ Thomas Petazzoni
 Thomas Ruecker
 Thomas Schwinge
 Thomas Tonino
+Thomas Vegas
 Thomas van Hesteren
 Thorsten Schöning
 Tiit Pikma
@@ -1921,6 +1939,7 @@ cbartl on github
 cclauss on github
 clbr on github
 cmfrolick on github
+codesniffer13 on github
 d912e3 on github
 daboul on github
 dasimx on github
@@ -1956,20 +1975,24 @@ madblobfish on github
 marc-groundctl on github
 masbug on github
 mccormickt12 on github
+migueljcrum on github
 mkzero on github
 moohoorama on github
 nedres on github
 neex on github
 neheb on github
 nevv on HackerOne/curl
+niallor on github
 nianxuejie on github
 niner on github
 nk
 nopjmp on github
 olesteban on github
 omau on github
+osabc on github
 ovidiu-benea on github
 patelvivekv1993 on github
+patnyb on github
 pendrek at hackerone
 pszemus on github
 silveja1 on github
diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h
index 19f6c0b5a1..ff0c774962 100644
--- a/libs/libcurl/include/curl/curl.h
+++ b/libs/libcurl/include/curl/curl.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_CURL_H
-#define __CURL_CURL_H
+#ifndef CURLINC_CURL_H
+#define CURLINC_CURL_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -284,10 +284,7 @@ typedef enum {
 #define CURLFINFOFLAG_KNOWN_SIZE        (1<<6)
 #define CURLFINFOFLAG_KNOWN_HLINKCOUNT  (1<<7)
 
-/* Content of this structure depends on information which is known and is
-   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
-   page for callbacks returning this structure -- some fields are mandatory,
-   some others are optional. The FLAG field has special meaning. */
+/* Information about a single file, used when doing FTP wildcard matching */
 struct curl_fileinfo {
   char *filename;
   curlfiletype filetype;
@@ -603,6 +600,8 @@ typedef enum {
                                     */
   CURLE_RECURSIVE_API_CALL,      /* 93 - an api function was called from
                                     inside a callback */
+  CURLE_AUTH_ERROR,              /* 94 - an authentication function returned an
+                                    error */
   CURL_LAST /* never use! */
 } CURLcode;
 
@@ -886,7 +885,7 @@ typedef enum {
 
 /* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
 #define CURLALTSVC_IMMEDIATELY  (1<<0)
-#define CURLALTSVC_ALTUSED      (1<<1)
+
 #define CURLALTSVC_READONLYFILE (1<<2)
 #define CURLALTSVC_H1           (1<<3)
 #define CURLALTSVC_H2           (1<<4)
@@ -1925,6 +1924,9 @@ typedef enum {
   /* maximum age of a connection to consider it for reuse (in seconds) */
   CINIT(MAXAGE_CONN, LONG, 288),
 
+  /* SASL authorisation identity */
+  CINIT(SASL_AUTHZID, STRINGPOINT, 289),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
@@ -1978,7 +1980,8 @@ enum {
   CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
   CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE,  /* please use HTTP 2 without HTTP/1.1
                                            Upgrade */
-
+  CURL_HTTP_VERSION_3 = 30, /* Makes use of explicit HTTP/3 without fallback.
+                               Use CURLOPT_ALTSVC to enable HTTP/3 upgrade */
   CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
 };
 
@@ -2614,8 +2617,9 @@ typedef enum {
   CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
   CURLINFO_REDIRECT_TIME_T  = CURLINFO_OFF_T + 55,
   CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
+  CURLINFO_RETRY_AFTER      = CURLINFO_OFF_T + 57,
 
-  CURLINFO_LASTONE          = 56
+  CURLINFO_LASTONE          = 57
 } CURLINFO;
 
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@@ -2714,6 +2718,7 @@ typedef enum {
   CURLVERSION_THIRD,
   CURLVERSION_FOURTH,
   CURLVERSION_FIFTH,
+  CURLVERSION_SIXTH,
   CURLVERSION_LAST /* never actually use this */
 } CURLversion;
 
@@ -2722,7 +2727,7 @@ typedef enum {
    meant to be a built-in version number for what kind of struct the caller
    expects. If the struct ever changes, we redefine the NOW to another enum
    from above. */
-#define CURLVERSION_NOW CURLVERSION_FIFTH
+#define CURLVERSION_NOW CURLVERSION_SIXTH
 
 typedef struct {
   CURLversion age;          /* age of the returned struct */
@@ -2751,11 +2756,16 @@ typedef struct {
   const char *libssh_version; /* human readable string */
 
   /* These fields were added in CURLVERSION_FIFTH */
-
   unsigned int brotli_ver_num; /* Numeric Brotli version
                                   (MAJOR << 24) | (MINOR << 12) | PATCH */
   const char *brotli_version; /* human readable string. */
 
+  /* These fields were added in CURLVERSION_SIXTH */
+  unsigned int nghttp2_ver_num; /* Numeric nghttp2 version
+                                   (MAJOR << 16) | (MINOR << 8) | PATCH */
+  const char *nghttp2_version; /* human readable string. */
+  const char *quic_version;    /* human readable quic (+ HTTP/3) library +
+                                  version or NULL */
 } curl_version_info_data;
 
 #define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
@@ -2788,6 +2798,7 @@ typedef struct {
 #define CURL_VERSION_MULTI_SSL    (1<<22) /* Multiple SSL backends available */
 #define CURL_VERSION_BROTLI       (1<<23) /* Brotli features are present. */
 #define CURL_VERSION_ALTSVC       (1<<24) /* Alt-Svc handling built-in */
+#define CURL_VERSION_HTTP3        (1<<25) /* HTTP3 support built-in */
 
  /*
  * NAME curl_version_info()
@@ -2868,4 +2879,4 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
 #endif /* __STDC__ >= 1 */
 #endif /* gcc >= 4.3 && !__cplusplus */
 
-#endif /* __CURL_CURL_H */
+#endif /* CURLINC_CURL_H */
diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h
index 3e8789e86b..f537b9205e 100644
--- a/libs/libcurl/include/curl/curlver.h
+++ b/libs/libcurl/include/curl/curlver.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_CURLVER_H
-#define __CURL_CURLVER_H
+#ifndef CURLINC_CURLVER_H
+#define CURLINC_CURLVER_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -30,13 +30,13 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.65.3"
+#define LIBCURL_VERSION "7.66.0"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 65
-#define LIBCURL_VERSION_PATCH 3
+#define LIBCURL_VERSION_MINOR 66
+#define LIBCURL_VERSION_PATCH 0
 
 /* This is the numeric version of the libcurl version number, meant for easier
    parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -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 0x074103
+#define LIBCURL_VERSION_NUM 0x074200
 
 /*
  * This is the date and time when the full source package was created. The
@@ -68,10 +68,10 @@
  *
  * "2007-11-23"
  */
-#define LIBCURL_TIMESTAMP "2019-07-19"
+#define LIBCURL_TIMESTAMP "2019-09-11"
 
 #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
 #define CURL_AT_LEAST_VERSION(x,y,z) \
   (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
 
-#endif /* __CURL_CURLVER_H */
+#endif /* CURLINC_CURLVER_H */
diff --git a/libs/libcurl/include/curl/easy.h b/libs/libcurl/include/curl/easy.h
index f42a8a9692..592f5d3c1c 100644
--- a/libs/libcurl/include/curl/easy.h
+++ b/libs/libcurl/include/curl/easy.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_EASY_H
-#define __CURL_EASY_H
+#ifndef CURLINC_EASY_H
+#define CURLINC_EASY_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/libs/libcurl/include/curl/mprintf.h b/libs/libcurl/include/curl/mprintf.h
index e20f546e19..f615ed7d63 100644
--- a/libs/libcurl/include/curl/mprintf.h
+++ b/libs/libcurl/include/curl/mprintf.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_MPRINTF_H
-#define __CURL_MPRINTF_H
+#ifndef CURLINC_MPRINTF_H
+#define CURLINC_MPRINTF_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,4 +47,4 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
 }
 #endif
 
-#endif /* __CURL_MPRINTF_H */
+#endif /* CURLINC_MPRINTF_H */
diff --git a/libs/libcurl/include/curl/multi.h b/libs/libcurl/include/curl/multi.h
index b19dbaf791..02df0f3893 100644
--- a/libs/libcurl/include/curl/multi.h
+++ b/libs/libcurl/include/curl/multi.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_MULTI_H
-#define __CURL_MULTI_H
+#ifndef CURLINC_MULTI_H
+#define CURLINC_MULTI_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -173,6 +173,20 @@ CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
                                       int timeout_ms,
                                       int *ret);
 
+/*
+ * Name:     curl_multi_poll()
+ *
+ * Desc:     Poll on all fds within a CURLM set as well as any
+ *           additional fds passed to the function.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
+                                      struct curl_waitfd extra_fds[],
+                                      unsigned int extra_nfds,
+                                      int timeout_ms,
+                                      int *ret);
+
  /*
   * Name:    curl_multi_perform()
   *
diff --git a/libs/libcurl/include/curl/stdcheaders.h b/libs/libcurl/include/curl/stdcheaders.h
index 027b6f4211..a6bdc1a25c 100644
--- a/libs/libcurl/include/curl/stdcheaders.h
+++ b/libs/libcurl/include/curl/stdcheaders.h
@@ -1,5 +1,5 @@
-#ifndef __STDC_HEADERS_H
-#define __STDC_HEADERS_H
+#ifndef CURLINC_STDCHEADERS_H
+#define CURLINC_STDCHEADERS_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,4 +30,4 @@ size_t fwrite(const void *, size_t, size_t, FILE *);
 int strcasecmp(const char *, const char *);
 int strncasecmp(const char *, const char *, size_t);
 
-#endif /* __STDC_HEADERS_H */
+#endif /* CURLINC_STDCHEADERS_H */
diff --git a/libs/libcurl/include/curl/system.h b/libs/libcurl/include/curl/system.h
index 1e555ec19e..cd37c2bf54 100644
--- a/libs/libcurl/include/curl/system.h
+++ b/libs/libcurl/include/curl/system.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_SYSTEM_H
-#define __CURL_SYSTEM_H
+#ifndef CURLINC_SYSTEM_H
+#define CURLINC_SYSTEM_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -473,21 +473,21 @@
  */
 
 #if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
-#  define __CURL_OFF_T_C_HLPR2(x) x
-#  define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
-#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val) ## \
-                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
-#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
-                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#  define CURLINC_OFF_T_C_HLPR2(x) x
+#  define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
+#  define CURL_OFF_T_C(Val)  CURLINC_OFF_T_C_HLPR1(Val) ## \
+                             CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
+                             CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
 #else
 #  ifdef CURL_ISOCPP
-#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+#    define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
 #  else
-#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+#    define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
 #  endif
-#  define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
-#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
-#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#  define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
+#  define CURL_OFF_T_C(Val)  CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
 #endif
 
-#endif /* __CURL_SYSTEM_H */
+#endif /* CURLINC_SYSTEM_H */
diff --git a/libs/libcurl/include/curl/typecheck-gcc.h b/libs/libcurl/include/curl/typecheck-gcc.h
index eeb36abc09..03c84fc85b 100644
--- a/libs/libcurl/include/curl/typecheck-gcc.h
+++ b/libs/libcurl/include/curl/typecheck-gcc.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_TYPECHECK_GCC_H
-#define __CURL_TYPECHECK_GCC_H
+#ifndef CURLINC_TYPECHECK_GCC_H
+#define CURLINC_TYPECHECK_GCC_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -25,10 +25,10 @@
 /* wraps curl_easy_setopt() with typechecking */
 
 /* To add a new kind of warning, add an
- *   if(_curl_is_sometype_option(_curl_opt))
- *     if(!_curl_is_sometype(value))
+ *   if(curlcheck_sometype_option(_curl_opt))
+ *     if(!curlcheck_sometype(value))
  *       _curl_easy_setopt_err_sometype();
- * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * block and define curlcheck_sometype_option, curlcheck_sometype and
  * _curl_easy_setopt_err_sometype below
  *
  * NOTE: We use two nested 'if' statements here instead of the && operator, in
@@ -38,112 +38,112 @@
  * To add an option that uses the same type as an existing option, you'll just
  * need to extend the appropriate _curl_*_option macro
  */
-#define curl_easy_setopt(handle, option, value)                               \
-__extension__ ({                                                              \
-  __typeof__(option) _curl_opt = option;                                     \
-  if(__builtin_constant_p(_curl_opt)) {                                       \
-    if(_curl_is_long_option(_curl_opt))                                       \
-      if(!_curl_is_long(value))                                               \
-        _curl_easy_setopt_err_long();                                         \
-    if(_curl_is_off_t_option(_curl_opt))                                      \
-      if(!_curl_is_off_t(value))                                              \
-        _curl_easy_setopt_err_curl_off_t();                                   \
-    if(_curl_is_string_option(_curl_opt))                                     \
-      if(!_curl_is_string(value))                                             \
-        _curl_easy_setopt_err_string();                                       \
-    if(_curl_is_write_cb_option(_curl_opt))                                   \
-      if(!_curl_is_write_cb(value))                                           \
-        _curl_easy_setopt_err_write_callback();                               \
-    if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION)                        \
-      if(!_curl_is_resolver_start_callback(value))                            \
-        _curl_easy_setopt_err_resolver_start_callback();                      \
-    if((_curl_opt) == CURLOPT_READFUNCTION)                                   \
-      if(!_curl_is_read_cb(value))                                            \
-        _curl_easy_setopt_err_read_cb();                                      \
-    if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                                  \
-      if(!_curl_is_ioctl_cb(value))                                           \
-        _curl_easy_setopt_err_ioctl_cb();                                     \
-    if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                                \
-      if(!_curl_is_sockopt_cb(value))                                         \
-        _curl_easy_setopt_err_sockopt_cb();                                   \
-    if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                             \
-      if(!_curl_is_opensocket_cb(value))                                      \
-        _curl_easy_setopt_err_opensocket_cb();                                \
-    if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                               \
-      if(!_curl_is_progress_cb(value))                                        \
-        _curl_easy_setopt_err_progress_cb();                                  \
-    if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                                  \
-      if(!_curl_is_debug_cb(value))                                           \
-        _curl_easy_setopt_err_debug_cb();                                     \
-    if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                               \
-      if(!_curl_is_ssl_ctx_cb(value))                                         \
-        _curl_easy_setopt_err_ssl_ctx_cb();                                   \
-    if(_curl_is_conv_cb_option(_curl_opt))                                    \
-      if(!_curl_is_conv_cb(value))                                            \
-        _curl_easy_setopt_err_conv_cb();                                      \
-    if((_curl_opt) == CURLOPT_SEEKFUNCTION)                                   \
-      if(!_curl_is_seek_cb(value))                                            \
-        _curl_easy_setopt_err_seek_cb();                                      \
-    if(_curl_is_cb_data_option(_curl_opt))                                    \
-      if(!_curl_is_cb_data(value))                                            \
-        _curl_easy_setopt_err_cb_data();                                      \
-    if((_curl_opt) == CURLOPT_ERRORBUFFER)                                    \
-      if(!_curl_is_error_buffer(value))                                       \
-        _curl_easy_setopt_err_error_buffer();                                 \
-    if((_curl_opt) == CURLOPT_STDERR)                                         \
-      if(!_curl_is_FILE(value))                                               \
-        _curl_easy_setopt_err_FILE();                                         \
-    if(_curl_is_postfields_option(_curl_opt))                                 \
-      if(!_curl_is_postfields(value))                                         \
-        _curl_easy_setopt_err_postfields();                                   \
-    if((_curl_opt) == CURLOPT_HTTPPOST)                                       \
-      if(!_curl_is_arr((value), struct curl_httppost))                        \
-        _curl_easy_setopt_err_curl_httpost();                                 \
-    if((_curl_opt) == CURLOPT_MIMEPOST)                                       \
-      if(!_curl_is_ptr((value), curl_mime))                                   \
-        _curl_easy_setopt_err_curl_mimepost();                                \
-    if(_curl_is_slist_option(_curl_opt))                                      \
-      if(!_curl_is_arr((value), struct curl_slist))                           \
-        _curl_easy_setopt_err_curl_slist();                                   \
-    if((_curl_opt) == CURLOPT_SHARE)                                          \
-      if(!_curl_is_ptr((value), CURLSH))                                      \
-        _curl_easy_setopt_err_CURLSH();                                       \
-  }                                                                           \
-  curl_easy_setopt(handle, _curl_opt, value);                                 \
-})
+#define curl_easy_setopt(handle, option, value)                         \
+  __extension__({                                                       \
+      __typeof__(option) _curl_opt = option;                            \
+      if(__builtin_constant_p(_curl_opt)) {                             \
+        if(curlcheck_long_option(_curl_opt))                            \
+          if(!curlcheck_long(value))                                    \
+            _curl_easy_setopt_err_long();                               \
+        if(curlcheck_off_t_option(_curl_opt))                           \
+          if(!curlcheck_off_t(value))                                   \
+            _curl_easy_setopt_err_curl_off_t();                         \
+        if(curlcheck_string_option(_curl_opt))                          \
+          if(!curlcheck_string(value))                                  \
+            _curl_easy_setopt_err_string();                             \
+        if(curlcheck_write_cb_option(_curl_opt))                        \
+          if(!curlcheck_write_cb(value))                                \
+            _curl_easy_setopt_err_write_callback();                     \
+        if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION)              \
+          if(!curlcheck_resolver_start_callback(value))                 \
+            _curl_easy_setopt_err_resolver_start_callback();            \
+        if((_curl_opt) == CURLOPT_READFUNCTION)                         \
+          if(!curlcheck_read_cb(value))                                 \
+            _curl_easy_setopt_err_read_cb();                            \
+        if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                        \
+          if(!curlcheck_ioctl_cb(value))                                \
+            _curl_easy_setopt_err_ioctl_cb();                           \
+        if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                      \
+          if(!curlcheck_sockopt_cb(value))                              \
+            _curl_easy_setopt_err_sockopt_cb();                         \
+        if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                   \
+          if(!curlcheck_opensocket_cb(value))                           \
+            _curl_easy_setopt_err_opensocket_cb();                      \
+        if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                     \
+          if(!curlcheck_progress_cb(value))                             \
+            _curl_easy_setopt_err_progress_cb();                        \
+        if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                        \
+          if(!curlcheck_debug_cb(value))                                \
+            _curl_easy_setopt_err_debug_cb();                           \
+        if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                     \
+          if(!curlcheck_ssl_ctx_cb(value))                              \
+            _curl_easy_setopt_err_ssl_ctx_cb();                         \
+        if(curlcheck_conv_cb_option(_curl_opt))                         \
+          if(!curlcheck_conv_cb(value))                                 \
+            _curl_easy_setopt_err_conv_cb();                            \
+        if((_curl_opt) == CURLOPT_SEEKFUNCTION)                         \
+          if(!curlcheck_seek_cb(value))                                 \
+            _curl_easy_setopt_err_seek_cb();                            \
+        if(curlcheck_cb_data_option(_curl_opt))                         \
+          if(!curlcheck_cb_data(value))                                 \
+            _curl_easy_setopt_err_cb_data();                            \
+        if((_curl_opt) == CURLOPT_ERRORBUFFER)                          \
+          if(!curlcheck_error_buffer(value))                            \
+            _curl_easy_setopt_err_error_buffer();                       \
+        if((_curl_opt) == CURLOPT_STDERR)                               \
+          if(!curlcheck_FILE(value))                                    \
+            _curl_easy_setopt_err_FILE();                               \
+        if(curlcheck_postfields_option(_curl_opt))                      \
+          if(!curlcheck_postfields(value))                              \
+            _curl_easy_setopt_err_postfields();                         \
+        if((_curl_opt) == CURLOPT_HTTPPOST)                             \
+          if(!curlcheck_arr((value), struct curl_httppost))             \
+            _curl_easy_setopt_err_curl_httpost();                       \
+        if((_curl_opt) == CURLOPT_MIMEPOST)                             \
+          if(!curlcheck_ptr((value), curl_mime))                        \
+            _curl_easy_setopt_err_curl_mimepost();                      \
+        if(curlcheck_slist_option(_curl_opt))                           \
+          if(!curlcheck_arr((value), struct curl_slist))                \
+            _curl_easy_setopt_err_curl_slist();                         \
+        if((_curl_opt) == CURLOPT_SHARE)                                \
+          if(!curlcheck_ptr((value), CURLSH))                           \
+            _curl_easy_setopt_err_CURLSH();                             \
+      }                                                                 \
+      curl_easy_setopt(handle, _curl_opt, value);                       \
+    })
 
 /* wraps curl_easy_getinfo() with typechecking */
-#define curl_easy_getinfo(handle, info, arg)                                  \
-__extension__ ({                                                              \
-  __typeof__(info) _curl_info = info;                                         \
-  if(__builtin_constant_p(_curl_info)) {                                      \
-    if(_curl_is_string_info(_curl_info))                                      \
-      if(!_curl_is_arr((arg), char *))                                        \
-        _curl_easy_getinfo_err_string();                                      \
-    if(_curl_is_long_info(_curl_info))                                        \
-      if(!_curl_is_arr((arg), long))                                          \
-        _curl_easy_getinfo_err_long();                                        \
-    if(_curl_is_double_info(_curl_info))                                      \
-      if(!_curl_is_arr((arg), double))                                        \
-        _curl_easy_getinfo_err_double();                                      \
-    if(_curl_is_slist_info(_curl_info))                                       \
-      if(!_curl_is_arr((arg), struct curl_slist *))                           \
-        _curl_easy_getinfo_err_curl_slist();                                  \
-    if(_curl_is_tlssessioninfo_info(_curl_info))                              \
-      if(!_curl_is_arr((arg), struct curl_tlssessioninfo *))                  \
-        _curl_easy_getinfo_err_curl_tlssesssioninfo();                        \
-    if(_curl_is_certinfo_info(_curl_info))                                    \
-      if(!_curl_is_arr((arg), struct curl_certinfo *))                        \
-        _curl_easy_getinfo_err_curl_certinfo();                               \
-    if(_curl_is_socket_info(_curl_info))                                      \
-      if(!_curl_is_arr((arg), curl_socket_t))                                 \
-        _curl_easy_getinfo_err_curl_socket();                                 \
-    if(_curl_is_off_t_info(_curl_info))                                       \
-      if(!_curl_is_arr((arg), curl_off_t))                                    \
-        _curl_easy_getinfo_err_curl_off_t();                                  \
-  }                                                                           \
-  curl_easy_getinfo(handle, _curl_info, arg);                                 \
-})
+#define curl_easy_getinfo(handle, info, arg)                            \
+  __extension__({                                                      \
+      __typeof__(info) _curl_info = info;                               \
+      if(__builtin_constant_p(_curl_info)) {                            \
+        if(curlcheck_string_info(_curl_info))                           \
+          if(!curlcheck_arr((arg), char *))                             \
+            _curl_easy_getinfo_err_string();                            \
+        if(curlcheck_long_info(_curl_info))                             \
+          if(!curlcheck_arr((arg), long))                               \
+            _curl_easy_getinfo_err_long();                              \
+        if(curlcheck_double_info(_curl_info))                           \
+          if(!curlcheck_arr((arg), double))                             \
+            _curl_easy_getinfo_err_double();                            \
+        if(curlcheck_slist_info(_curl_info))                            \
+          if(!curlcheck_arr((arg), struct curl_slist *))                \
+            _curl_easy_getinfo_err_curl_slist();                        \
+        if(curlcheck_tlssessioninfo_info(_curl_info))                   \
+          if(!curlcheck_arr((arg), struct curl_tlssessioninfo *))       \
+            _curl_easy_getinfo_err_curl_tlssesssioninfo();              \
+        if(curlcheck_certinfo_info(_curl_info))                         \
+          if(!curlcheck_arr((arg), struct curl_certinfo *))             \
+            _curl_easy_getinfo_err_curl_certinfo();                     \
+        if(curlcheck_socket_info(_curl_info))                           \
+          if(!curlcheck_arr((arg), curl_socket_t))                      \
+            _curl_easy_getinfo_err_curl_socket();                       \
+        if(curlcheck_off_t_info(_curl_info))                            \
+          if(!curlcheck_arr((arg), curl_off_t))                         \
+            _curl_easy_getinfo_err_curl_off_t();                        \
+      }                                                                 \
+      curl_easy_getinfo(handle, _curl_info, arg);                       \
+    })
 
 /*
  * For now, just make sure that the functions are called with three arguments
@@ -156,83 +156,83 @@ __extension__ ({                                                              \
  * functions */
 
 /* To define a new warning, use _CURL_WARNING(identifier, "message") */
-#define _CURL_WARNING(id, message)                                            \
-  static void __attribute__((__warning__(message)))                           \
-  __attribute__((__unused__)) __attribute__((__noinline__))                   \
+#define CURLWARNING(id, message)                                        \
+  static void __attribute__((__warning__(message)))                     \
+  __attribute__((__unused__)) __attribute__((__noinline__))             \
   id(void) { __asm__(""); }
 
-_CURL_WARNING(_curl_easy_setopt_err_long,
+CURLWARNING(_curl_easy_setopt_err_long,
   "curl_easy_setopt expects a long argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+CURLWARNING(_curl_easy_setopt_err_curl_off_t,
   "curl_easy_setopt expects a curl_off_t argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_string,
+CURLWARNING(_curl_easy_setopt_err_string,
               "curl_easy_setopt expects a "
               "string ('char *' or char[]) argument for this option"
   )
-_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+CURLWARNING(_curl_easy_setopt_err_write_callback,
   "curl_easy_setopt expects a curl_write_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_resolver_start_callback,
+CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
               "curl_easy_setopt expects a "
               "curl_resolver_start_callback argument for this option"
   )
-_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+CURLWARNING(_curl_easy_setopt_err_read_cb,
   "curl_easy_setopt expects a curl_read_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
   "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
   "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
               "curl_easy_setopt expects a "
               "curl_opensocket_callback argument for this option"
   )
-_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+CURLWARNING(_curl_easy_setopt_err_progress_cb,
   "curl_easy_setopt expects a curl_progress_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+CURLWARNING(_curl_easy_setopt_err_debug_cb,
   "curl_easy_setopt expects a curl_debug_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
   "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+CURLWARNING(_curl_easy_setopt_err_conv_cb,
   "curl_easy_setopt expects a curl_conv_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+CURLWARNING(_curl_easy_setopt_err_seek_cb,
   "curl_easy_setopt expects a curl_seek_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+CURLWARNING(_curl_easy_setopt_err_cb_data,
               "curl_easy_setopt expects a "
               "private data pointer as argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+CURLWARNING(_curl_easy_setopt_err_error_buffer,
               "curl_easy_setopt expects a "
               "char buffer of CURL_ERROR_SIZE as argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_FILE,
+CURLWARNING(_curl_easy_setopt_err_FILE,
   "curl_easy_setopt expects a 'FILE *' argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_postfields,
+CURLWARNING(_curl_easy_setopt_err_postfields,
   "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+CURLWARNING(_curl_easy_setopt_err_curl_httpost,
               "curl_easy_setopt expects a 'struct curl_httppost *' "
               "argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost,
+CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
               "curl_easy_setopt expects a 'curl_mime *' "
               "argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+CURLWARNING(_curl_easy_setopt_err_curl_slist,
   "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+CURLWARNING(_curl_easy_setopt_err_CURLSH,
   "curl_easy_setopt expects a CURLSH* argument for this option")
 
-_CURL_WARNING(_curl_easy_getinfo_err_string,
+CURLWARNING(_curl_easy_getinfo_err_string,
   "curl_easy_getinfo expects a pointer to 'char *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_long,
+CURLWARNING(_curl_easy_getinfo_err_long,
   "curl_easy_getinfo expects a pointer to long for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_double,
+CURLWARNING(_curl_easy_getinfo_err_double,
   "curl_easy_getinfo expects a pointer to double for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+CURLWARNING(_curl_easy_getinfo_err_curl_slist,
   "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
+CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
               "curl_easy_getinfo expects a pointer to "
               "'struct curl_tlssessioninfo *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo,
+CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
               "curl_easy_getinfo expects a pointer to "
               "'struct curl_certinfo *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_socket,
+CURLWARNING(_curl_easy_getinfo_err_curl_socket,
   "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
+CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
   "curl_easy_getinfo expects a pointer to curl_off_t for this info")
 
 /* groups of curl_easy_setops options that take the same type of argument */
@@ -244,14 +244,14 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
  */
 
 /* evaluates to true if option takes a long argument */
-#define _curl_is_long_option(option)                                          \
+#define curlcheck_long_option(option)                   \
   (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
 
-#define _curl_is_off_t_option(option)                                         \
+#define curlcheck_off_t_option(option)          \
   ((option) > CURLOPTTYPE_OFF_T)
 
 /* evaluates to true if option takes a char* argument */
-#define _curl_is_string_option(option)                                        \
+#define curlcheck_string_option(option)                                       \
   ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                                \
    (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
    (option) == CURLOPT_ALTSVC ||                                              \
@@ -311,6 +311,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
    (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
    (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
+   (option) == CURLOPT_SASL_AUTHZID ||                                        \
    (option) == CURLOPT_SERVICE_NAME ||                                        \
    (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
    (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
@@ -336,18 +337,18 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
    0)
 
 /* evaluates to true if option takes a curl_write_callback argument */
-#define _curl_is_write_cb_option(option)                                      \
-  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+#define curlcheck_write_cb_option(option)                               \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                \
    (option) == CURLOPT_WRITEFUNCTION)
 
 /* evaluates to true if option takes a curl_conv_callback argument */
-#define _curl_is_conv_cb_option(option)                                       \
-  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
-   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+#define curlcheck_conv_cb_option(option)                                \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                      \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                    \
    (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
 
 /* evaluates to true if option takes a data argument to pass to a callback */
-#define _curl_is_cb_data_option(option)                                       \
+#define curlcheck_cb_data_option(option)                                      \
   ((option) == CURLOPT_CHUNK_DATA ||                                          \
    (option) == CURLOPT_CLOSESOCKETDATA ||                                     \
    (option) == CURLOPT_DEBUGDATA ||                                           \
@@ -369,13 +370,13 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
    0)
 
 /* evaluates to true if option takes a POST data argument (void* or char*) */
-#define _curl_is_postfields_option(option)                                    \
+#define curlcheck_postfields_option(option)                                   \
   ((option) == CURLOPT_POSTFIELDS ||                                          \
    (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
    0)
 
 /* evaluates to true if option takes a struct curl_slist * argument */
-#define _curl_is_slist_option(option)                                         \
+#define curlcheck_slist_option(option)                                        \
   ((option) == CURLOPT_HTTP200ALIASES ||                                      \
    (option) == CURLOPT_HTTPHEADER ||                                          \
    (option) == CURLOPT_MAIL_RCPT ||                                           \
@@ -391,40 +392,40 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
 /* groups of curl_easy_getinfo infos that take the same type of argument */
 
 /* evaluates to true if info expects a pointer to char * argument */
-#define _curl_is_string_info(info)                                            \
+#define curlcheck_string_info(info)                     \
   (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
 
 /* evaluates to true if info expects a pointer to long argument */
-#define _curl_is_long_info(info)                                              \
+#define curlcheck_long_info(info)                       \
   (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
 
 /* evaluates to true if info expects a pointer to double argument */
-#define _curl_is_double_info(info)                                            \
+#define curlcheck_double_info(info)                     \
   (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
 
 /* true if info expects a pointer to struct curl_slist * argument */
-#define _curl_is_slist_info(info)                                       \
+#define curlcheck_slist_info(info)                                      \
   (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
 
 /* true if info expects a pointer to struct curl_tlssessioninfo * argument */
-#define _curl_is_tlssessioninfo_info(info)                              \
+#define curlcheck_tlssessioninfo_info(info)                              \
   (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
 
 /* true if info expects a pointer to struct curl_certinfo * argument */
-#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
+#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
 
 /* true if info expects a pointer to struct curl_socket_t argument */
-#define _curl_is_socket_info(info)                                            \
+#define curlcheck_socket_info(info)                     \
   (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
 
 /* true if info expects a pointer to curl_off_t argument */
-#define _curl_is_off_t_info(info)                                             \
+#define curlcheck_off_t_info(info)              \
   (CURLINFO_OFF_T < (info))
 
 
 /* typecheck helpers -- check whether given expression has requested type*/
 
-/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
  * otherwise define a new macro. Search for __builtin_types_compatible_p
  * in the GCC manual.
  * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
@@ -434,35 +435,35 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
  */
 
 /* XXX: should evaluate to true if expr is a pointer */
-#define _curl_is_any_ptr(expr)                                                \
+#define curlcheck_any_ptr(expr)                 \
   (sizeof(expr) == sizeof(void *))
 
 /* evaluates to true if expr is NULL */
 /* XXX: must not evaluate expr, so this check is not accurate */
-#define _curl_is_NULL(expr)                                                   \
+#define curlcheck_NULL(expr)                                            \
   (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
 
 /* evaluates to true if expr is type*, const type* or NULL */
-#define _curl_is_ptr(expr, type)                                              \
-  (_curl_is_NULL(expr) ||                                                     \
-   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+#define curlcheck_ptr(expr, type)                                       \
+  (curlcheck_NULL(expr) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||            \
    __builtin_types_compatible_p(__typeof__(expr), const type *))
 
 /* evaluates to true if expr is one of type[], type*, NULL or const type* */
-#define _curl_is_arr(expr, type)                                              \
-  (_curl_is_ptr((expr), type) ||                                              \
+#define curlcheck_arr(expr, type)                                       \
+  (curlcheck_ptr((expr), type) ||                                       \
    __builtin_types_compatible_p(__typeof__(expr), type []))
 
 /* evaluates to true if expr is a string */
-#define _curl_is_string(expr)                                                 \
-  (_curl_is_arr((expr), char) ||                                              \
-   _curl_is_arr((expr), signed char) ||                                       \
-   _curl_is_arr((expr), unsigned char))
+#define curlcheck_string(expr)                                          \
+  (curlcheck_arr((expr), char) ||                                       \
+   curlcheck_arr((expr), signed char) ||                                \
+   curlcheck_arr((expr), unsigned char))
 
 /* evaluates to true if expr is a long (no matter the signedness)
  * XXX: for now, int is also accepted (and therefore short and char, which
  * are promoted to int when passed to a variadic function) */
-#define _curl_is_long(expr)                                                   \
+#define curlcheck_long(expr)                                                  \
   (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
    __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
    __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
@@ -477,59 +478,59 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
    __builtin_types_compatible_p(__typeof__(expr), unsigned char))
 
 /* evaluates to true if expr is of type curl_off_t */
-#define _curl_is_off_t(expr)                                                  \
+#define curlcheck_off_t(expr)                                   \
   (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
 
 /* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
 /* XXX: also check size of an char[] array? */
-#define _curl_is_error_buffer(expr)                                           \
-  (_curl_is_NULL(expr) ||                                                     \
-   __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+#define curlcheck_error_buffer(expr)                                    \
+  (curlcheck_NULL(expr) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), char *) ||            \
    __builtin_types_compatible_p(__typeof__(expr), char[]))
 
 /* evaluates to true if expr is of type (const) void* or (const) FILE* */
 #if 0
-#define _curl_is_cb_data(expr)                                                \
-  (_curl_is_ptr((expr), void) ||                                              \
-   _curl_is_ptr((expr), FILE))
+#define curlcheck_cb_data(expr)                                         \
+  (curlcheck_ptr((expr), void) ||                                       \
+   curlcheck_ptr((expr), FILE))
 #else /* be less strict */
-#define _curl_is_cb_data(expr)                                                \
-  _curl_is_any_ptr(expr)
+#define curlcheck_cb_data(expr)                 \
+  curlcheck_any_ptr(expr)
 #endif
 
 /* evaluates to true if expr is of type FILE* */
-#define _curl_is_FILE(expr)                                             \
-  (_curl_is_NULL(expr) ||                                              \
+#define curlcheck_FILE(expr)                                            \
+  (curlcheck_NULL(expr) ||                                              \
    (__builtin_types_compatible_p(__typeof__(expr), FILE *)))
 
 /* evaluates to true if expr can be passed as POST data (void* or char*) */
-#define _curl_is_postfields(expr)                                             \
-  (_curl_is_ptr((expr), void) ||                                              \
-   _curl_is_arr((expr), char) ||                                              \
-   _curl_is_arr((expr), unsigned char))
+#define curlcheck_postfields(expr)                                      \
+  (curlcheck_ptr((expr), void) ||                                       \
+   curlcheck_arr((expr), char) ||                                       \
+   curlcheck_arr((expr), unsigned char))
 
 /* helper: __builtin_types_compatible_p distinguishes between functions and
  * function pointers, hide it */
-#define _curl_callback_compatible(func, type)                                 \
-  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+#define curlcheck_cb_compatible(func, type)                             \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||              \
    __builtin_types_compatible_p(__typeof__(func) *, type))
 
 /* evaluates to true if expr is of type curl_resolver_start_callback */
-#define _curl_is_resolver_start_callback(expr)       \
-  (_curl_is_NULL(expr) || \
-   _curl_callback_compatible((expr), curl_resolver_start_callback))
+#define curlcheck_resolver_start_callback(expr)       \
+  (curlcheck_NULL(expr) || \
+   curlcheck_cb_compatible((expr), curl_resolver_start_callback))
 
 /* evaluates to true if expr is of type curl_read_callback or "similar" */
-#define _curl_is_read_cb(expr)                                          \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), __typeof__(fread) *) ||                  \
-   _curl_callback_compatible((expr), curl_read_callback) ||                   \
-   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback6))
+#define curlcheck_read_cb(expr)                                         \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), __typeof__(fread) *) ||              \
+   curlcheck_cb_compatible((expr), curl_read_callback) ||               \
+   curlcheck_cb_compatible((expr), _curl_read_callback1) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback2) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback3) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback4) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback5) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback6))
 typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
 typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
 typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
@@ -538,16 +539,16 @@ typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
 typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
 
 /* evaluates to true if expr is of type curl_write_callback or "similar" */
-#define _curl_is_write_cb(expr)                                               \
-  (_curl_is_read_cb(expr) ||                                            \
-   _curl_callback_compatible((expr), __typeof__(fwrite) *) ||                 \
-   _curl_callback_compatible((expr), curl_write_callback) ||                  \
-   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback6))
+#define curlcheck_write_cb(expr)                                        \
+  (curlcheck_read_cb(expr) ||                                           \
+   curlcheck_cb_compatible((expr), __typeof__(fwrite) *) ||             \
+   curlcheck_cb_compatible((expr), curl_write_callback) ||              \
+   curlcheck_cb_compatible((expr), _curl_write_callback1) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback2) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback3) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback4) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback5) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback6))
 typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
 typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
                                        const void *);
@@ -558,37 +559,37 @@ typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
 typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
 
 /* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
-#define _curl_is_ioctl_cb(expr)                                         \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_ioctl_callback) ||                  \
-   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
-   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
-   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
-   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+#define curlcheck_ioctl_cb(expr)                                        \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_ioctl_callback) ||              \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback1) ||            \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback2) ||            \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback3) ||            \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
 typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
 typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
 typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
 typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
 
 /* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
-#define _curl_is_sockopt_cb(expr)                                       \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_sockopt_callback) ||                \
-   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
-   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+#define curlcheck_sockopt_cb(expr)                                      \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_sockopt_callback) ||            \
+   curlcheck_cb_compatible((expr), _curl_sockopt_callback1) ||          \
+   curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
 typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
 typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
                                       curlsocktype);
 
 /* evaluates to true if expr is of type curl_opensocket_callback or
    "similar" */
-#define _curl_is_opensocket_cb(expr)                                    \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_opensocket_callback) ||             \
-   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
-   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
-   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
-   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+#define curlcheck_opensocket_cb(expr)                                   \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_opensocket_callback) ||         \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback1) ||       \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback2) ||       \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback3) ||       \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
 typedef curl_socket_t (*_curl_opensocket_callback1)
   (void *, curlsocktype, struct curl_sockaddr *);
 typedef curl_socket_t (*_curl_opensocket_callback2)
@@ -599,28 +600,28 @@ typedef curl_socket_t (*_curl_opensocket_callback4)
   (const void *, curlsocktype, const struct curl_sockaddr *);
 
 /* evaluates to true if expr is of type curl_progress_callback or "similar" */
-#define _curl_is_progress_cb(expr)                                      \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_progress_callback) ||               \
-   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
-   _curl_callback_compatible((expr), _curl_progress_callback2))
+#define curlcheck_progress_cb(expr)                                     \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_progress_callback) ||           \
+   curlcheck_cb_compatible((expr), _curl_progress_callback1) ||         \
+   curlcheck_cb_compatible((expr), _curl_progress_callback2))
 typedef int (*_curl_progress_callback1)(void *,
     double, double, double, double);
 typedef int (*_curl_progress_callback2)(const void *,
     double, double, double, double);
 
 /* evaluates to true if expr is of type curl_debug_callback or "similar" */
-#define _curl_is_debug_cb(expr)                                         \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_debug_callback) ||                  \
-   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback4) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback5) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback6) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback7) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback8))
+#define curlcheck_debug_cb(expr)                                        \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_debug_callback) ||              \
+   curlcheck_cb_compatible((expr), _curl_debug_callback1) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback2) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback3) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback4) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback5) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback6) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback7) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback8))
 typedef int (*_curl_debug_callback1) (CURL *,
     curl_infotype, char *, size_t, void *);
 typedef int (*_curl_debug_callback2) (CURL *,
@@ -640,17 +641,17 @@ typedef int (*_curl_debug_callback8) (CURL *,
 
 /* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
 /* this is getting even messier... */
-#define _curl_is_ssl_ctx_cb(expr)                                       \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_ssl_ctx_callback) ||                \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+#define curlcheck_ssl_ctx_cb(expr)                                      \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) ||            \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
 typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
 typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
 typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
@@ -673,26 +674,26 @@ typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
 #endif
 
 /* evaluates to true if expr is of type curl_conv_callback or "similar" */
-#define _curl_is_conv_cb(expr)                                          \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_conv_callback) ||                   \
-   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
-   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
-   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
-   _curl_callback_compatible((expr), _curl_conv_callback4))
+#define curlcheck_conv_cb(expr)                                         \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_conv_callback) ||               \
+   curlcheck_cb_compatible((expr), _curl_conv_callback1) ||             \
+   curlcheck_cb_compatible((expr), _curl_conv_callback2) ||             \
+   curlcheck_cb_compatible((expr), _curl_conv_callback3) ||             \
+   curlcheck_cb_compatible((expr), _curl_conv_callback4))
 typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
 typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
 typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
 typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
 
 /* evaluates to true if expr is of type curl_seek_callback or "similar" */
-#define _curl_is_seek_cb(expr)                                          \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_seek_callback) ||                   \
-   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
-   _curl_callback_compatible((expr), _curl_seek_callback2))
+#define curlcheck_seek_cb(expr)                                         \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_seek_callback) ||               \
+   curlcheck_cb_compatible((expr), _curl_seek_callback1) ||             \
+   curlcheck_cb_compatible((expr), _curl_seek_callback2))
 typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
 typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
 
 
-#endif /* __CURL_TYPECHECK_GCC_H */
+#endif /* CURLINC_TYPECHECK_GCC_H */
diff --git a/libs/libcurl/include/curl/urlapi.h b/libs/libcurl/include/curl/urlapi.h
index 58e89d85c2..0f2f152f1f 100644
--- a/libs/libcurl/include/curl/urlapi.h
+++ b/libs/libcurl/include/curl/urlapi.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_URLAPI_H
-#define __CURL_URLAPI_H
+#ifndef CURLINC_URLAPI_H
+#define CURLINC_URLAPI_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -120,4 +120,4 @@ CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
 } /* end of extern "C" */
 #endif
 
-#endif
+#endif /* CURLINC_URLAPI_H */
diff --git a/libs/libcurl/libcurl.vcxproj b/libs/libcurl/libcurl.vcxproj
index 5909d76717..b8724b921a 100644
--- a/libs/libcurl/libcurl.vcxproj
+++ b/libs/libcurl/libcurl.vcxproj
@@ -29,6 +29,9 @@
     <ClCompile Include="src\vauth\*.c">
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="src\vssh\*.c">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
     <ClCompile Include="src\vtls\*.c">
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
     </ClCompile>
diff --git a/libs/libcurl/src/Makefile.am b/libs/libcurl/src/Makefile.am
index 7c258b3fa7..516a2394df 100644
--- a/libs/libcurl/src/Makefile.am
+++ b/libs/libcurl/src/Makefile.am
@@ -23,8 +23,8 @@ AUTOMAKE_OPTIONS = foreign nostdinc
 
 CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
 
-EXTRA_DIST = Makefile.m32 config-win32.h                            \
- config-win32ce.h config-riscos.h config-mac.h curl_config.h.in     \
+EXTRA_DIST = Makefile.m32 config-win32.h config-win32ce.h           \
+ config-plan9.h config-riscos.h config-mac.h curl_config.h.in       \
  makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \
  makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h    \
  config-os400.h setup-os400.h config-symbian.h Makefile.Watcom      \
@@ -65,7 +65,7 @@ endif
 # Prevent LIBS from being used for all link targets
 LIBS = $(BLANK_AT_MAKETIME)
 
-VERSIONINFO=-version-info 9:0:5
+VERSIONINFO=-version-info 10:0:6
 # This flag accepts an argument of the form current[:revision[:age]]. So,
 # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
 # 1.
@@ -138,7 +138,7 @@ CS_ = $(CS_0)
 
 checksrc:
 	$(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \
-	$(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch])
+	$(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch] $(srcdir)/vquic/*.[ch] $(srcdir)/vssh/*.[ch])
 
 if CURLDEBUG
 # for debug builds, we scan the sources on all regular make invokes
diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in
index da01c26a66..28dfe93e43 100644
--- a/libs/libcurl/src/Makefile.in
+++ b/libs/libcurl/src/Makefile.in
@@ -205,25 +205,24 @@ am__objects_1 = libcurl_la-file.lo libcurl_la-timeval.lo \
 	libcurl_la-hostsyn.lo libcurl_la-inet_ntop.lo \
 	libcurl_la-parsedate.lo libcurl_la-select.lo \
 	libcurl_la-tftp.lo libcurl_la-splay.lo libcurl_la-strdup.lo \
-	libcurl_la-socks.lo libcurl_la-ssh.lo libcurl_la-ssh-libssh.lo \
-	libcurl_la-curl_addrinfo.lo libcurl_la-socks_gssapi.lo \
-	libcurl_la-socks_sspi.lo libcurl_la-curl_sspi.lo \
-	libcurl_la-slist.lo libcurl_la-nonblock.lo \
-	libcurl_la-curl_memrchr.lo libcurl_la-imap.lo \
-	libcurl_la-pop3.lo libcurl_la-smtp.lo libcurl_la-pingpong.lo \
-	libcurl_la-rtsp.lo libcurl_la-curl_threads.lo \
-	libcurl_la-warnless.lo libcurl_la-hmac.lo \
-	libcurl_la-curl_rtmp.lo libcurl_la-openldap.lo \
-	libcurl_la-curl_gethostname.lo libcurl_la-gopher.lo \
-	libcurl_la-idn_win32.lo libcurl_la-http_proxy.lo \
-	libcurl_la-non-ascii.lo libcurl_la-asyn-ares.lo \
-	libcurl_la-asyn-thread.lo libcurl_la-curl_gssapi.lo \
-	libcurl_la-http_ntlm.lo libcurl_la-curl_ntlm_wb.lo \
-	libcurl_la-curl_ntlm_core.lo libcurl_la-curl_sasl.lo \
-	libcurl_la-rand.lo libcurl_la-curl_multibyte.lo \
-	libcurl_la-hostcheck.lo libcurl_la-conncache.lo \
-	libcurl_la-dotdot.lo libcurl_la-x509asn1.lo \
-	libcurl_la-http2.lo libcurl_la-smb.lo \
+	libcurl_la-socks.lo libcurl_la-curl_addrinfo.lo \
+	libcurl_la-socks_gssapi.lo libcurl_la-socks_sspi.lo \
+	libcurl_la-curl_sspi.lo libcurl_la-slist.lo \
+	libcurl_la-nonblock.lo libcurl_la-curl_memrchr.lo \
+	libcurl_la-imap.lo libcurl_la-pop3.lo libcurl_la-smtp.lo \
+	libcurl_la-pingpong.lo libcurl_la-rtsp.lo \
+	libcurl_la-curl_threads.lo libcurl_la-warnless.lo \
+	libcurl_la-hmac.lo libcurl_la-curl_rtmp.lo \
+	libcurl_la-openldap.lo libcurl_la-curl_gethostname.lo \
+	libcurl_la-gopher.lo libcurl_la-idn_win32.lo \
+	libcurl_la-http_proxy.lo libcurl_la-non-ascii.lo \
+	libcurl_la-asyn-ares.lo libcurl_la-asyn-thread.lo \
+	libcurl_la-curl_gssapi.lo libcurl_la-http_ntlm.lo \
+	libcurl_la-curl_ntlm_wb.lo libcurl_la-curl_ntlm_core.lo \
+	libcurl_la-curl_sasl.lo libcurl_la-rand.lo \
+	libcurl_la-curl_multibyte.lo libcurl_la-hostcheck.lo \
+	libcurl_la-conncache.lo libcurl_la-dotdot.lo \
+	libcurl_la-x509asn1.lo libcurl_la-http2.lo libcurl_la-smb.lo \
 	libcurl_la-curl_endian.lo libcurl_la-curl_des.lo \
 	libcurl_la-system_win32.lo libcurl_la-mime.lo \
 	libcurl_la-sha256.lo libcurl_la-setopt.lo \
@@ -247,10 +246,14 @@ am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.lo \
 	vtls/libcurl_la-schannel_verify.lo \
 	vtls/libcurl_la-sectransp.lo vtls/libcurl_la-gskit.lo \
 	vtls/libcurl_la-mbedtls.lo vtls/libcurl_la-mesalink.lo
-am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3)
-am__objects_5 =
-am__objects_6 = $(am__objects_5) $(am__objects_5) $(am__objects_5)
-am_libcurl_la_OBJECTS = $(am__objects_4) $(am__objects_6)
+am__objects_4 = vquic/libcurl_la-ngtcp2.lo vquic/libcurl_la-quiche.lo
+am__objects_5 = vssh/libcurl_la-libssh2.lo vssh/libcurl_la-libssh.lo
+am__objects_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+	$(am__objects_4) $(am__objects_5)
+am__objects_7 =
+am__objects_8 = $(am__objects_7) $(am__objects_7) $(am__objects_7) \
+	$(am__objects_7)
+am_libcurl_la_OBJECTS = $(am__objects_6) $(am__objects_8)
 libcurl_la_OBJECTS = $(am_libcurl_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -260,7 +263,7 @@ libcurl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcurl_la_CFLAGS) \
 	$(CFLAGS) $(libcurl_la_LDFLAGS) $(LDFLAGS) -o $@
 libcurlu_la_LIBADD =
-am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \
+am__objects_9 = libcurlu_la-file.lo libcurlu_la-timeval.lo \
 	libcurlu_la-base64.lo libcurlu_la-hostip.lo \
 	libcurlu_la-progress.lo libcurlu_la-formdata.lo \
 	libcurlu_la-cookie.lo libcurlu_la-http.lo libcurlu_la-sendf.lo \
@@ -287,12 +290,12 @@ am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \
 	libcurlu_la-hostip6.lo libcurlu_la-hostsyn.lo \
 	libcurlu_la-inet_ntop.lo libcurlu_la-parsedate.lo \
 	libcurlu_la-select.lo libcurlu_la-tftp.lo libcurlu_la-splay.lo \
-	libcurlu_la-strdup.lo libcurlu_la-socks.lo libcurlu_la-ssh.lo \
-	libcurlu_la-ssh-libssh.lo libcurlu_la-curl_addrinfo.lo \
-	libcurlu_la-socks_gssapi.lo libcurlu_la-socks_sspi.lo \
-	libcurlu_la-curl_sspi.lo libcurlu_la-slist.lo \
-	libcurlu_la-nonblock.lo libcurlu_la-curl_memrchr.lo \
-	libcurlu_la-imap.lo libcurlu_la-pop3.lo libcurlu_la-smtp.lo \
+	libcurlu_la-strdup.lo libcurlu_la-socks.lo \
+	libcurlu_la-curl_addrinfo.lo libcurlu_la-socks_gssapi.lo \
+	libcurlu_la-socks_sspi.lo libcurlu_la-curl_sspi.lo \
+	libcurlu_la-slist.lo libcurlu_la-nonblock.lo \
+	libcurlu_la-curl_memrchr.lo libcurlu_la-imap.lo \
+	libcurlu_la-pop3.lo libcurlu_la-smtp.lo \
 	libcurlu_la-pingpong.lo libcurlu_la-rtsp.lo \
 	libcurlu_la-curl_threads.lo libcurlu_la-warnless.lo \
 	libcurlu_la-hmac.lo libcurlu_la-curl_rtmp.lo \
@@ -313,7 +316,7 @@ am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \
 	libcurlu_la-curl_ctype.lo libcurlu_la-curl_range.lo \
 	libcurlu_la-psl.lo libcurlu_la-doh.lo libcurlu_la-urlapi.lo \
 	libcurlu_la-curl_get_line.lo libcurlu_la-altsvc.lo
-am__objects_8 = vauth/libcurlu_la-vauth.lo \
+am__objects_10 = vauth/libcurlu_la-vauth.lo \
 	vauth/libcurlu_la-cleartext.lo vauth/libcurlu_la-cram.lo \
 	vauth/libcurlu_la-digest.lo vauth/libcurlu_la-digest_sspi.lo \
 	vauth/libcurlu_la-krb5_gssapi.lo \
@@ -321,7 +324,7 @@ am__objects_8 = vauth/libcurlu_la-vauth.lo \
 	vauth/libcurlu_la-ntlm_sspi.lo vauth/libcurlu_la-oauth2.lo \
 	vauth/libcurlu_la-spnego_gssapi.lo \
 	vauth/libcurlu_la-spnego_sspi.lo
-am__objects_9 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \
+am__objects_11 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \
 	vtls/libcurlu_la-vtls.lo vtls/libcurlu_la-nss.lo \
 	vtls/libcurlu_la-polarssl.lo \
 	vtls/libcurlu_la-polarssl_threadlock.lo \
@@ -329,8 +332,13 @@ am__objects_9 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \
 	vtls/libcurlu_la-schannel_verify.lo \
 	vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-gskit.lo \
 	vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo
-am__objects_10 = $(am__objects_7) $(am__objects_8) $(am__objects_9)
-am_libcurlu_la_OBJECTS = $(am__objects_10) $(am__objects_6)
+am__objects_12 = vquic/libcurlu_la-ngtcp2.lo \
+	vquic/libcurlu_la-quiche.lo
+am__objects_13 = vssh/libcurlu_la-libssh2.lo \
+	vssh/libcurlu_la-libssh.lo
+am__objects_14 = $(am__objects_9) $(am__objects_10) $(am__objects_11) \
+	$(am__objects_12) $(am__objects_13)
+am_libcurlu_la_OBJECTS = $(am__objects_14) $(am__objects_8)
 libcurlu_la_OBJECTS = $(am_libcurlu_la_OBJECTS)
 libcurlu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcurlu_la_CFLAGS) \
@@ -441,8 +449,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
 	./$(DEPDIR)/libcurl_la-socks_sspi.Plo \
 	./$(DEPDIR)/libcurl_la-speedcheck.Plo \
 	./$(DEPDIR)/libcurl_la-splay.Plo \
-	./$(DEPDIR)/libcurl_la-ssh-libssh.Plo \
-	./$(DEPDIR)/libcurl_la-ssh.Plo \
 	./$(DEPDIR)/libcurl_la-strcase.Plo \
 	./$(DEPDIR)/libcurl_la-strdup.Plo \
 	./$(DEPDIR)/libcurl_la-strerror.Plo \
@@ -553,8 +559,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
 	./$(DEPDIR)/libcurlu_la-socks_sspi.Plo \
 	./$(DEPDIR)/libcurlu_la-speedcheck.Plo \
 	./$(DEPDIR)/libcurlu_la-splay.Plo \
-	./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo \
-	./$(DEPDIR)/libcurlu_la-ssh.Plo \
 	./$(DEPDIR)/libcurlu_la-strcase.Plo \
 	./$(DEPDIR)/libcurlu_la-strdup.Plo \
 	./$(DEPDIR)/libcurlu_la-strerror.Plo \
@@ -595,6 +599,14 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
 	vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo \
 	vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo \
 	vauth/$(DEPDIR)/libcurlu_la-vauth.Plo \
+	vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo \
+	vquic/$(DEPDIR)/libcurl_la-quiche.Plo \
+	vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo \
+	vquic/$(DEPDIR)/libcurlu_la-quiche.Plo \
+	vssh/$(DEPDIR)/libcurl_la-libssh.Plo \
+	vssh/$(DEPDIR)/libcurl_la-libssh2.Plo \
+	vssh/$(DEPDIR)/libcurlu_la-libssh.Plo \
+	vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo \
 	vtls/$(DEPDIR)/libcurl_la-gskit.Plo \
 	vtls/$(DEPDIR)/libcurl_la-gtls.Plo \
 	vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo \
@@ -808,8 +820,12 @@ USE_LIBSSH2 = @USE_LIBSSH2@
 USE_MBEDTLS = @USE_MBEDTLS@
 USE_MESALINK = @USE_MESALINK@
 USE_NGHTTP2 = @USE_NGHTTP2@
+USE_NGHTTP3 = @USE_NGHTTP3@
+USE_NGTCP2 = @USE_NGTCP2@
+USE_NGTCP2_CRYPTO_OPENSSL = @USE_NGTCP2_CRYPTO_OPENSSL@
 USE_NSS = @USE_NSS@
 USE_OPENLDAP = @USE_OPENLDAP@
+USE_QUICHE = @USE_QUICHE@
 USE_SCHANNEL = @USE_SCHANNEL@
 USE_SECTRANSP = @USE_SECTRANSP@
 USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
@@ -898,8 +914,8 @@ top_srcdir = @top_srcdir@
 ###########################################################################
 AUTOMAKE_OPTIONS = foreign nostdinc
 CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
-EXTRA_DIST = Makefile.m32 config-win32.h                            \
- config-win32ce.h config-riscos.h config-mac.h curl_config.h.in     \
+EXTRA_DIST = Makefile.m32 config-win32.h config-win32ce.h           \
+ config-plan9.h config-riscos.h config-mac.h curl_config.h.in       \
  makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \
  makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h    \
  config-os400.h setup-os400.h config-symbian.h Makefile.Watcom      \
@@ -934,7 +950,7 @@ lib_LTLIBRARIES = libcurl.la
 # For the full guide on libcurl ABI rules, see docs/libcurl/ABI
 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \
 	-I$(top_srcdir)/lib $(am__append_1) -DBUILDING_LIBCURL
-VERSIONINFO = -version-info 9:0:5
+VERSIONINFO = -version-info 10:0:6
 AM_LDFLAGS = 
 AM_CFLAGS = 
 libcurl_la_CPPFLAGS_EXTRA = $(am__append_7) $(am__append_8)
@@ -963,6 +979,9 @@ LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h                \
   vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h          \
   vtls/mbedtls.h vtls/mesalink.h
 
+LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
+LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
+LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c
 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         \
@@ -972,7 +991,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
   http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c    \
   strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c         \
   inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c      \
-  ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c        \
+  curl_addrinfo.c socks_gssapi.c socks_sspi.c                           \
   curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c    \
   pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c        \
   openldap.c curl_gethostname.c gopher.c idn_win32.c                    \
@@ -1002,11 +1021,15 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
   x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h           \
   curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h     \
   curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h        \
-  curl_get_line.h altsvc.h
+  curl_get_line.h altsvc.h quic.h
 
 LIB_RCFILES = libcurl.rc
-CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES)
-HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES)
+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)
+
 
 # Makefile.inc provides the CSOURCES and HHEADERS defines
 libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
@@ -1179,6 +1202,26 @@ vtls/libcurl_la-mbedtls.lo: vtls/$(am__dirstamp) \
 	vtls/$(DEPDIR)/$(am__dirstamp)
 vtls/libcurl_la-mesalink.lo: vtls/$(am__dirstamp) \
 	vtls/$(DEPDIR)/$(am__dirstamp)
+vquic/$(am__dirstamp):
+	@$(MKDIR_P) vquic
+	@: > vquic/$(am__dirstamp)
+vquic/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) vquic/$(DEPDIR)
+	@: > vquic/$(DEPDIR)/$(am__dirstamp)
+vquic/libcurl_la-ngtcp2.lo: vquic/$(am__dirstamp) \
+	vquic/$(DEPDIR)/$(am__dirstamp)
+vquic/libcurl_la-quiche.lo: vquic/$(am__dirstamp) \
+	vquic/$(DEPDIR)/$(am__dirstamp)
+vssh/$(am__dirstamp):
+	@$(MKDIR_P) vssh
+	@: > vssh/$(am__dirstamp)
+vssh/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) vssh/$(DEPDIR)
+	@: > vssh/$(DEPDIR)/$(am__dirstamp)
+vssh/libcurl_la-libssh2.lo: vssh/$(am__dirstamp) \
+	vssh/$(DEPDIR)/$(am__dirstamp)
+vssh/libcurl_la-libssh.lo: vssh/$(am__dirstamp) \
+	vssh/$(DEPDIR)/$(am__dirstamp)
 
 libcurl.la: $(libcurl_la_OBJECTS) $(libcurl_la_DEPENDENCIES) $(EXTRA_libcurl_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(libcurl_la_LINK) -rpath $(libdir) $(libcurl_la_OBJECTS) $(libcurl_la_LIBADD) $(LIBS)
@@ -1232,6 +1275,14 @@ vtls/libcurlu_la-mbedtls.lo: vtls/$(am__dirstamp) \
 	vtls/$(DEPDIR)/$(am__dirstamp)
 vtls/libcurlu_la-mesalink.lo: vtls/$(am__dirstamp) \
 	vtls/$(DEPDIR)/$(am__dirstamp)
+vquic/libcurlu_la-ngtcp2.lo: vquic/$(am__dirstamp) \
+	vquic/$(DEPDIR)/$(am__dirstamp)
+vquic/libcurlu_la-quiche.lo: vquic/$(am__dirstamp) \
+	vquic/$(DEPDIR)/$(am__dirstamp)
+vssh/libcurlu_la-libssh2.lo: vssh/$(am__dirstamp) \
+	vssh/$(DEPDIR)/$(am__dirstamp)
+vssh/libcurlu_la-libssh.lo: vssh/$(am__dirstamp) \
+	vssh/$(DEPDIR)/$(am__dirstamp)
 
 libcurlu.la: $(libcurlu_la_OBJECTS) $(libcurlu_la_DEPENDENCIES) $(EXTRA_libcurlu_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(libcurlu_la_LINK) $(am_libcurlu_la_rpath) $(libcurlu_la_OBJECTS) $(libcurlu_la_LIBADD) $(LIBS)
@@ -1240,6 +1291,10 @@ mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
 	-rm -f vauth/*.$(OBJEXT)
 	-rm -f vauth/*.lo
+	-rm -f vquic/*.$(OBJEXT)
+	-rm -f vquic/*.lo
+	-rm -f vssh/*.$(OBJEXT)
+	-rm -f vssh/*.lo
 	-rm -f vtls/*.$(OBJEXT)
 	-rm -f vtls/*.lo
 
@@ -1340,8 +1395,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-socks_sspi.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-speedcheck.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-splay.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ssh-libssh.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ssh.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strcase.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strdup.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strerror.Plo@am__quote@ # am--include-marker
@@ -1452,8 +1505,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-socks_sspi.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-speedcheck.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-splay.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ssh.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strcase.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strdup.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strerror.Plo@am__quote@ # am--include-marker
@@ -1494,6 +1545,14 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-vauth.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurl_la-quiche.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurlu_la-quiche.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-libssh.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gskit.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gtls.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo@am__quote@ # am--include-marker
@@ -1964,20 +2023,6 @@ libcurl_la-socks.lo: socks.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-socks.lo `test -f 'socks.c' || echo '$(srcdir)/'`socks.c
 
-libcurl_la-ssh.lo: ssh.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ssh.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ssh.Tpo -c -o libcurl_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ssh.Tpo $(DEPDIR)/libcurl_la-ssh.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ssh.c' object='libcurl_la-ssh.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c
-
-libcurl_la-ssh-libssh.lo: ssh-libssh.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ssh-libssh.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ssh-libssh.Tpo -c -o libcurl_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ssh-libssh.Tpo $(DEPDIR)/libcurl_la-ssh-libssh.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ssh-libssh.c' object='libcurl_la-ssh-libssh.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c
-
 libcurl_la-curl_addrinfo.lo: curl_addrinfo.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_addrinfo.Tpo -c -o libcurl_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_addrinfo.Tpo $(DEPDIR)/libcurl_la-curl_addrinfo.Plo
@@ -2510,6 +2555,34 @@ vtls/libcurl_la-mesalink.lo: vtls/mesalink.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c
 
+vquic/libcurl_la-ngtcp2.lo: vquic/ngtcp2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vquic/libcurl_la-ngtcp2.lo -MD -MP -MF vquic/$(DEPDIR)/libcurl_la-ngtcp2.Tpo -c -o vquic/libcurl_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurl_la-ngtcp2.Tpo vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vquic/ngtcp2.c' object='vquic/libcurl_la-ngtcp2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vquic/libcurl_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c
+
+vquic/libcurl_la-quiche.lo: vquic/quiche.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vquic/libcurl_la-quiche.lo -MD -MP -MF vquic/$(DEPDIR)/libcurl_la-quiche.Tpo -c -o vquic/libcurl_la-quiche.lo `test -f 'vquic/quiche.c' || echo '$(srcdir)/'`vquic/quiche.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurl_la-quiche.Tpo vquic/$(DEPDIR)/libcurl_la-quiche.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vquic/quiche.c' object='vquic/libcurl_la-quiche.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vquic/libcurl_la-quiche.lo `test -f 'vquic/quiche.c' || echo '$(srcdir)/'`vquic/quiche.c
+
+vssh/libcurl_la-libssh2.lo: vssh/libssh2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vssh/libcurl_la-libssh2.lo -MD -MP -MF vssh/$(DEPDIR)/libcurl_la-libssh2.Tpo -c -o vssh/libcurl_la-libssh2.lo `test -f 'vssh/libssh2.c' || echo '$(srcdir)/'`vssh/libssh2.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurl_la-libssh2.Tpo vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vssh/libssh2.c' object='vssh/libcurl_la-libssh2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vssh/libcurl_la-libssh2.lo `test -f 'vssh/libssh2.c' || echo '$(srcdir)/'`vssh/libssh2.c
+
+vssh/libcurl_la-libssh.lo: vssh/libssh.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vssh/libcurl_la-libssh.lo -MD -MP -MF vssh/$(DEPDIR)/libcurl_la-libssh.Tpo -c -o vssh/libcurl_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurl_la-libssh.Tpo vssh/$(DEPDIR)/libcurl_la-libssh.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vssh/libssh.c' object='vssh/libcurl_la-libssh.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vssh/libcurl_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
+
 libcurlu_la-file.lo: file.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-file.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-file.Tpo -c -o libcurlu_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-file.Tpo $(DEPDIR)/libcurlu_la-file.Plo
@@ -2923,20 +2996,6 @@ libcurlu_la-socks.lo: socks.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-socks.lo `test -f 'socks.c' || echo '$(srcdir)/'`socks.c
 
-libcurlu_la-ssh.lo: ssh.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ssh.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ssh.Tpo -c -o libcurlu_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ssh.Tpo $(DEPDIR)/libcurlu_la-ssh.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ssh.c' object='libcurlu_la-ssh.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c
-
-libcurlu_la-ssh-libssh.lo: ssh-libssh.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ssh-libssh.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ssh-libssh.Tpo -c -o libcurlu_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ssh-libssh.Tpo $(DEPDIR)/libcurlu_la-ssh-libssh.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ssh-libssh.c' object='libcurlu_la-ssh-libssh.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c
-
 libcurlu_la-curl_addrinfo.lo: curl_addrinfo.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_addrinfo.Tpo -c -o libcurlu_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_addrinfo.Tpo $(DEPDIR)/libcurlu_la-curl_addrinfo.Plo
@@ -3469,12 +3528,42 @@ vtls/libcurlu_la-mesalink.lo: vtls/mesalink.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c
 
+vquic/libcurlu_la-ngtcp2.lo: vquic/ngtcp2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vquic/libcurlu_la-ngtcp2.lo -MD -MP -MF vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Tpo -c -o vquic/libcurlu_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Tpo vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vquic/ngtcp2.c' object='vquic/libcurlu_la-ngtcp2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vquic/libcurlu_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c
+
+vquic/libcurlu_la-quiche.lo: vquic/quiche.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vquic/libcurlu_la-quiche.lo -MD -MP -MF vquic/$(DEPDIR)/libcurlu_la-quiche.Tpo -c -o vquic/libcurlu_la-quiche.lo `test -f 'vquic/quiche.c' || echo '$(srcdir)/'`vquic/quiche.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurlu_la-quiche.Tpo vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vquic/quiche.c' object='vquic/libcurlu_la-quiche.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vquic/libcurlu_la-quiche.lo `test -f 'vquic/quiche.c' || echo '$(srcdir)/'`vquic/quiche.c
+
+vssh/libcurlu_la-libssh2.lo: vssh/libssh2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vssh/libcurlu_la-libssh2.lo -MD -MP -MF vssh/$(DEPDIR)/libcurlu_la-libssh2.Tpo -c -o vssh/libcurlu_la-libssh2.lo `test -f 'vssh/libssh2.c' || echo '$(srcdir)/'`vssh/libssh2.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurlu_la-libssh2.Tpo vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vssh/libssh2.c' object='vssh/libcurlu_la-libssh2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vssh/libcurlu_la-libssh2.lo `test -f 'vssh/libssh2.c' || echo '$(srcdir)/'`vssh/libssh2.c
+
+vssh/libcurlu_la-libssh.lo: vssh/libssh.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vssh/libcurlu_la-libssh.lo -MD -MP -MF vssh/$(DEPDIR)/libcurlu_la-libssh.Tpo -c -o vssh/libcurlu_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurlu_la-libssh.Tpo vssh/$(DEPDIR)/libcurlu_la-libssh.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vssh/libssh.c' object='vssh/libcurlu_la-libssh.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vssh/libcurlu_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
 clean-libtool:
 	-rm -rf .libs _libs
 	-rm -rf vauth/.libs vauth/_libs
+	-rm -rf vquic/.libs vquic/_libs
+	-rm -rf vssh/.libs vssh/_libs
 	-rm -rf vtls/.libs vtls/_libs
 
 ID: $(am__tagged_files)
@@ -3598,6 +3687,10 @@ distclean-generic:
 	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
 	-rm -f vauth/$(DEPDIR)/$(am__dirstamp)
 	-rm -f vauth/$(am__dirstamp)
+	-rm -f vquic/$(DEPDIR)/$(am__dirstamp)
+	-rm -f vquic/$(am__dirstamp)
+	-rm -f vssh/$(DEPDIR)/$(am__dirstamp)
+	-rm -f vssh/$(am__dirstamp)
 	-rm -f vtls/$(DEPDIR)/$(am__dirstamp)
 	-rm -f vtls/$(am__dirstamp)
 
@@ -3704,8 +3797,6 @@ distclean: distclean-am
 	-rm -f ./$(DEPDIR)/libcurl_la-socks_sspi.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-speedcheck.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-splay.Plo
-	-rm -f ./$(DEPDIR)/libcurl_la-ssh-libssh.Plo
-	-rm -f ./$(DEPDIR)/libcurl_la-ssh.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-strcase.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-strdup.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-strerror.Plo
@@ -3816,8 +3907,6 @@ distclean: distclean-am
 	-rm -f ./$(DEPDIR)/libcurlu_la-socks_sspi.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-speedcheck.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-splay.Plo
-	-rm -f ./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo
-	-rm -f ./$(DEPDIR)/libcurlu_la-ssh.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-strcase.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-strdup.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-strerror.Plo
@@ -3858,6 +3947,14 @@ distclean: distclean-am
 	-rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo
 	-rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo
 	-rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo
+	-rm -f vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo
+	-rm -f vquic/$(DEPDIR)/libcurl_la-quiche.Plo
+	-rm -f vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo
+	-rm -f vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
+	-rm -f vssh/$(DEPDIR)/libcurl_la-libssh.Plo
+	-rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
+	-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo
+	-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo
 	-rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo
 	-rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo
 	-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
@@ -4023,8 +4120,6 @@ maintainer-clean: maintainer-clean-am
 	-rm -f ./$(DEPDIR)/libcurl_la-socks_sspi.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-speedcheck.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-splay.Plo
-	-rm -f ./$(DEPDIR)/libcurl_la-ssh-libssh.Plo
-	-rm -f ./$(DEPDIR)/libcurl_la-ssh.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-strcase.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-strdup.Plo
 	-rm -f ./$(DEPDIR)/libcurl_la-strerror.Plo
@@ -4135,8 +4230,6 @@ maintainer-clean: maintainer-clean-am
 	-rm -f ./$(DEPDIR)/libcurlu_la-socks_sspi.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-speedcheck.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-splay.Plo
-	-rm -f ./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo
-	-rm -f ./$(DEPDIR)/libcurlu_la-ssh.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-strcase.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-strdup.Plo
 	-rm -f ./$(DEPDIR)/libcurlu_la-strerror.Plo
@@ -4177,6 +4270,14 @@ maintainer-clean: maintainer-clean-am
 	-rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo
 	-rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo
 	-rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo
+	-rm -f vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo
+	-rm -f vquic/$(DEPDIR)/libcurl_la-quiche.Plo
+	-rm -f vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo
+	-rm -f vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
+	-rm -f vssh/$(DEPDIR)/libcurl_la-libssh.Plo
+	-rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
+	-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo
+	-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo
 	-rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo
 	-rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo
 	-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
@@ -4244,7 +4345,7 @@ uninstall-am: uninstall-libLTLIBRARIES
 
 checksrc:
 	$(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \
-	$(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch])
+	$(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch] $(srcdir)/vquic/*.[ch] $(srcdir)/vssh/*.[ch])
 
 # for debug builds, we scan the sources on all regular make invokes
 @CURLDEBUG_TRUE@all-local: checksrc
diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc
index 37f7026818..3e3a385c59 100644
--- a/libs/libcurl/src/Makefile.inc
+++ b/libs/libcurl/src/Makefile.inc
@@ -37,6 +37,12 @@ LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h                \
   vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h          \
   vtls/mbedtls.h vtls/mesalink.h
 
+LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
+
+LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
+
+LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c
+
 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         \
@@ -46,7 +52,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
   http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c    \
   strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c         \
   inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c      \
-  ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c        \
+  curl_addrinfo.c socks_gssapi.c socks_sspi.c                           \
   curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c    \
   pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c        \
   openldap.c curl_gethostname.c gopher.c idn_win32.c                    \
@@ -76,9 +82,11 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
   x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h           \
   curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h     \
   curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h        \
-  curl_get_line.h altsvc.h
+  curl_get_line.h altsvc.h quic.h
 
 LIB_RCFILES = libcurl.rc
 
-CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES)
-HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES)
+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)
diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c
index 85a4e01b50..a649fefd80 100644
--- a/libs/libcurl/src/altsvc.c
+++ b/libs/libcurl/src/altsvc.c
@@ -54,10 +54,13 @@ static enum alpnid alpn2alpnid(char *name)
     return ALPN_h1;
   if(strcasecompare(name, "h2"))
     return ALPN_h2;
-  if(strcasecompare(name, "h2c"))
-    return ALPN_h2c;
+#if (defined(USE_QUICHE) || defined(USE_NGHTTP2)) && !defined(UNITTESTS)
+  if(strcasecompare(name, "h3-22"))
+    return ALPN_h3;
+#else
   if(strcasecompare(name, "h3"))
     return ALPN_h3;
+#endif
   return ALPN_none; /* unknown, probably rubbish input */
 }
 
@@ -69,10 +72,12 @@ const char *Curl_alpnid2str(enum alpnid id)
     return "h1";
   case ALPN_h2:
     return "h2";
-  case ALPN_h2c:
-    return "h2c";
   case ALPN_h3:
+#if (defined(USE_QUICHE) || defined(USE_NGHTTP2)) && !defined(UNITTESTS)
+    return "h3-22";
+#else
     return "h3";
+#endif
   default:
     return ""; /* bad */
   }
@@ -81,8 +86,8 @@ const char *Curl_alpnid2str(enum alpnid id)
 
 static void altsvc_free(struct altsvc *as)
 {
-  free(as->srchost);
-  free(as->dsthost);
+  free(as->src.host);
+  free(as->dst.host);
   free(as);
 }
 
@@ -97,17 +102,17 @@ static struct altsvc *altsvc_createid(const char *srchost,
   if(!as)
     return NULL;
 
-  as->srchost = strdup(srchost);
-  if(!as->srchost)
+  as->src.host = strdup(srchost);
+  if(!as->src.host)
     goto error;
-  as->dsthost = strdup(dsthost);
-  if(!as->dsthost)
+  as->dst.host = strdup(dsthost);
+  if(!as->dst.host)
     goto error;
 
-  as->srcalpnid = srcalpnid;
-  as->dstalpnid = dstalpnid;
-  as->srcport = curlx_ultous(srcport);
-  as->dstport = curlx_ultous(dstport);
+  as->src.alpnid = srcalpnid;
+  as->dst.alpnid = dstalpnid;
+  as->src.port = curlx_ultous(srcport);
+  as->dst.port = curlx_ultous(dstport);
 
   return as;
   error:
@@ -226,8 +231,8 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
           "\"%d%02d%02d "
           "%02d:%02d:%02d\" "
           "%u %d\n",
-          Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport,
-          Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport,
+          Curl_alpnid2str(as->src.alpnid), as->src.host, as->src.port,
+          Curl_alpnid2str(as->dst.alpnid), as->dst.host, as->dst.port,
           stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
           stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
           as->persist, as->prio);
@@ -252,7 +257,7 @@ struct altsvcinfo *Curl_altsvc_init(void)
 #ifdef USE_NGHTTP2
     | CURLALTSVC_H2
 #endif
-#ifdef USE_HTTP3
+#ifdef ENABLE_QUIC
     | CURLALTSVC_H3
 #endif
     ;
@@ -343,7 +348,7 @@ static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
   while(*p && ISBLANK(*p))
     p++;
   protop = p;
-  while(*p && ISALNUM(*p))
+  while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '='))
     p++;
   len = p - protop;
 
@@ -365,9 +370,9 @@ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
   for(e = asi->list.head; e; e = n) {
     struct altsvc *as = e->ptr;
     n = e->next;
-    if((srcalpnid == as->srcalpnid) &&
-       (srcport == as->srcport) &&
-       strcasecompare(srchost, as->srchost)) {
+    if((srcalpnid == as->src.alpnid) &&
+       (srcport == as->src.port) &&
+       strcasecompare(srchost, as->src.host)) {
       Curl_llist_remove(&asi->list, e, NULL);
       altsvc_free(as);
       asi->num--;
@@ -535,31 +540,31 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
 bool Curl_altsvc_lookup(struct altsvcinfo *asi,
                         enum alpnid srcalpnid, const char *srchost,
                         int srcport,
-                        enum alpnid *dstalpnid, const char **dsthost,
-                        int *dstport)
+                        struct altsvc **dstentry,
+                        const int versions) /* one or more bits */
 {
   struct curl_llist_element *e;
   struct curl_llist_element *n;
   time_t now = time(NULL);
   DEBUGASSERT(asi);
   DEBUGASSERT(srchost);
-  DEBUGASSERT(dsthost);
+  DEBUGASSERT(dstentry);
 
   for(e = asi->list.head; e; e = n) {
     struct altsvc *as = e->ptr;
     n = e->next;
     if(as->expires < now) {
       /* an expired entry, remove */
+      Curl_llist_remove(&asi->list, e, NULL);
       altsvc_free(as);
       continue;
     }
-    if((as->srcalpnid == srcalpnid) &&
-       strcasecompare(as->srchost, srchost) &&
-       as->srcport == srcport) {
+    if((as->src.alpnid == srcalpnid) &&
+       strcasecompare(as->src.host, srchost) &&
+       (as->src.port == srcport) &&
+       (versions & as->dst.alpnid)) {
       /* match */
-      *dstalpnid = as->dstalpnid;
-      *dsthost = as->dsthost;
-      *dstport = as->dstport;
+      *dstentry = as;
       return TRUE;
     }
   }
diff --git a/libs/libcurl/src/altsvc.h b/libs/libcurl/src/altsvc.h
index eefb45bf61..99d0499af7 100644
--- a/libs/libcurl/src/altsvc.h
+++ b/libs/libcurl/src/altsvc.h
@@ -28,20 +28,21 @@
 #include "llist.h"
 
 enum alpnid {
-  ALPN_none,
-  ALPN_h1,
-  ALPN_h2,
-  ALPN_h2c,
-  ALPN_h3
+  ALPN_none = 0,
+  ALPN_h1 = CURLALTSVC_H1,
+  ALPN_h2 = CURLALTSVC_H2,
+  ALPN_h3 = CURLALTSVC_H3
+};
+
+struct althost {
+  char *host;
+  unsigned short port;
+  enum alpnid alpnid;
 };
 
 struct altsvc {
-  char *srchost;
-  char *dsthost;
-  unsigned short srcport;
-  unsigned short dstport;
-  enum alpnid srcalpnid;
-  enum alpnid dstalpnid;
+  struct althost src;
+  struct althost dst;
   time_t expires;
   bool persist;
   int prio;
@@ -68,8 +69,8 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
 bool Curl_altsvc_lookup(struct altsvcinfo *asi,
                         enum alpnid srcalpnid, const char *srchost,
                         int srcport,
-                        enum alpnid *dstalpnid, const char **dsthost,
-                        int *dstport);
+                        struct altsvc **dstentry,
+                        int versions); /* one or more CURLALTSVC_H* bits */
 #else
 /* disabled */
 #define Curl_altsvc_save(a,b)
diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c
index 6b14aa6981..835cfa48fa 100644
--- a/libs/libcurl/src/asyn-ares.c
+++ b/libs/libcurl/src/asyn-ares.c
@@ -253,16 +253,14 @@ static void destroy_async_data(struct Curl_async *async)
  */
 
 int Curl_resolver_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
-
+                          curl_socket_t *socks)
 {
   struct timeval maxtime;
   struct timeval timebuf;
   struct timeval *timeout;
   long milli;
   int max = ares_getsock((ares_channel)conn->data->state.resolver,
-                         (ares_socket_t *)socks, numsocks);
+                         (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
 
   maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
   maxtime.tv_usec = 0;
diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c
index 55e0811c5c..24da748850 100644
--- a/libs/libcurl/src/asyn-thread.c
+++ b/libs/libcurl/src/asyn-thread.c
@@ -163,6 +163,10 @@ struct thread_sync_data {
   char *hostname;        /* hostname to resolve, Curl_async.hostname
                             duplicate */
   int port;
+#ifdef HAVE_SOCKETPAIR
+  struct connectdata *conn;
+  curl_socket_t sock_pair[2]; /* socket pair */
+#endif
   int sock_error;
   Curl_addrinfo *res;
 #ifdef HAVE_GETADDRINFO
@@ -197,6 +201,15 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
   if(tsd->res)
     Curl_freeaddrinfo(tsd->res);
 
+#ifdef HAVE_SOCKETPAIR
+  /*
+   * close one end of the socket pair (may be done in resolver thread);
+   * the other end (for reading) is always closed in the parent thread.
+   */
+  if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
+    sclose(tsd->sock_pair[1]);
+  }
+#endif
   memset(tsd, 0, sizeof(*tsd));
 }
 
@@ -230,6 +243,14 @@ int init_thread_sync_data(struct thread_data * td,
 
   Curl_mutex_init(tsd->mtx);
 
+#ifdef HAVE_SOCKETPAIR
+  /* create socket pair */
+  if(socketpair(AF_LOCAL, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
+    tsd->sock_pair[0] = CURL_SOCKET_BAD;
+    tsd->sock_pair[1] = CURL_SOCKET_BAD;
+    goto err_exit;
+  }
+#endif
   tsd->sock_error = CURL_ASYNC_SUCCESS;
 
   /* Copying hostname string because original can be destroyed by parent
@@ -276,6 +297,9 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
   struct thread_data *td = tsd->td;
   char service[12];
   int rc;
+#ifdef HAVE_SOCKETPAIR
+  char buf[1];
+#endif
 
   msnprintf(service, sizeof(service), "%d", tsd->port);
 
@@ -298,6 +322,16 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
     free(td);
   }
   else {
+#ifdef HAVE_SOCKETPAIR
+    if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
+      /* DNS has been resolved, signal client task */
+      buf[0] = 1;
+      if(write(tsd->sock_pair[1],  buf, sizeof(buf)) < 0) {
+        /* update sock_erro to errno */
+        tsd->sock_error = SOCKERRNO;
+      }
+    }
+#endif
     tsd->done = 1;
     Curl_mutex_release(tsd->mtx);
   }
@@ -348,6 +382,10 @@ static void destroy_async_data(struct Curl_async *async)
   if(async->os_specific) {
     struct thread_data *td = (struct thread_data*) async->os_specific;
     int done;
+#ifdef HAVE_SOCKETPAIR
+    curl_socket_t sock_rd = td->tsd.sock_pair[0];
+    struct connectdata *conn = td->tsd.conn;
+#endif
 
     /*
      * if the thread is still blocking in the resolve syscall, detach it and
@@ -369,6 +407,15 @@ static void destroy_async_data(struct Curl_async *async)
 
       free(async->os_specific);
     }
+#ifdef HAVE_SOCKETPAIR
+    /*
+     * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
+     * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
+     */
+    if(conn)
+      Curl_multi_closed(conn->data, sock_rd);
+    sclose(sock_rd);
+#endif
   }
   async->os_specific = NULL;
 
@@ -569,8 +616,9 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
   }
   else {
     /* poll for name lookup done with exponential backoff up to 250ms */
-    timediff_t elapsed = Curl_timediff(Curl_now(),
-                                       data->progress.t_startsingle);
+    /* should be fine even if this converts to 32 bit */
+    time_t elapsed = (time_t)Curl_timediff(Curl_now(),
+                                           data->progress.t_startsingle);
     if(elapsed < 0)
       elapsed = 0;
 
@@ -592,26 +640,45 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
 }
 
 int Curl_resolver_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
+                          curl_socket_t *socks)
 {
+  int ret_val = 0;
   time_t milli;
   timediff_t ms;
   struct Curl_easy *data = conn->data;
   struct resdata *reslv = (struct resdata *)data->state.resolver;
+#ifdef HAVE_SOCKETPAIR
+  struct thread_data *td = (struct thread_data*)conn->async.os_specific;
+#else
   (void)socks;
-  (void)numsocks;
-  ms = Curl_timediff(Curl_now(), reslv->start);
-  if(ms < 3)
-    milli = 0;
-  else if(ms <= 50)
-    milli = ms/3;
-  else if(ms <= 250)
-    milli = 50;
-  else
-    milli = 200;
-  Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
-  return 0;
+#endif
+
+#ifdef HAVE_SOCKETPAIR
+  if(td) {
+    /* return read fd to client for polling the DNS resolution status */
+    socks[0] = td->tsd.sock_pair[0];
+    DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn);
+    td->tsd.conn = conn;
+    ret_val = GETSOCK_READSOCK(0);
+  }
+  else {
+#endif
+    ms = Curl_timediff(Curl_now(), reslv->start);
+    if(ms < 3)
+      milli = 0;
+    else if(ms <= 50)
+      milli = (time_t)ms/3;
+    else if(ms <= 250)
+      milli = 50;
+    else
+      milli = 200;
+    Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
+#ifdef HAVE_SOCKETPAIR
+  }
+#endif
+
+
+  return ret_val;
 }
 
 #ifndef HAVE_GETADDRINFO
@@ -706,7 +773,8 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
-  hints.ai_socktype = conn->socktype;
+  hints.ai_socktype = (conn->transport == TRNSPRT_TCP)?
+    SOCK_STREAM : SOCK_DGRAM;
 
   msnprintf(sbuf, sizeof(sbuf), "%d", port);
 
diff --git a/libs/libcurl/src/asyn.h b/libs/libcurl/src/asyn.h
index ccd4b1f7e2..081c3fef03 100644
--- a/libs/libcurl/src/asyn.h
+++ b/libs/libcurl/src/asyn.h
@@ -114,8 +114,7 @@ void Curl_resolver_kill(struct connectdata *conn);
  * return bitmask indicating what file descriptors (referring to array indexes
  * in the 'sock' array) to wait for, read/write.
  */
-int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
-                          int numsocks);
+int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock);
 
 /*
  * Curl_resolver_is_resolved()
diff --git a/libs/libcurl/src/base64.c b/libs/libcurl/src/base64.c
index fb081a6bb8..643cef6251 100644
--- a/libs/libcurl/src/base64.c
+++ b/libs/libcurl/src/base64.c
@@ -24,8 +24,8 @@
 
 #include "curl_setup.h"
 
-#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_LIBSSH2) || \
-  defined(USE_LIBSSH) || !defined(CURL_DISABLE_LDAP) || \
+#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \
+  !defined(CURL_DISABLE_LDAP) || \
   !defined(CURL_DISABLE_DOH) || defined(USE_SSL)
 
 #include "urldata.h" /* for the Curl_easy definition */
diff --git a/libs/libcurl/src/config-os400.h b/libs/libcurl/src/config-os400.h
index a741e91857..d14bd33917 100644
--- a/libs/libcurl/src/config-os400.h
+++ b/libs/libcurl/src/config-os400.h
@@ -434,6 +434,9 @@
 /* Define to enable alt-svc support (experimental) */
 #undef USE_ALTSVC
 
+/* Define to enable HTTP3 support (experimental, requires NGTCP2 or QUICHE) */
+#undef ENABLE_QUIC
+
 /* Version number of package */
 #undef VERSION
 
diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h
new file mode 100644
index 0000000000..70833a51dd
--- /dev/null
+++ b/libs/libcurl/src/config-plan9.h
@@ -0,0 +1,217 @@
+#ifndef HEADER_CURL_CONFIG_PLAN9_H
+#define HEADER_CURL_CONFIG_PLAN9_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * 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.
+ *
+ ***************************************************************************/
+
+#define BUILDING_LIBCURL 1
+#define CURL_CA_BUNDLE "/sys/lib/tls/ca.pem"
+#define CURL_CA_PATH "/sys/lib/tls"
+#define CURL_STATICLIB 1
+#define ENABLE_IPV6 1
+#define CURL_DISABLE_LDAP 1
+
+#define NEED_REENTRANT 1
+#define OS "plan9"
+#define PACKAGE "curl"
+#define PACKAGE_NAME "curl"
+#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.haxx.se/mail/"
+#define PACKAGE_STRING "curl -"
+#define PACKAGE_TARNAME "curl"
+#define PACKAGE_VERSION "-"
+#define RANDOM_FILE "/dev/random"
+#define VERSION "0.0.0" /* TODO */
+
+#define RETSIGTYPE void
+
+#define STDC_HEADERS 1
+
+#ifdef _BITS64
+#error not implement
+#else
+#define SIZEOF_INT 4
+#define SIZEOF_SHORT 2
+#define SIZEOF_LONG 4
+#define SIZEOF_OFF_T 8
+#define SIZEOF_CURL_OFF_T 4 /* curl_off_t = timediff_t = int */
+#define SIZEOF_SIZE_T 4
+#define SIZEOF_TIME_T 4
+#endif
+
+#define HAVE_GETNAMEINFO 1
+#define GETNAMEINFO_QUAL_ARG1 const
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+#define GETNAMEINFO_TYPE_ARG2 int
+#define GETNAMEINFO_TYPE_ARG46 long
+#define GETNAMEINFO_TYPE_ARG7 int
+
+#define HAVE_RECV 1
+#define RECV_TYPE_ARG1 int
+#define RECV_TYPE_ARG2 void *
+#define RECV_TYPE_ARG3 int
+#define RECV_TYPE_ARG4 int
+#define RECV_TYPE_RETV int
+
+#define HAVE_RECVFROM 1
+#define RECVFROM_TYPE_ARG1 int
+#define RECVFROM_TYPE_ARG2 void
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+#define RECVFROM_TYPE_ARG3 int
+#define RECVFROM_TYPE_ARG4 int
+#define RECVFROM_TYPE_ARG5 void
+#define RECVFROM_TYPE_ARG5_IS_VOID 1
+#define RECVFROM_TYPE_ARG6 int
+#define RECVFROM_TYPE_ARG6_IS_VOID 1
+#define RECVFROM_TYPE_RETV int
+
+#define HAVE_SELECT 1
+#define SELECT_TYPE_ARG1 int
+#define SELECT_TYPE_ARG234 fd_set *
+#define SELECT_TYPE_ARG5 struct timeval *
+#define SELECT_TYPE_RETV int
+
+#define HAVE_SEND 1
+#define SEND_TYPE_ARG1 int
+#define SEND_TYPE_ARG2 void *
+#define SEND_QUAL_ARG2
+#define SEND_TYPE_ARG3 int
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV int
+
+#define HAVE_ALARM 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_ASSERT_H 1
+#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
+#define HAVE_FDOPEN 1
+#define HAVE_FORK 1
+#define HAVE_FREEADDRINFO 1
+#define HAVE_FTRUNCATE 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETEUID 1
+#define HAVE_GETHOSTBYADDR 1
+#define HAVE_GETHOSTBYNAME 1
+#define HAVE_GETHOSTNAME 1
+#define HAVE_GETPPID 1
+#define HAVE_GETPROTOBYNAME 1
+#define HAVE_GETPWUID 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_GMTIME_R 1
+#define HAVE_INET_ADDR 1
+#define HAVE_INET_NTOP 1
+#define HAVE_INET_PTON 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_IOCTL 1
+#define HAVE_LIBGEN_H 1
+#define HAVE_LIBSSL 1
+#define HAVE_LIBZ 1
+#define HAVE_LL 1
+#define HAVE_LOCALE_H 1
+#define HAVE_LOCALTIME_R 1
+#define HAVE_LONGLONG 1
+#define HAVE_NETDB_H 1
+#define HAVE_NETINET_IN_H 1
+#define HAVE_NETINET_TCP_H 1
+#define HAVE_PWD_H 1
+#define HAVE_SYS_SELECT_H 1
+
+#define USE_OPENSSL 1
+#define HAVE_OPENSSL_CRYPTO_H 1
+#define HAVE_OPENSSL_ENGINE_H 1
+#define HAVE_OPENSSL_ERR_H 1
+#define HAVE_OPENSSL_PEM_H 1
+#define HAVE_OPENSSL_PKCS12_H 1
+#define HAVE_OPENSSL_RSA_H 1
+#define HAVE_OPENSSL_SSL_H 1
+#define HAVE_OPENSSL_X509_H 1
+
+#define HAVE_PERROR 1
+#define HAVE_PIPE 1
+#define HAVE_POLL 1
+#define HAVE_POLL_FINE 1
+#define HAVE_POLL_H 1
+#define HAVE_PTHREAD_H 1
+#define HAVE_RAND_STATUS 1
+#define HAVE_SETJMP_H 1
+#define HAVE_SETLOCALE 1
+
+#define HAVE_SETSOCKOPT 1
+#define HAVE_SOCK_OPTS 1 /* for /sys/include/ape/sys/socket.h */
+
+#define HAVE_SIGACTION 1
+#define HAVE_SIGNAL 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_SIGSETJMP 1
+#define HAVE_SIG_ATOMIC_T 1
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+#define HAVE_SOCKET 1
+#define HAVE_SSL_GET_SHUTDOWN 1
+#define HAVE_STDBOOL_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDIO_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRCASECMP 1
+#define HAVE_STRDUP 1
+#define HAVE_STRING_H 1
+#define HAVE_STRNCASECMP 1
+#define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
+#define HAVE_STRTOLL 1
+#define HAVE_STRUCT_TIMEVAL 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_RESOURCE_H 1
+#define HAVE_SYS_SOCKET_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UIO_H 1
+#define HAVE_SYS_UN_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_TIME_H 1
+#define HAVE_UNAME 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UTIME 1
+#define HAVE_UTIME_H 1
+#define HAVE_WRITEV 1
+
+#define HAVE_ZLIB_H 1
+
+#define HAVE_POSIX_STRERROR_R 1
+#define HAVE_STRERROR_R 1
+#define STRERROR_R_TYPE_ARG3 int
+
+#define TIME_WITH_SYS_TIME 1
+#define USE_BLOCKING_SOCKETS 1
+#define USE_MANUAL 1
+
+#define __attribute__(x)
+
+#ifndef __cplusplus
+#undef inline
+#endif
+
+#endif /* HEADER_CURL_CONFIG_PLAN9_H */
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index 4a1f2c6406..77196250de 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -75,6 +75,8 @@
 #include "conncache.h"
 #include "multihandle.h"
 #include "system_win32.h"
+#include "quic.h"
+#include "socks.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -165,7 +167,7 @@ tcpkeepalive(struct Curl_easy *data,
 static CURLcode
 singleipconnect(struct connectdata *conn,
                 const Curl_addrinfo *ai, /* start connecting to this */
-                curl_socket_t *sock);
+                int sockindex);          /* 0 or 1 among the temp ones */
 
 /*
  * Curl_timeleft() returns the amount of milliseconds left allowed for the
@@ -595,7 +597,7 @@ static CURLcode trynextip(struct connectdata *conn,
       }
 
       if(ai) {
-        result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
+        result = singleipconnect(conn, ai, tempindex);
         if(result == CURLE_COULDNT_CONNECT) {
           ai = ai->ai_next;
           continue;
@@ -625,13 +627,10 @@ void Curl_persistconninfo(struct connectdata *conn)
   conn->data->info.conn_local_port = conn->local_port;
 }
 
-UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
-                             long *port);
-
 /* retrieves ip address and port from a sockaddr structure.
    note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
-UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
-                             long *port)
+bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
+                      char *addr, long *port)
 {
   struct sockaddr_in *si = NULL;
 #ifdef ENABLE_IPV6
@@ -639,6 +638,8 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
 #endif
 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
   struct sockaddr_un *su = NULL;
+#else
+  (void)salen;
 #endif
 
   switch(sa->sa_family) {
@@ -664,8 +665,12 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
 #endif
 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
     case AF_UNIX:
-      su = (struct sockaddr_un*)sa;
-      msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      if(salen > sizeof(sa_family_t)) {
+        su = (struct sockaddr_un*)sa;
+        msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      }
+      else
+        addr[0] = 0; /* socket with no name */
       *port = 0;
       return TRUE;
 #endif
@@ -683,8 +688,8 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
    connection */
 void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
 {
-  if(conn->socktype == SOCK_DGRAM)
-    /* there's no connection! */
+  if(conn->transport != TRNSPRT_TCP)
+    /* there's no TCP connection! */
     return;
 
 #if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
@@ -693,10 +698,11 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     char buffer[STRERROR_LEN];
     struct Curl_sockaddr_storage ssrem;
     struct Curl_sockaddr_storage ssloc;
-    curl_socklen_t len;
+    curl_socklen_t plen;
+    curl_socklen_t slen;
 #ifdef HAVE_GETPEERNAME
-    len = sizeof(struct Curl_sockaddr_storage);
-    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
+    plen = sizeof(struct Curl_sockaddr_storage);
+    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
       int error = SOCKERRNO;
       failf(data, "getpeername() failed with errno %d: %s",
             error, Curl_strerror(error, buffer, sizeof(buffer)));
@@ -704,9 +710,9 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     }
 #endif
 #ifdef HAVE_GETSOCKNAME
-    len = sizeof(struct Curl_sockaddr_storage);
+    slen = sizeof(struct Curl_sockaddr_storage);
     memset(&ssloc, 0, sizeof(ssloc));
-    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
+    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
       int error = SOCKERRNO;
       failf(data, "getsockname() failed with errno %d: %s",
             error, Curl_strerror(error, buffer, sizeof(buffer)));
@@ -714,8 +720,8 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     }
 #endif
 #ifdef HAVE_GETPEERNAME
-    if(!getaddressinfo((struct sockaddr*)&ssrem,
-                       conn->primary_ip, &conn->primary_port)) {
+    if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+                         conn->primary_ip, &conn->primary_port)) {
       failf(data, "ssrem inet_ntop() failed with errno %d: %s",
             errno, Curl_strerror(errno, buffer, sizeof(buffer)));
       return;
@@ -723,8 +729,8 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
 #endif
 #ifdef HAVE_GETSOCKNAME
-    if(!getaddressinfo((struct sockaddr*)&ssloc,
-                       conn->local_ip, &conn->local_port)) {
+    if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+                         conn->local_ip, &conn->local_port)) {
       failf(data, "ssloc inet_ntop() failed with errno %d: %s",
             errno, Curl_strerror(errno, buffer, sizeof(buffer)));
       return;
@@ -739,6 +745,58 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
   Curl_persistconninfo(conn);
 }
 
+/* after a TCP connection to the proxy has been verified, this function does
+   the next magic step.
+
+   Note: this function's sub-functions call failf()
+
+*/
+static CURLcode connected_proxy(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->bits.socksproxy) {
+#ifndef CURL_DISABLE_PROXY
+    /* for the secondary socket (FTP), use the "connect to host"
+     * but ignore the "connect to port" (use the secondary port)
+     */
+    const char * const host = conn->bits.httpproxy ?
+                              conn->http_proxy.host.name :
+                              conn->bits.conn_to_host ?
+                              conn->conn_to_host.name :
+                              sockindex == SECONDARYSOCKET ?
+                              conn->secondaryhostname : conn->host.name;
+    const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
+                     sockindex == SECONDARYSOCKET ? conn->secondary_port :
+                     conn->bits.conn_to_port ? conn->conn_to_port :
+                     conn->remote_port;
+    conn->bits.socksproxy_connecting = TRUE;
+    switch(conn->socks_proxy.proxytype) {
+    case CURLPROXY_SOCKS5:
+    case CURLPROXY_SOCKS5_HOSTNAME:
+      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
+                         host, port, sockindex, conn);
+      break;
+
+    case CURLPROXY_SOCKS4:
+    case CURLPROXY_SOCKS4A:
+      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
+                           conn);
+      break;
+
+    default:
+      failf(conn->data, "unknown proxytype option given");
+      result = CURLE_COULDNT_CONNECT;
+    } /* switch proxytype */
+    conn->bits.socksproxy_connecting = FALSE;
+#else
+  (void)sockindex;
+#endif /* CURL_DISABLE_PROXY */
+  }
+
+  return result;
+}
+
 /*
  * Curl_is_connected() checks if the socket has connected.
  */
@@ -781,6 +839,24 @@ CURLcode Curl_is_connected(struct connectdata *conn,
     if(conn->tempsock[i] == CURL_SOCKET_BAD)
       continue;
 
+#ifdef ENABLE_QUIC
+    if(conn->transport == TRNSPRT_QUIC) {
+      result = Curl_quic_is_connected(conn, i, connected);
+      if(result) {
+        error = SOCKERRNO;
+        goto error;
+      }
+      if(*connected) {
+        /* use this socket from now on */
+        conn->sock[sockindex] = conn->tempsock[i];
+        conn->ip_addr = conn->tempaddr[i];
+        conn->tempsock[i] = CURL_SOCKET_BAD;
+        connkeep(conn, "HTTP/3 default");
+      }
+      return result;
+    }
+#endif
+
 #ifdef mpeix
     /* Call this function once now, and ignore the results. We do this to
        "clear" the error state on the socket so that we can later read it
@@ -794,8 +870,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
     if(rc == 0) { /* no connection yet */
       error = 0;
       if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
-        infof(data, "After %ldms connect time, move on!\n",
-              conn->timeoutms_per_addr);
+        infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
+              "ms connect time, move on!\n", conn->timeoutms_per_addr);
         error = ETIMEDOUT;
       }
 
@@ -825,7 +901,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
         }
 
         /* see if we need to do any proxy magic first once we connected */
-        result = Curl_connected_proxy(conn, sockindex);
+        result = connected_proxy(conn, sockindex);
         if(result)
           return result;
 
@@ -844,6 +920,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
     else if(rc & CURL_CSELECT_ERR)
       (void)verifyconnect(conn->tempsock[i], &error);
 
+#ifdef ENABLE_QUIC
+    error:
+#endif
     /*
      * The connection failed here, we should attempt to connect to the "next
      * address" for the given host. But first remember the latest error.
@@ -861,11 +940,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
               Curl_strerror(error, buffer, sizeof(buffer)));
 
         conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
-                                   allow : allow / 2;
+          allow : allow / 2;
 
         status = trynextip(conn, sockindex, i);
-        if(status != CURLE_COULDNT_CONNECT
-            || conn->tempsock[other] == CURL_SOCKET_BAD)
+        if((status != CURLE_COULDNT_CONNECT) ||
+           conn->tempsock[other] == CURL_SOCKET_BAD)
           /* the last attempt failed and no other sockets remain open */
           result = status;
       }
@@ -1004,7 +1083,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
  */
 static CURLcode singleipconnect(struct connectdata *conn,
                                 const Curl_addrinfo *ai,
-                                curl_socket_t *sockp)
+                                int sockindex)
 {
   struct Curl_sockaddr_ex addr;
   int rc = -1;
@@ -1020,7 +1099,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
   int optval = 1;
 #endif
   char buffer[STRERROR_LEN];
-
+  curl_socket_t *sockp = &conn->tempsock[sockindex];
   *sockp = CURL_SOCKET_BAD;
 
   result = Curl_socket(conn, ai, &addr, &sockfd);
@@ -1031,8 +1110,8 @@ static CURLcode singleipconnect(struct connectdata *conn,
     return CURLE_OK;
 
   /* store remote address and port used in this connection attempt */
-  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
-                     ipaddress, &port)) {
+  if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen,
+                       ipaddress, &port)) {
     /* malformed address or bug in inet_ntop, try next address */
     failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
@@ -1099,8 +1178,8 @@ static CURLcode singleipconnect(struct connectdata *conn,
   if(conn->num_addr > 1)
     Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME);
 
-  /* Connect TCP sockets, bind UDP */
-  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
+  /* Connect TCP and QUIC sockets */
+  if(!isconnected && (conn->transport != TRNSPRT_UDP)) {
     if(conn->bits.tcp_fastopen) {
 #if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */
 #  if defined(HAVE_BUILTIN_AVAILABLE)
@@ -1146,6 +1225,16 @@ static CURLcode singleipconnect(struct connectdata *conn,
 
     if(-1 == rc)
       error = SOCKERRNO;
+#ifdef ENABLE_QUIC
+    else if(conn->transport == TRNSPRT_QUIC) {
+      /* pass in 'sockfd' separately since it hasn't been put into the
+         tempsock array at this point */
+      result = Curl_quic_connect(conn, sockfd, sockindex,
+                                 &addr.sa_addr, addr.addrlen);
+      if(result)
+        error = SOCKERRNO;
+    }
+#endif
   }
   else {
     *sockp = sockfd;
@@ -1219,7 +1308,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
 
   /* start connecting to first IP */
   while(conn->tempaddr[0]) {
-    result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
+    result = singleipconnect(conn, conn->tempaddr[0], 0);
     if(!result)
       break;
     conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
@@ -1386,8 +1475,9 @@ CURLcode Curl_socket(struct connectdata *conn,
    */
 
   addr->family = ai->ai_family;
-  addr->socktype = conn->socktype;
-  addr->protocol = conn->socktype == SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
+  addr->socktype = (conn->transport == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM;
+  addr->protocol = conn->transport != TRNSPRT_TCP ? IPPROTO_UDP :
+    ai->ai_protocol;
   addr->addrlen = ai->ai_addrlen;
 
   if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
diff --git a/libs/libcurl/src/connect.h b/libs/libcurl/src/connect.h
index 6a5c755cc1..b23085a98a 100644
--- a/libs/libcurl/src/connect.h
+++ b/libs/libcurl/src/connect.h
@@ -51,6 +51,9 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
 curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
                                   struct connectdata **connp);
 
+bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
+                      char *addr, long *port);
+
 /*
  * Check if a connection seems to be alive.
  */
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index 9a9e14d012..53ca40237f 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.c
@@ -819,22 +819,14 @@ Curl_cookie_add(struct Curl_easy *data,
           badcookie = TRUE;
         break;
       case 1:
-        /* This field got its explanation on the 23rd of May 2001 by
-           Andrés García:
-
-           flag: A TRUE/FALSE value indicating if all machines within a given
-           domain can access the variable. This value is set automatically by
-           the browser, depending on the value you set for the domain.
-
-           As far as I can see, it is set to true when the cookie says
+        /* flag: A TRUE/FALSE value indicating if all machines within a given
+           domain can access the variable. Set TRUE when the cookie says
            .domain.com and to false when the domain is complete www.domain.com
         */
         co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
         break;
       case 2:
-        /* It turns out, that sometimes the file format allows the path
-           field to remain not filled in, we try to detect this and work
-           around it! Andrés García made us aware of this... */
+        /* The file format allows the path field to remain not filled in */
         if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
           /* only if the path doesn't look like a boolean option! */
           co->path = strdup(ptr);
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index 871c664e55..e5abe77b9e 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -486,6 +486,15 @@
 /* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
 #undef HAVE_NGHTTP2_NGHTTP2_H
 
+/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */
+#undef HAVE_NGHTTP3_NGHTTP3_H
+
+/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */
+#undef HAVE_NGTCP2_NGTCP2_CRYPTO_H
+
+/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */
+#undef HAVE_NGTCP2_NGTCP2_H
+
 /* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE
    */
 #undef HAVE_OLD_GSSMIT
@@ -544,6 +553,9 @@
 /* Define to 1 if you have the <pwd.h> header file. */
 #undef HAVE_PWD_H
 
+/* Define to 1 if you have the <quiche.h> header file. */
+#undef HAVE_QUICHE_H
+
 /* Define to 1 if you have the `RAND_egd' function. */
 #undef HAVE_RAND_EGD
 
@@ -739,6 +751,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the `usleep' function. */
+#undef HAVE_USLEEP
+
 /* Define to 1 if you have the `utime' function. */
 #undef HAVE_UTIME
 
@@ -970,6 +985,15 @@
 /* if nghttp2 is in use */
 #undef USE_NGHTTP2
 
+/* if nghttp3 is in use */
+#undef USE_NGHTTP3
+
+/* if ngtcp2 is in use */
+#undef USE_NGTCP2
+
+/* if ngtcp2_crypto_openssl is in use */
+#undef USE_NGTCP2_CRYPTO_OPENSSL
+
 /* if NSS is enabled */
 #undef USE_NSS
 
@@ -979,6 +1003,9 @@
 /* if OpenSSL is in use */
 #undef USE_OPENSSL
 
+/* if quiche is in use */
+#undef USE_QUICHE
+
 /* to enable Windows native SSL/TLS support */
 #undef USE_SCHANNEL
 
diff --git a/libs/libcurl/src/curl_md4.h b/libs/libcurl/src/curl_md4.h
index 392203f9e3..82df708cee 100644
--- a/libs/libcurl/src/curl_md4.h
+++ b/libs/libcurl/src/curl_md4.h
@@ -24,14 +24,12 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#define MD4_DIGEST_LENGTH 16
 
 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
 
-#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
+#endif /* !defined(CURL_DISABLE_CRYPTO_AUTH) */
 
 #endif /* HEADER_CURL_MD4_H */
diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c
index 9e6fdcab2e..19f9b61d87 100644
--- a/libs/libcurl/src/curl_ntlm_core.c
+++ b/libs/libcurl/src/curl_ntlm_core.c
@@ -55,11 +55,6 @@
 #ifdef USE_OPENSSL
 
 #  include <openssl/des.h>
-#  ifndef OPENSSL_NO_MD4
-#    include <openssl/md4.h>
-#  else
-#    include "curl_md4.h"
-#  endif
 #  include <openssl/md5.h>
 #  include <openssl/ssl.h>
 #  include <openssl/rand.h>
@@ -79,29 +74,23 @@
 #elif defined(USE_GNUTLS_NETTLE)
 
 #  include <nettle/des.h>
-#  include <nettle/md4.h>
 
 #elif defined(USE_GNUTLS)
 
 #  include <gcrypt.h>
 #  define MD5_DIGEST_LENGTH 16
-#  define MD4_DIGEST_LENGTH 16
 
 #elif defined(USE_NSS)
 
 #  include <nss.h>
 #  include <pk11pub.h>
 #  include <hasht.h>
-#  include "curl_md4.h"
 #  define MD5_DIGEST_LENGTH MD5_LENGTH
 
 #elif defined(USE_MBEDTLS)
 
 #  include <mbedtls/des.h>
-#  include <mbedtls/md4.h>
-#  if !defined(MBEDTLS_MD4_C)
-#    include "curl_md4.h"
-#  endif
+#  include "curl_md4.h"
 
 #elif defined(USE_SECTRANSP)
 
@@ -110,7 +99,6 @@
 
 #elif defined(USE_OS400CRYPTO)
 #  include "cipher.mih"  /* mih/cipher */
-#  include "curl_md4.h"
 #elif defined(USE_WIN32_CRYPTO)
 #  include <wincrypt.h>
 #else
@@ -126,6 +114,7 @@
 #include "warnless.h"
 #include "curl_endian.h"
 #include "curl_des.h"
+#include "curl_md4.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -552,7 +541,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
   CURLcode result;
   if(len > SIZE_T_MAX/2) /* avoid integer overflow */
     return CURLE_OUT_OF_MEMORY;
-  pw = len ? malloc(len * 2) : strdup("");
+  pw = len ? malloc(len * 2) : (unsigned char *)strdup("");
   if(!pw)
     return CURLE_OUT_OF_MEMORY;
 
@@ -566,57 +555,10 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
   if(result)
     return result;
 
-  {
-    /* Create NT hashed password. */
-#ifdef USE_OPENSSL
-#if !defined(OPENSSL_NO_MD4)
-    MD4_CTX MD4pw;
-    MD4_Init(&MD4pw);
-    MD4_Update(&MD4pw, pw, 2 * len);
-    MD4_Final(ntbuffer, &MD4pw);
-#else
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#endif
-#elif defined(USE_GNUTLS_NETTLE)
-    struct md4_ctx MD4pw;
-    md4_init(&MD4pw);
-    md4_update(&MD4pw, (unsigned int)(2 * len), pw);
-    md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
-#elif defined(USE_GNUTLS)
-    gcry_md_hd_t MD4pw;
-    gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
-    gcry_md_write(MD4pw, pw, 2 * len);
-    memcpy(ntbuffer, gcry_md_read(MD4pw, 0), MD4_DIGEST_LENGTH);
-    gcry_md_close(MD4pw);
-#elif defined(USE_NSS)
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#elif defined(USE_MBEDTLS)
-#if defined(MBEDTLS_MD4_C)
-    mbedtls_md4(pw, 2 * len, ntbuffer);
-#else
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#endif
-#elif defined(USE_SECTRANSP)
-    (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
-#elif defined(USE_OS400CRYPTO)
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#elif defined(USE_WIN32_CRYPTO)
-    HCRYPTPROV hprov;
-    if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
-                           CRYPT_VERIFYCONTEXT)) {
-      HCRYPTHASH hhash;
-      if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
-        DWORD length = 16;
-        CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
-        CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
-        CryptDestroyHash(hhash);
-      }
-      CryptReleaseContext(hprov, 0);
-    }
-#endif
+  /* Create NT hashed password. */
+  Curl_md4it(ntbuffer, pw, 2 * len);
 
-    memset(ntbuffer + 16, 0, 21 - 16);
-  }
+  memset(ntbuffer + 16, 0, 21 - 16);
 
   free(pw);
 
diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c
index 85dddcef1b..f429634630 100644
--- a/libs/libcurl/src/curl_path.c
+++ b/libs/libcurl/src/curl_path.c
@@ -55,7 +55,7 @@ CURLcode Curl_getworkingpath(struct connectdata *conn,
     }
     if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
       /* It is referenced to the home directory, so strip the leading '/~/' */
-      memcpy(real_path, working_path + 3, 4 + working_path_len-3);
+      memcpy(real_path, working_path + 3, working_path_len - 2);
     else
       memcpy(real_path, working_path, 1 + working_path_len);
   }
diff --git a/libs/libcurl/src/curl_rtmp.c b/libs/libcurl/src/curl_rtmp.c
index 16b1de1ae4..df8f2b1d95 100644
--- a/libs/libcurl/src/curl_rtmp.c
+++ b/libs/libcurl/src/curl_rtmp.c
@@ -199,13 +199,13 @@ static CURLcode rtmp_setup_connection(struct connectdata *conn)
     RTMP_Free(r);
     return CURLE_URL_MALFORMAT;
   }
-  conn->proto.generic = r;
+  conn->proto.rtmp = r;
   return CURLE_OK;
 }
 
 static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   SET_RCVTIMEO(tv, 10);
 
   r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
@@ -240,7 +240,7 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
 static CURLcode rtmp_do(struct connectdata *conn, bool *done)
 {
   struct Curl_easy *data = conn->data;
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
 
   if(!RTMP_ConnectStream(r, 0))
     return CURLE_FAILED_INIT;
@@ -268,10 +268,10 @@ static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
 static CURLcode rtmp_disconnect(struct connectdata *conn,
                                 bool dead_connection)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   (void)dead_connection;
   if(r) {
-    conn->proto.generic = NULL;
+    conn->proto.rtmp = NULL;
     RTMP_Close(r);
     RTMP_Free(r);
   }
@@ -281,7 +281,7 @@ static CURLcode rtmp_disconnect(struct connectdata *conn,
 static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
                          size_t len, CURLcode *err)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   ssize_t nread;
 
   (void)sockindex; /* unused */
@@ -302,7 +302,7 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
 static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
                          const void *buf, size_t len, CURLcode *err)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   ssize_t num;
 
   (void)sockindex; /* unused */
diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c
index 018e4228b3..0aa1f5bb7a 100644
--- a/libs/libcurl/src/curl_sasl.c
+++ b/libs/libcurl/src/curl_sasl.c
@@ -370,8 +370,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
       sasl->authused = SASL_MECH_PLAIN;
 
       if(force_ir || data->set.sasl_ir)
-        result = Curl_auth_create_plain_message(data, NULL, conn->user,
-                                                conn->passwd, &resp, &len);
+        result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+                                                conn->user, conn->passwd,
+                                                &resp, &len);
     }
     else if(enabledmechs & SASL_MECH_LOGIN) {
       mech = SASL_MECH_STRING_LOGIN;
@@ -453,8 +454,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
     *progress = SASL_DONE;
     return result;
   case SASL_PLAIN:
-    result = Curl_auth_create_plain_message(data, NULL, conn->user,
-                                            conn->passwd, &resp, &len);
+    result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+                                            conn->user, conn->passwd,
+                                            &resp, &len);
     break;
   case SASL_LOGIN:
     result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h
index 27414a540e..13af8cdec9 100644
--- a/libs/libcurl/src/curl_setup.h
+++ b/libs/libcurl/src/curl_setup.h
@@ -96,6 +96,10 @@
 #  include "config-vxworks.h"
 #endif
 
+#ifdef __PLAN9__
+#  include "config-plan9.h"
+#endif
+
 #endif /* HAVE_CONFIG_H */
 
 /* ================================================================ */
@@ -482,7 +486,6 @@
 #ifdef WIN32
 
 #  define DIR_CHAR      "\\"
-#  define DOT_CHAR      "_"
 
 #else /* WIN32 */
 
@@ -508,14 +511,6 @@
 #  endif
 
 #  define DIR_CHAR      "/"
-#  ifndef DOT_CHAR
-#    define DOT_CHAR      "."
-#  endif
-
-#  ifdef MSDOS
-#    undef DOT_CHAR
-#    define DOT_CHAR      "_"
-#  endif
 
 #  ifndef fileno /* sunos 4 have this as a macro! */
      int fileno(FILE *stream);
@@ -827,4 +822,8 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
 #define UNITTEST static
 #endif
 
+#if defined(USE_NGTCP2) || defined(USE_QUICHE)
+#define ENABLE_QUIC
+#endif
+
 #endif /* HEADER_CURL_SETUP_H */
diff --git a/libs/libcurl/src/doh.h b/libs/libcurl/src/doh.h
index 34bfa6f2ba..f522d33085 100644
--- a/libs/libcurl/src/doh.h
+++ b/libs/libcurl/src/doh.h
@@ -40,8 +40,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
 CURLcode Curl_doh_is_resolved(struct connectdata *conn,
                               struct Curl_dns_entry **dns);
 
-int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks,
-                     int numsocks);
+int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks);
 
 typedef enum {
   DOH_OK,
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index a4fff5b36e..0b0016be47 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -187,16 +187,8 @@ static CURLcode global_init(long flags, bool memoryfuncs)
 
   (void)Curl_ipv6works();
 
-#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
-  if(libssh2_init(0)) {
-    DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
-    return CURLE_FAILED_INIT;
-  }
-#endif
-
-#if defined(USE_LIBSSH)
-  if(ssh_init()) {
-    DEBUGF(fprintf(stderr, "Error: libssh_init failed\n"));
+#if defined(USE_SSH)
+  if(Curl_ssh_init()) {
     return CURLE_FAILED_INIT;
   }
 #endif
@@ -274,13 +266,7 @@ void curl_global_cleanup(void)
 
   Curl_amiga_cleanup();
 
-#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
-  (void)libssh2_exit();
-#endif
-
-#if defined(USE_LIBSSH)
-  (void)ssh_finalize();
-#endif
+  Curl_ssh_cleanup();
 
   init_flags  = 0;
 }
@@ -602,27 +588,11 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
 
   while(!done && !mcode) {
     int still_running = 0;
-    bool gotsocket = FALSE;
-
-    mcode = Curl_multi_wait(multi, NULL, 0, 1000, NULL, &gotsocket);
-
-    if(!mcode) {
-      if(!gotsocket) {
-        long sleep_ms;
-
-        /* If it returns without any filedescriptor instantly, we need to
-           avoid busy-looping during periods where it has nothing particular
-           to wait for */
-        curl_multi_timeout(multi, &sleep_ms);
-        if(sleep_ms) {
-          if(sleep_ms > 1000)
-            sleep_ms = 1000;
-          Curl_wait_ms((int)sleep_ms);
-        }
-      }
 
+    mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL);
+
+    if(!mcode)
       mcode = curl_multi_perform(multi, &still_running);
-    }
 
     /* only read 'still_running' if curl_multi_perform() return OK */
     if(!mcode && !still_running) {
@@ -942,6 +912,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
  */
 void curl_easy_reset(struct Curl_easy *data)
 {
+  long old_buffer_size = data->set.buffer_size;
+
   Curl_free_request_state(data);
 
   /* zero out UserDefined data: */
@@ -965,6 +937,18 @@ void curl_easy_reset(struct Curl_easy *data)
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
   Curl_http_auth_cleanup_digest(data);
 #endif
+
+  /* resize receive buffer */
+  if(old_buffer_size != data->set.buffer_size) {
+    char *newbuff = realloc(data->state.buffer, data->set.buffer_size + 1);
+    if(!newbuff) {
+      DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
+      /* nothing we can do here except use the old size */
+      data->set.buffer_size = old_buffer_size;
+    }
+    else
+      data->state.buffer = newbuff;
+  }
 }
 
 /*
@@ -1140,6 +1124,35 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
   return result;
 }
 
+/*
+ * Wrapper to call functions in Curl_conncache_foreach()
+ *
+ * Returns always 0.
+ */
+static int conn_upkeep(struct connectdata *conn,
+                       void *param)
+{
+  /* Param is unused. */
+  (void)param;
+
+  if(conn->handler->connection_check) {
+    /* Do a protocol-specific keepalive check on the connection. */
+    conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
+  }
+
+  return 0; /* continue iteration */
+}
+
+static CURLcode upkeep(struct conncache *conn_cache, void *data)
+{
+  /* Loop over every connection and make connection alive. */
+  Curl_conncache_foreach(data,
+                         conn_cache,
+                         data,
+                         conn_upkeep);
+  return CURLE_OK;
+}
+
 /*
  * Performs connection upkeep for the given session handle.
  */
@@ -1151,7 +1164,7 @@ CURLcode curl_easy_upkeep(struct Curl_easy *data)
 
   if(data->multi_easy) {
     /* Use the common function to keep connections alive. */
-    return Curl_upkeep(&data->multi_easy->conn_cache, data);
+    return upkeep(&data->multi_easy->conn_cache, data);
   }
   else {
     /* No connections, so just return success */
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index 76ebbc44f4..e807a2acde 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.c
@@ -132,10 +132,8 @@ static CURLcode ftp_connect(struct connectdata *conn, bool *done);
 static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
 static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
 static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
-static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                       int numsocks);
-static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
-                              int numsocks);
+static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks);
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode ftp_doing(struct connectdata *conn,
                           bool *dophase_done);
 static CURLcode ftp_setup_connection(struct connectdata * conn);
@@ -382,7 +380,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct pingpong *pp = &ftpc->pp;
   int result;
-  time_t timeout_ms;
+  timediff_t timeout_ms;
   ssize_t nread;
   int ftpcode;
 
@@ -493,7 +491,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
 static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
 {
   struct Curl_easy *data = conn->data;
-  time_t timeout_ms;
+  timediff_t timeout_ms;
   CURLcode result = CURLE_OK;
 
   *connected = FALSE;
@@ -810,21 +808,16 @@ static CURLcode ftp_state_pwd(struct connectdata *conn)
 
 /* For the FTP "protocol connect" and "doing" phases only */
 static int ftp_getsock(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks)
+                       curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks);
 }
 
 /* For the FTP "DO_MORE" phase only */
-static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
-                              int numsocks)
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   /* When in DO_MORE state, we could be either waiting for us to connect to a
    * remote site, or we could wait for that site to connect to us. Or just
    * handle ordinary commands.
@@ -856,7 +849,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
 
     return bits;
   }
-  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks);
 }
 
 /* This is called after the FTP_QUOTE state is passed.
diff --git a/libs/libcurl/src/getenv.c b/libs/libcurl/src/getenv.c
index 89d181de3c..e444a6a3ad 100644
--- a/libs/libcurl/src/getenv.c
+++ b/libs/libcurl/src/getenv.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,7 +35,7 @@ char *GetEnv(const char *variable)
   return NULL;
 #else
 #ifdef WIN32
-  char env[MAX_PATH]; /* MAX_PATH is from windef.h */
+  char env[4096];
   char *temp = getenv(variable);
   env[0] = '\0';
   if(temp != NULL)
diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c
index e118da80d4..2b8f2303e1 100644
--- a/libs/libcurl/src/getinfo.c
+++ b/libs/libcurl/src/getinfo.c
@@ -235,6 +235,9 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
     case 20:
       *param_longp = CURL_HTTP_VERSION_2_0;
       break;
+    case 30:
+      *param_longp = CURL_HTTP_VERSION_3;
+      break;
     default:
       *param_longp = CURL_HTTP_VERSION_NONE;
       break;
@@ -243,7 +246,6 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
   case CURLINFO_PROTOCOL:
     *param_longp = data->info.conn_protocol;
     break;
-
   default:
     return CURLE_UNKNOWN_OPTION;
   }
@@ -301,7 +303,9 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
   case CURLINFO_REDIRECT_TIME_T:
     *param_offt = data->progress.t_redirect;
     break;
-
+  case CURLINFO_RETRY_AFTER:
+    *param_offt = data->info.retry_after;
+    break;
   default:
     return CURLE_UNKNOWN_OPTION;
   }
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index cf33ed8f4d..bd532a891e 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -624,7 +624,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
                         const char *hostname,
                         int port,
                         struct Curl_dns_entry **entry,
-                        time_t timeoutms)
+                        timediff_t timeoutms)
 {
 #ifdef USE_ALARM_TIMEOUT
 #ifdef HAVE_SIGACTION
@@ -1027,19 +1027,17 @@ CURLcode Curl_resolv_check(struct connectdata *conn,
 }
 
 int Curl_resolv_getsock(struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks)
+                        curl_socket_t *socks)
 {
 #ifdef CURLRES_ASYNCH
   if(conn->data->set.doh)
     /* nothing to wait for during DOH resolve, those handles have their own
        sockets */
     return GETSOCK_BLANK;
-  return Curl_resolver_getsock(conn, socks, numsocks);
+  return Curl_resolver_getsock(conn, socks);
 #else
   (void)conn;
   (void)socks;
-  (void)numsocks;
   return GETSOCK_BLANK;
 #endif
 }
diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h
index 1bda524be4..e0597ea96a 100644
--- a/libs/libcurl/src/hostip.h
+++ b/libs/libcurl/src/hostip.h
@@ -25,6 +25,7 @@
 #include "curl_setup.h"
 #include "hash.h"
 #include "curl_addrinfo.h"
+#include "timeval.h" /* for timediff_t */
 #include "asyn.h"
 
 #ifdef HAVE_SETJMP_H
@@ -89,7 +90,7 @@ int Curl_resolv(struct connectdata *conn,
                 struct Curl_dns_entry **dnsentry);
 int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
                         int port, struct Curl_dns_entry **dnsentry,
-                        time_t timeoutms);
+                        timediff_t timeoutms);
 
 #ifdef CURLRES_IPV6
 /*
@@ -240,7 +241,6 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data);
 CURLcode Curl_resolv_check(struct connectdata *conn,
                            struct Curl_dns_entry **dns);
 int Curl_resolv_getsock(struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks);
+                        curl_socket_t *socks);
 
 #endif /* HEADER_CURL_HOSTIP_H */
diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c
index 5511f1aab1..e0e0c58dfa 100644
--- a/libs/libcurl/src/hostip6.c
+++ b/libs/libcurl/src/hostip6.c
@@ -165,7 +165,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
-  hints.ai_socktype = conn->socktype;
+  hints.ai_socktype = (conn->transport == TRNSPRT_TCP) ?
+    SOCK_STREAM : SOCK_DGRAM;
 
 #ifndef USE_RESOLVE_ON_IPS
   /*
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index 9fbd7201e8..28d1fa607d 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -88,8 +88,7 @@
  */
 
 static int http_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks);
+                           curl_socket_t *socks);
 static int http_should_fail(struct connectdata *conn);
 
 #ifndef CURL_DISABLE_PROXY
@@ -99,8 +98,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
 #ifdef USE_SSL
 static CURLcode https_connecting(struct connectdata *conn, bool *done);
 static int https_getsock(struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks);
+                         curl_socket_t *socks);
 #else
 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
 #endif
@@ -171,10 +169,22 @@ static CURLcode http_setup_conn(struct connectdata *conn)
   Curl_mime_initpart(&http->form, conn->data);
   data->req.protop = http;
 
-  if(!CONN_INUSE(conn))
-    /* if not already multi-using, setup connection details */
-    Curl_http2_setup_conn(conn);
-  Curl_http2_setup_req(data);
+  if(data->set.httpversion == CURL_HTTP_VERSION_3) {
+    if(conn->handler->flags & PROTOPT_SSL)
+      /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does
+         the QUIC dance. */
+      conn->transport = TRNSPRT_QUIC;
+    else {
+      failf(data, "HTTP/3 requested for non-HTTPS URL");
+      return CURLE_URL_MALFORMAT;
+    }
+  }
+  else {
+    if(!CONN_INUSE(conn))
+      /* if not already multi-using, setup connection details */
+      Curl_http2_setup_conn(conn);
+    Curl_http2_setup_req(data);
+  }
   return CURLE_OK;
 }
 
@@ -1136,10 +1146,14 @@ Curl_send_buffer *Curl_add_buffer_init(void)
  */
 void Curl_add_buffer_free(Curl_send_buffer **inp)
 {
-  Curl_send_buffer *in = *inp;
-  if(in) /* deal with NULL input */
+  Curl_send_buffer *in;
+  if(!inp)
+    return;
+  in = *inp;
+  if(in) { /* deal with NULL input */
     free(in->buffer);
-  free(in);
+    free(in);
+  }
   *inp = NULL;
 }
 
@@ -1497,11 +1511,9 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
    interface and then we're always _sending_ a request and thus we wait for
    the single socket to become writable only */
 static int http_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks)
+                           curl_socket_t *socks)
 {
   /* write mode */
-  (void)numsocks; /* unused, we trust it to be at least 1 */
   socks[0] = conn->sock[FIRSTSOCKET];
   return GETSOCK_WRITESOCK(0);
 }
@@ -1555,6 +1567,13 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
   CURLcode result;
   DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
 
+#ifdef ENABLE_QUIC
+  if(conn->transport == TRNSPRT_QUIC) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+#endif
+
   /* perform SSL initialization for this socket */
   result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
   if(result)
@@ -1564,11 +1583,10 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
 }
 
 static int https_getsock(struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks)
+                         curl_socket_t *socks)
 {
   if(conn->handler->flags & PROTOPT_SSL)
-    return Curl_ssl_getsock(conn, socks, numsocks);
+    return Curl_ssl_getsock(conn, socks);
   return GETSOCK_BLANK;
 }
 #endif /* USE_SSL */
@@ -1650,6 +1668,12 @@ static bool use_http_1_1plus(const struct Curl_easy *data,
 static const char *get_http_string(const struct Curl_easy *data,
                                    const struct connectdata *conn)
 {
+#ifdef ENABLE_QUIC
+  if((data->set.httpversion == CURL_HTTP_VERSION_3) ||
+     (conn->httpversion == 30))
+    return "3";
+#endif
+
 #ifdef USE_NGHTTP2
   if(conn->proto.httpc.h2)
     return "2";
@@ -1670,7 +1694,7 @@ static CURLcode expect100(struct Curl_easy *data,
   data->state.expect100header = FALSE; /* default to false unless it is set
                                           to TRUE below */
   if(use_http_1_1plus(data, conn) &&
-     (conn->httpversion != 20)) {
+     (conn->httpversion < 20)) {
     /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
        Expect: 100-continue to the headers which actually speeds up post
        operations (as there is one packet coming back from the web server) */
@@ -1700,7 +1724,7 @@ enum proxy_use {
    will return an error code if one of the headers is
    not formatted correctly */
 CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
-                                    Curl_send_buffer *buffer,
+                                    Curl_send_buffer **buffer,
                                     struct Curl_easy *handle)
 {
   char *ptr = NULL;
@@ -1726,7 +1750,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
     /* only add correctly formatted trailers */
     ptr = strchr(trailers->data, ':');
     if(ptr && *(ptr + 1) == ' ') {
-      result = Curl_add_bufferf(&buffer, "%s%s", trailers->data,
+      result = Curl_add_bufferf(buffer, "%s%s", trailers->data,
                                 endofline_native);
       if(result)
         return result;
@@ -1735,7 +1759,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
       infof(handle, "Malformatted trailing header ! Skipping trailer.");
     trailers = trailers->next;
   }
-  result = Curl_add_buffer(&buffer, endofline_network,
+  result = Curl_add_buffer(buffer, endofline_network,
                            strlen(endofline_network));
   return result;
 }
@@ -1851,7 +1875,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
                      Connection: */
                   checkprefix("Connection:", compare))
             ;
-          else if((conn->httpversion == 20) &&
+          else if((conn->httpversion >= 20) &&
                   checkprefix("Transfer-Encoding:", compare))
             /* HTTP/2 doesn't support chunked requests */
             ;
@@ -1982,55 +2006,57 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   const char *httpstring;
   Curl_send_buffer *req_buffer;
   curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
+  char *altused = NULL;
 
   /* Always consider the DO phase done after this function call, even if there
      may be parts of the request that is not yet sent, since we can deal with
      the rest of the request in the PERFORM phase. */
   *done = TRUE;
 
-  if(conn->httpversion < 20) { /* unless the connection is re-used and already
-                                  http2 */
-    switch(conn->negnpn) {
-    case CURL_HTTP_VERSION_2:
-      conn->httpversion = 20; /* we know we're on HTTP/2 now */
-
-      result = Curl_http2_switched(conn, NULL, 0);
-      if(result)
-        return result;
-      break;
-    case CURL_HTTP_VERSION_1_1:
-      /* continue with HTTP/1.1 when explicitly requested */
-      break;
-    default:
-      /* Check if user wants to use HTTP/2 with clear TCP*/
-#ifdef USE_NGHTTP2
-      if(conn->data->set.httpversion ==
-         CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
-        if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
-          /* We don't support HTTP/2 proxies yet. Also it's debatable whether
-             or not this setting should apply to HTTP/2 proxies. */
-          infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
-          break;
-        }
-
-        DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
-        conn->httpversion = 20;
+  if(conn->transport != TRNSPRT_QUIC) {
+    if(conn->httpversion < 20) { /* unless the connection is re-used and
+                                    already http2 */
+      switch(conn->negnpn) {
+      case CURL_HTTP_VERSION_2:
+        conn->httpversion = 20; /* we know we're on HTTP/2 now */
 
         result = Curl_http2_switched(conn, NULL, 0);
         if(result)
           return result;
-      }
+        break;
+      case CURL_HTTP_VERSION_1_1:
+        /* continue with HTTP/1.1 when explicitly requested */
+        break;
+      default:
+        /* Check if user wants to use HTTP/2 with clear TCP*/
+#ifdef USE_NGHTTP2
+        if(conn->data->set.httpversion ==
+           CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
+          if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
+            /* We don't support HTTP/2 proxies yet. Also it's debatable
+               whether or not this setting should apply to HTTP/2 proxies. */
+            infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
+            break;
+          }
+
+          DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
+          conn->httpversion = 20;
+
+          result = Curl_http2_switched(conn, NULL, 0);
+          if(result)
+            return result;
+        }
 #endif
-      break;
+        break;
+      }
+    }
+    else {
+      /* prepare for a http2 request */
+      result = Curl_http2_setup(conn);
+      if(result)
+        return result;
     }
   }
-  else {
-    /* prepare for a http2 request */
-    result = Curl_http2_setup(conn);
-    if(result)
-      return result;
-  }
-
   http = data->req.protop;
   DEBUGASSERT(http);
 
@@ -2226,14 +2252,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   else {
     if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
        (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
-       http->postsize < 0) ||
-       (data->set.upload && data->state.infilesize == -1))) {
+         http->postsize < 0) ||
+        ((data->set.upload || httpreq == HTTPREQ_POST) &&
+         data->state.infilesize == -1))) {
       if(conn->bits.authneg)
         /* don't enable chunked during auth neg */
         ;
       else if(use_http_1_1plus(data, conn)) {
-        /* HTTP, upload, unknown file size and not HTTP 1.0 */
-        data->req.upload_chunky = TRUE;
+        if(conn->httpversion < 20)
+          /* HTTP, upload, unknown file size and not HTTP 1.0 */
+          data->req.upload_chunky = TRUE;
       }
       else {
         failf(data, "Chunky upload is not supported by HTTP 1.0");
@@ -2334,7 +2362,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
 
     /* and no fragment part */
     CURLUcode uc;
-    char *url;
     CURLU *h = curl_url_dup(data->state.uh);
     if(!h)
       return CURLE_OUT_OF_MEMORY;
@@ -2365,19 +2392,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
         return CURLE_OUT_OF_MEMORY;
       }
     }
-    /* now extract the new version of the URL */
-    uc = curl_url_get(h, CURLUPART_URL, &url, 0);
+    /* Extract the the URL to use in the request. Store in STRING_TEMP_URL for
+       clean-up reasons if the function returns before the free() further
+       down. */
+    uc = curl_url_get(h, CURLUPART_URL, &data->set.str[STRING_TEMP_URL], 0);
     if(uc) {
       curl_url_cleanup(h);
       return CURLE_OUT_OF_MEMORY;
     }
 
-    if(data->change.url_alloc)
-      free(data->change.url);
-
-    data->change.url = url;
-    data->change.url_alloc = TRUE;
-
     curl_url_cleanup(h);
 
     if(strcasecompare("ftp", data->state.up.scheme)) {
@@ -2556,12 +2579,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     query = NULL;
   }
 
+#ifndef CURL_DISABLE_PROXY
   /* url */
   if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
-    char *url = data->change.url;
+    char *url = data->set.str[STRING_TEMP_URL];
     result = Curl_add_buffer(&req_buffer, url, strlen(url));
+    Curl_safefree(data->set.str[STRING_TEMP_URL]);
   }
-  else if(paste_ftp_userpwd)
+  else
+#endif
+  if(paste_ftp_userpwd)
     result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s",
                               conn->user, conn->passwd,
                               path + sizeof("ftp://") - 1);
@@ -2575,6 +2602,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   if(result)
     return result;
 
+#ifdef USE_ALTSVC
+  if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
+    altused = aprintf("Alt-Used: %s:%d\r\n",
+                      conn->conn_to_host.name, conn->conn_to_port);
+    if(!altused)
+      return CURLE_OUT_OF_MEMORY;
+  }
+#endif
   result =
     Curl_add_bufferf(&req_buffer,
                      "%s" /* ftp typecode (;type=x) */
@@ -2589,7 +2624,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                      "%s" /* accept-encoding */
                      "%s" /* referer */
                      "%s" /* Proxy-Connection */
-                     "%s",/* transfer-encoding */
+                     "%s" /* transfer-encoding */
+                     "%s",/* Alt-Used */
 
                      ftp_typecode,
                      httpstring,
@@ -2615,13 +2651,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
                       !conn->bits.tunnel_proxy &&
                       !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
                      "Proxy-Connection: Keep-Alive\r\n":"",
-                     te
+                     te,
+                     altused ? altused : ""
       );
 
   /* clear userpwd and proxyuserpwd to avoid re-using old credentials
    * from re-used connections */
   Curl_safefree(conn->allocptr.userpwd);
   Curl_safefree(conn->allocptr.proxyuserpwd);
+  free(altused);
 
   if(result)
     return result;
@@ -3660,6 +3698,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
          * guarantees on future behaviors since it isn't within the protocol.
          */
         char separator;
+        char twoorthree[2];
         nc = sscanf(HEADER1,
                     " HTTP/%1d.%1d%c%3d",
                     &httpversion_major,
@@ -3667,8 +3706,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
                     &separator,
                     &k->httpcode);
 
-        if(nc == 1 && httpversion_major == 2 &&
-           1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
+        if(nc == 1 && httpversion_major >= 2 &&
+           2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) {
           conn->httpversion = 0;
           nc = 4;
           separator = ' ';
@@ -3706,7 +3745,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
           }
         }
         else {
-          failf(data, "Unsupported HTTP version in response\n");
+          failf(data, "Unsupported HTTP version in response");
           return CURLE_UNSUPPORTED_PROTOCOL;
         }
       }
@@ -3935,6 +3974,19 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
       if(result)
         return result;
     }
+    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);
+      if(-1 == date) {
+        /* not a date, try it as a decimal number */
+        (void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
+      }
+      else
+        /* convert date to number of seconds into the future */
+        retry_after = date - time(NULL);
+      data->info.retry_after = retry_after; /* store it */
+    }
     else if(!k->http_bodyless && checkprefix("Content-Range:", k->p)) {
       /* Content-Range: bytes [num]-
          Content-Range: bytes: [num]-
diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h
index 72161f6b03..f0ddec7590 100644
--- a/libs/libcurl/src/http.h
+++ b/libs/libcurl/src/http.h
@@ -75,7 +75,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
                                  bool is_connect,
                                  Curl_send_buffer *req_buffer);
 CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
-                                    Curl_send_buffer *buffer,
+                                    Curl_send_buffer **buffer,
                                     struct Curl_easy *handle);
 
 /* protocol-specific functions set up to be called by the main engine */
@@ -126,6 +126,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn);
 
 #endif /* CURL_DISABLE_HTTP */
 
+#ifdef USE_NGHTTP3
+struct h3out; /* see ngtcp2 */
+#endif
+
 /****************************************************************************
  * HTTP unique setup
  ***************************************************************************/
@@ -172,19 +176,34 @@ struct HTTP {
   int status_code; /* HTTP status code */
   const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
   size_t pauselen; /* the number of bytes left in data */
-  bool closed; /* TRUE on HTTP2 stream close */
   bool close_handled; /* TRUE if stream closure is handled by libcurl */
+
+  char **push_headers;       /* allocated array */
+  size_t push_headers_used;  /* number of entries filled in */
+  size_t push_headers_alloc; /* number of entries allocated */
+#endif
+#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3)
+  bool closed; /* TRUE on HTTP2 stream close */
   char *mem;     /* points to a buffer in memory to store received data */
   size_t len;    /* size of the buffer 'mem' points to */
   size_t memlen; /* size of data copied to mem */
-
+#endif
+#if defined(USE_NGHTTP2) || defined(ENABLE_QUIC)
+  /* fields used by both HTTP/2 and HTTP/3 */
   const uint8_t *upload_mem; /* points to a buffer to read from */
   size_t upload_len; /* size of the buffer 'upload_mem' points to */
   curl_off_t upload_left; /* number of bytes left to upload */
+#endif
 
-  char **push_headers;       /* allocated array */
-  size_t push_headers_used;  /* number of entries filled in */
-  size_t push_headers_alloc; /* number of entries allocated */
+#ifdef ENABLE_QUIC
+  /*********** for HTTP/3 we store stream-local data here *************/
+  int64_t stream3_id; /* stream we are interested in */
+  bool firstbody;  /* FALSE until body arrives */
+  bool h3req;    /* FALSE until request is issued */
+  bool upload_done;
+#endif
+#ifdef USE_NGHTTP3
+  struct h3out *h3out; /* per-stream buffers for upload */
 #endif
 };
 
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index eb55e62d1c..31d2d698ad 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -100,16 +100,11 @@ void Curl_http2_init_userset(struct UserDefined *set)
 }
 
 static int http2_perform_getsock(const struct connectdata *conn,
-                                 curl_socket_t *sock, /* points to
-                                                         numsocks
-                                                         number of
-                                                         sockets */
-                                 int numsocks)
+                                 curl_socket_t *sock)
 {
   const struct http_conn *c = &conn->proto.httpc;
   struct SingleRequest *k = &conn->data->req;
   int bitmap = GETSOCK_BLANK;
-  (void)numsocks;
 
   sock[0] = conn->sock[FIRSTSOCKET];
 
@@ -126,11 +121,9 @@ static int http2_perform_getsock(const struct connectdata *conn,
 }
 
 static int http2_getsock(struct connectdata *conn,
-                         curl_socket_t *sock, /* points to numsocks
-                                                 number of sockets */
-                         int numsocks)
+                         curl_socket_t *socks)
 {
-  return http2_perform_getsock(conn, sock, numsocks);
+  return http2_perform_getsock(conn, socks);
 }
 
 /*
@@ -240,7 +233,7 @@ static unsigned int http2_conncheck(struct connectdata *check,
 
   if(checks_to_perform & CONNCHECK_KEEPALIVE) {
     struct curltime now = Curl_now();
-    time_t elapsed = Curl_timediff(now, check->keepalive);
+    timediff_t elapsed = Curl_timediff(now, check->keepalive);
 
     if(elapsed > check->upkeep_interval_ms) {
       /* Perform an HTTP/2 PING */
@@ -1566,6 +1559,11 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
   if(should_close_session(httpc)) {
     H2BUGF(infof(data,
                  "http2_recv: nothing to do in this session\n"));
+    if(conn->bits.close) {
+      /* already marked for closure, return OK and we're done */
+      *err = CURLE_OK;
+      return 0;
+    }
     *err = CURLE_HTTP2;
     return -1;
   }
@@ -1755,6 +1753,9 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
     else if(!stream->closed) {
       drained_transfer(data, httpc);
     }
+    else
+      /* this stream is closed, trigger a another read ASAP to detect that */
+      Curl_expire(data, 0, EXPIRE_RUN_NOW);
 
     return retlen;
   }
diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c
index c8f4064449..8e1f3bf685 100644
--- a/libs/libcurl/src/http_negotiate.c
+++ b/libs/libcurl/src/http_negotiate.c
@@ -148,10 +148,10 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
     }
     if(!neg_ctx->context) {
       result = Curl_input_negotiate(conn, proxy, "Negotiate");
-      if(result == CURLE_LOGIN_DENIED) {
+      if(result == CURLE_AUTH_ERROR) {
         /* negotiate auth failed, let's continue unauthenticated to stay
          * compatible with the behavior before curl-7_64_0-158-g6c6035532 */
-        conn->data->state.authproblem = TRUE;
+        authp->done = TRUE;
         return CURLE_OK;
       }
       else if(result)
diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c
index f3ffa290b4..ff9b629470 100644
--- a/libs/libcurl/src/imap.c
+++ b/libs/libcurl/src/imap.c
@@ -95,8 +95,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
 static CURLcode imap_connect(struct connectdata *conn, bool *done);
 static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
 static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
-static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
 static CURLcode imap_setup_connection(struct connectdata *conn);
 static char *imap_atom(const char *str, bool escape_only);
@@ -1392,10 +1391,9 @@ static CURLcode imap_init(struct connectdata *conn)
 }
 
 /* For the IMAP "protocol connect" and "doing" phases only */
-static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.imapc.pp, socks);
 }
 
 /***********************************************************************
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index c0adf43f54..9db8aa3107 100644
--- a/libs/libcurl/src/libcurl.plist
+++ b/libs/libcurl/src/libcurl.plist
@@ -15,7 +15,7 @@
 	<string>se.haxx.curl.libcurl</string>
 
 	<key>CFBundleVersion</key>
-	<string>7.65.3</string>
+	<string>7.66.0</string>
 
 	<key>CFBundleName</key>
 	<string>libcurl</string>
@@ -27,9 +27,9 @@
 	<string>????</string>
 
 	<key>CFBundleShortVersionString</key>
-	<string>libcurl 7.65.3</string>
+	<string>libcurl 7.66.0</string>
 
 	<key>CFBundleGetInfoString</key>
-	<string>libcurl.plist 7.65.3</string>
+	<string>libcurl.plist 7.66.0</string>
 </dict>
 </plist>
diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c
index 0b4ea9a3c3..bbf8975081 100644
--- a/libs/libcurl/src/md4.c
+++ b/libs/libcurl/src/md4.c
@@ -1,5 +1,223 @@
-/*
- * !checksrc! disable COPYRIGHT
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * 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"
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include "curl_md4.h"
+#include "warnless.h"
+
+#ifdef USE_OPENSSL
+#include <openssl/opensslconf.h>
+#endif
+#ifdef USE_MBEDTLS
+#include <mbedtls/config.h>
+#endif
+
+#if defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/md4.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct md4_ctx MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  md4_init(ctx);
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  md4_update(ctx, size, data);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  md4_digest(ctx, MD4_DIGEST_SIZE, result);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct gcry_md_hd_t MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_MD4, 0);
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  gcry_md_write(*ctx, data, size);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  memcpy(result, gcry_md_read(ctx, 0), MD4_DIGEST_LENGTH);
+  gcry_md_close(ctx);
+}
+
+#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
+/* When OpenSSL is available we use the MD4-functions from OpenSSL */
+#include <openssl/md4.h>
+
+#elif defined(USE_SECTRANSP)
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct {
+  void *data;
+  unsigned long size;
+} MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->data = NULL;
+  ctx->size = 0;
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  if(ctx->data == NULL) {
+    ctx->data = malloc(size);
+    if(ctx->data != NULL) {
+      memcpy(ctx->data, data, size);
+      ctx->size = size;
+    }
+  }
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  if(ctx->data != NULL) {
+    (void)CC_MD4(ctx->data, (CC_LONG) ctx->size, result);
+
+    Curl_safefree(ctx->data);
+    ctx->size = 0;
+  }
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+#include <wincrypt.h>
+
+#include "curl_memory.h"
+ /* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct {
+  HCRYPTPROV hCryptProv;
+  HCRYPTHASH hHash;
+} MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->hCryptProv = 0;
+  ctx->hHash = 0;
+
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                         CRYPT_VERIFYCONTEXT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
+  }
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  CryptHashData(ctx->hHash, data, (unsigned int) size, 0);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  unsigned long length = 0;
+
+  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+  if(length == MD4_DIGEST_LENGTH)
+    CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
+
+  if(ctx->hHash)
+    CryptDestroyHash(ctx->hHash);
+
+  if(ctx->hCryptProv)
+    CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
+
+#include <mbedtls/md4.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct {
+  void *data;
+  unsigned long size;
+} MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->data = NULL;
+  ctx->size = 0;
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  if(ctx->data == NULL) {
+    ctx->data = malloc(size);
+    if(ctx->data != NULL) {
+      memcpy(ctx->data, data, size);
+      ctx->size = size;
+    }
+  }
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  if(ctx->data != NULL) {
+    mbedtls_md4(ctx->data, ctx->size, result);
+
+    Curl_safefree(ctx->data);
+    ctx->size = 0;
+  }
+}
+
+#else
+/* When no other crypto library is available, or the crypto library doesn't
+ * support MD4, we use this code segment this implementation of it
+ *
  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
  * MD4 Message-Digest Algorithm (RFC 1320).
  *
@@ -36,26 +254,6 @@
  * compile-time configuration.
  */
 
-#include "curl_setup.h"
-
-#ifdef USE_OPENSSL
-#include <openssl/opensslconf.h>
-#endif
-#ifdef USE_MBEDTLS
-#include <mbedtls/config.h>
-#endif
-
-/* The NSS, OS/400, and when not included, OpenSSL and mbed TLS crypto
- * libraries do not provide the MD4 hash algorithm, so we use this
- * implementation of it */
-#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
-
-#include "curl_md4.h"
-#include "warnless.h"
-
-#ifndef HAVE_OPENSSL
 
 #include <string.h>
 
@@ -305,7 +503,7 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
   memset(ctx, 0, sizeof(*ctx));
 }
 
-#endif
+#endif /* CRYPTO LIBS */
 
 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
 {
@@ -315,6 +513,4 @@ void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
   MD4_Final(output, &ctx);
 }
 
-#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index 2b6b1bc522..2e91e4ff35 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -818,25 +818,27 @@ void Curl_attach_connnection(struct Curl_easy *data,
 }
 
 static int waitconnect_getsock(struct connectdata *conn,
-                               curl_socket_t *sock,
-                               int numsocks)
+                               curl_socket_t *sock)
 {
   int i;
   int s = 0;
   int rc = 0;
 
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
 #ifdef USE_SSL
   if(CONNECT_FIRSTSOCKET_PROXY_SSL())
-    return Curl_ssl_getsock(conn, sock, numsocks);
+    return Curl_ssl_getsock(conn, sock);
 #endif
 
   for(i = 0; i<2; i++) {
     if(conn->tempsock[i] != CURL_SOCKET_BAD) {
       sock[s] = conn->tempsock[i];
-      rc |= GETSOCK_WRITESOCK(s++);
+      rc |= GETSOCK_WRITESOCK(s);
+#ifdef ENABLE_QUIC
+      if(conn->transport == TRNSPRT_QUIC)
+        /* when connecting QUIC, we want to read the socket too */
+        rc |= GETSOCK_READSOCK(s);
+#endif
+      s++;
     }
   }
 
@@ -844,12 +846,8 @@ static int waitconnect_getsock(struct connectdata *conn,
 }
 
 static int waitproxyconnect_getsock(struct connectdata *conn,
-                                    curl_socket_t *sock,
-                                    int numsocks)
+                                    curl_socket_t *sock)
 {
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   sock[0] = conn->sock[FIRSTSOCKET];
 
   /* when we've sent a CONNECT to a proxy, we should rather wait for the
@@ -861,19 +859,37 @@ static int waitproxyconnect_getsock(struct connectdata *conn,
 }
 
 static int domore_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
+                          curl_socket_t *socks)
 {
   if(conn && conn->handler->domore_getsock)
-    return conn->handler->domore_getsock(conn, socks, numsocks);
+    return conn->handler->domore_getsock(conn, socks);
+  return GETSOCK_BLANK;
+}
+
+static int doing_getsock(struct connectdata *conn,
+                         curl_socket_t *socks)
+{
+  if(conn && conn->handler->doing_getsock)
+    return conn->handler->doing_getsock(conn, socks);
   return GETSOCK_BLANK;
 }
 
-/* returns bitmapped flags for this handle and its sockets */
+static int protocol_getsock(struct connectdata *conn,
+                            curl_socket_t *socks)
+{
+  if(conn->handler->proto_getsock)
+    return conn->handler->proto_getsock(conn, socks);
+  /* Backup getsock logic. Since there is a live socket in use, we must wait
+     for it or it will be removed from watching when the multi_socket API is
+     used. */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
+}
+
+/* returns bitmapped flags for this handle and its sockets. The 'socks[]'
+   array contains MAX_SOCKSPEREASYHANDLE entries. */
 static int multi_getsock(struct Curl_easy *data,
-                         curl_socket_t *socks, /* points to numsocks number
-                                                  of sockets */
-                         int numsocks)
+                         curl_socket_t *socks)
 {
   /* The no connection case can happen when this is called from
      curl_multi_remove_handle() => singlesocket() => multi_getsock().
@@ -905,30 +921,30 @@ static int multi_getsock(struct Curl_easy *data,
     return 0;
 
   case CURLM_STATE_WAITRESOLVE:
-    return Curl_resolv_getsock(data->conn, socks, numsocks);
+    return Curl_resolv_getsock(data->conn, socks);
 
   case CURLM_STATE_PROTOCONNECT:
   case CURLM_STATE_SENDPROTOCONNECT:
-    return Curl_protocol_getsock(data->conn, socks, numsocks);
+    return protocol_getsock(data->conn, socks);
 
   case CURLM_STATE_DO:
   case CURLM_STATE_DOING:
-    return Curl_doing_getsock(data->conn, socks, numsocks);
+    return doing_getsock(data->conn, socks);
 
   case CURLM_STATE_WAITPROXYCONNECT:
-    return waitproxyconnect_getsock(data->conn, socks, numsocks);
+    return waitproxyconnect_getsock(data->conn, socks);
 
   case CURLM_STATE_WAITCONNECT:
-    return waitconnect_getsock(data->conn, socks, numsocks);
+    return waitconnect_getsock(data->conn, socks);
 
   case CURLM_STATE_DO_MORE:
-    return domore_getsock(data->conn, socks, numsocks);
+    return domore_getsock(data->conn, socks);
 
   case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
                                to waiting for the same as the *PERFORM
                                states */
   case CURLM_STATE_PERFORM:
-    return Curl_single_getsock(data->conn, socks, numsocks);
+    return Curl_single_getsock(data->conn, socks);
   }
 
 }
@@ -954,7 +970,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
 
   data = multi->easyp;
   while(data) {
-    int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+    int bitmap = multi_getsock(data, sockbunch);
 
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
       curl_socket_t s = CURL_SOCKET_BAD;
@@ -984,12 +1000,12 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
 
 #define NUM_POLLS_ON_STACK 10
 
-CURLMcode Curl_multi_wait(struct Curl_multi *multi,
-                          struct curl_waitfd extra_fds[],
-                          unsigned int extra_nfds,
-                          int timeout_ms,
-                          int *ret,
-                          bool *gotsocket) /* if any socket was checked */
+static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
+                                 struct curl_waitfd extra_fds[],
+                                 unsigned int extra_nfds,
+                                 int timeout_ms,
+                                 int *ret,
+                                 bool extrawait) /* when no socket, wait */
 {
   struct Curl_easy *data;
   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
@@ -1003,9 +1019,6 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi,
   struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
   struct pollfd *ufds = &a_few_on_stack[0];
 
-  if(gotsocket)
-    *gotsocket = FALSE;
-
   if(!GOOD_MULTI_HANDLE(multi))
     return CURLM_BAD_HANDLE;
 
@@ -1015,7 +1028,7 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi,
   /* Count up how many fds we have from the multi handle */
   data = multi->easyp;
   while(data) {
-    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+    bitmap = multi_getsock(data, sockbunch);
 
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
       curl_socket_t s = CURL_SOCKET_BAD;
@@ -1065,7 +1078,7 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi,
     /* Add the curl handles to our pollfds first */
     data = multi->easyp;
     while(data) {
-      bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+      bitmap = multi_getsock(data, sockbunch);
 
       for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
         curl_socket_t s = CURL_SOCKET_BAD;
@@ -1134,9 +1147,19 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi,
     free(ufds);
   if(ret)
     *ret = retcode;
-  if(gotsocket && (extra_fds || curlfds))
+  if(!extrawait || extra_fds || curlfds)
     /* if any socket was checked */
-    *gotsocket = TRUE;
+    ;
+  else {
+    long sleep_ms = 0;
+
+    /* Avoid busy-looping when there's nothing particular to wait for */
+    if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
+      if(sleep_ms > timeout_ms)
+        sleep_ms = timeout_ms;
+      Curl_wait_ms((int)sleep_ms);
+    }
+  }
 
   return CURLM_OK;
 }
@@ -1147,7 +1170,16 @@ 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, NULL);
+  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE);
+}
+
+CURLMcode curl_multi_poll(struct Curl_multi *multi,
+                          struct curl_waitfd extra_fds[],
+                          unsigned int extra_nfds,
+                          int timeout_ms,
+                          int *ret)
+{
+  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE);
 }
 
 /*
@@ -1247,6 +1279,109 @@ static CURLcode multi_do_more(struct connectdata *conn, int *complete)
   return result;
 }
 
+/*
+ * We are doing protocol-specific connecting and this is being called over and
+ * over from the multi interface until the connection phase is done on
+ * protocol layer.
+ */
+
+static CURLcode protocol_connecting(struct connectdata *conn,
+                                    bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn && conn->handler->connecting) {
+    *done = FALSE;
+    result = conn->handler->connecting(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We are DOING this is being called over and over from the multi interface
+ * until the DOING phase is done on protocol layer.
+ */
+
+static CURLcode protocol_doing(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn && conn->handler->doing) {
+    *done = FALSE;
+    result = conn->handler->doing(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We have discovered that the TCP connection has been successful, we can now
+ * proceed with some action.
+ *
+ */
+static CURLcode protocol_connect(struct connectdata *conn,
+                                 bool *protocol_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(protocol_done);
+
+  *protocol_done = FALSE;
+
+  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
+    /* We already are connected, get back. This may happen when the connect
+       worked fine in the first call, like when we connect to a local server
+       or proxy. Note that we don't know if the protocol is actually done.
+
+       Unless this protocol doesn't have any protocol-connect callback, as
+       then we know we're done. */
+    if(!conn->handler->connecting)
+      *protocol_done = TRUE;
+
+    return CURLE_OK;
+  }
+
+  if(!conn->bits.protoconnstart) {
+
+    result = Curl_proxy_connect(conn, FIRSTSOCKET);
+    if(result)
+      return result;
+
+    if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+      /* wait for HTTPS proxy SSL initialization to complete */
+      return CURLE_OK;
+
+    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+       Curl_connect_ongoing(conn))
+      /* when using an HTTP tunnel proxy, await complete tunnel establishment
+         before proceeding further. Return CURLE_OK so we'll be called again */
+      return CURLE_OK;
+
+    if(conn->handler->connect_it) {
+      /* is there a protocol-specific connect() procedure? */
+
+      /* Call the protocol-specific connect function */
+      result = conn->handler->connect_it(conn, protocol_done);
+    }
+    else
+      *protocol_done = TRUE;
+
+    /* it has started, possibly even completed but that knowledge isn't stored
+       in this bit! */
+    if(!result)
+      conn->bits.protoconnstart = TRUE;
+  }
+
+  return result; /* pass back status */
+}
+
+
 static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                  struct curltime now,
                                  struct Curl_easy *data)
@@ -1254,7 +1389,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
   struct Curl_message *msg = NULL;
   bool connected;
   bool async;
-  bool protocol_connect = FALSE;
+  bool protocol_connected = FALSE;
   bool dophase_done = FALSE;
   bool done = FALSE;
   CURLMcode rc;
@@ -1373,7 +1508,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       if(data->set.connecttimeout)
         Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
 
-      result = Curl_connect(data, &async, &protocol_connect);
+      result = Curl_connect(data, &async, &protocol_connected);
       if(CURLE_NO_CONNECTION_AVAILABLE == result) {
         /* There was no connection available. We will go to the pending
            state and wait for an available connection. */
@@ -1401,7 +1536,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
              WAITDO or DO! */
           rc = CURLM_CALL_MULTI_PERFORM;
 
-          if(protocol_connect)
+          if(protocol_connected)
             multistate(data, CURLM_STATE_DO);
           else {
 #ifndef CURL_DISABLE_HTTP
@@ -1456,7 +1591,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       if(dns) {
         /* Perform the next step in the connection phase, and then move on
            to the WAITCONNECT state */
-        result = Curl_once_resolved(data->conn, &protocol_connect);
+        result = Curl_once_resolved(data->conn, &protocol_connected);
 
         if(result)
           /* if Curl_once_resolved() returns failure, the connection struct
@@ -1465,7 +1600,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         else {
           /* call again please so that we get the next socket setup */
           rc = CURLM_CALL_MULTI_PERFORM;
-          if(protocol_connect)
+          if(protocol_connected)
             multistate(data, CURLM_STATE_DO);
           else {
 #ifndef CURL_DISABLE_HTTP
@@ -1490,7 +1625,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
     case CURLM_STATE_WAITPROXYCONNECT:
       /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
       DEBUGASSERT(data->conn);
-      result = Curl_http_connect(data->conn, &protocol_connect);
+      result = Curl_http_connect(data->conn, &protocol_connected);
 
       if(data->conn->bits.proxy_connect_closed) {
         rc = CURLM_CALL_MULTI_PERFORM;
@@ -1541,8 +1676,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       break;
 
     case CURLM_STATE_SENDPROTOCONNECT:
-      result = Curl_protocol_connect(data->conn, &protocol_connect);
-      if(!result && !protocol_connect)
+      result = protocol_connect(data->conn, &protocol_connected);
+      if(!result && !protocol_connected)
         /* switch to waiting state */
         multistate(data, CURLM_STATE_PROTOCONNECT);
       else if(!result) {
@@ -1560,8 +1695,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
 
     case CURLM_STATE_PROTOCONNECT:
       /* protocol-specific connect phase */
-      result = Curl_protocol_connecting(data->conn, &protocol_connect);
-      if(!result && protocol_connect) {
+      result = protocol_connecting(data->conn, &protocol_connected);
+      if(!result && protocol_connected) {
         /* after the connect has completed, go WAITDO or DO */
         multistate(data, CURLM_STATE_DO);
         rc = CURLM_CALL_MULTI_PERFORM;
@@ -1683,8 +1818,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
     case CURLM_STATE_DOING:
       /* we continue DOING until the DO phase is complete */
       DEBUGASSERT(data->conn);
-      result = Curl_protocol_doing(data->conn,
-                                   &dophase_done);
+      result = protocol_doing(data->conn, &dophase_done);
       if(!result) {
         if(dophase_done) {
           /* after DO, go DO_DONE or DO_MORE */
@@ -2012,13 +2146,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           if(stream_error) {
             /* Don't attempt to send data over a connection that timed out */
             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
-            /* disconnect properly */
-            Curl_disconnect(data, data->conn, dead_connection);
+            struct connectdata *conn = data->conn;
 
             /* This is where we make sure that the conn pointer is reset.
                We don't have to do this in every case block above where a
                failure is detected */
             detach_connnection(data);
+
+            /* disconnect properly */
+            Curl_disconnect(data, conn, dead_connection);
           }
         }
         else if(data->mstate == CURLM_STATE_CONNECT) {
@@ -2234,7 +2370,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
 
   /* Fill in the 'current' struct with the state as it is now: what sockets to
      supervise and for what actions */
-  curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
+  curraction = multi_getsock(data, socks);
 
   /* We have 0 .. N sockets already and we get to know about the 0 .. M
      sockets we should have from now on. Detect the differences, remove no
@@ -2846,7 +2982,7 @@ multi_addtimeout(struct Curl_easy *data,
  *
  * Expire replaces a former timeout using the same id if already set.
  */
-void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
+void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
 {
   struct Curl_multi *multi = data->multi;
   struct curltime *nowp = &data->state.expiretime;
@@ -2860,7 +2996,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
   DEBUGASSERT(id < EXPIRE_LAST);
 
   set = Curl_now();
-  set.tv_sec += milli/1000;
+  set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */
   set.tv_usec += (unsigned int)(milli%1000)*1000;
 
   if(set.tv_usec >= 1000000) {
diff --git a/libs/libcurl/src/multiif.h b/libs/libcurl/src/multiif.h
index a644558677..0755a7cd24 100644
--- a/libs/libcurl/src/multiif.h
+++ b/libs/libcurl/src/multiif.h
@@ -27,7 +27,7 @@
  */
 
 void Curl_updatesocket(struct Curl_easy *data);
-void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
+void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id);
 void Curl_expire_clear(struct Curl_easy *data);
 void Curl_expire_done(struct Curl_easy *data, expire_id id);
 void Curl_update_timer(struct Curl_multi *multi);
@@ -89,11 +89,4 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
                                  struct Curl_easy *data,
                                  struct connectdata *conn);
 
-CURLMcode Curl_multi_wait(struct Curl_multi *multi,
-                          struct curl_waitfd extra_fds[],
-                          unsigned int extra_nfds,
-                          int timeout_ms,
-                          int *ret,
-                          bool *gotsocket); /* if any socket was checked */
-
 #endif /* HEADER_CURL_MULTIIF_H */
diff --git a/libs/libcurl/src/netrc.c b/libs/libcurl/src/netrc.c
index f41636e974..c74065e813 100644
--- a/libs/libcurl/src/netrc.c
+++ b/libs/libcurl/src/netrc.c
@@ -45,27 +45,27 @@ enum host_lookup_state {
   HOSTVALID     /* this is "our" machine! */
 };
 
+#define NETRC_FILE_MISSING 1
+#define NETRC_FAILED -1
+#define NETRC_SUCCESS 0
+
 /*
- * @unittest: 1304
- *
- * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
- * in.
+ * Returns zero on success.
  */
-int Curl_parsenetrc(const char *host,
-                    char **loginp,
-                    char **passwordp,
-                    bool *login_changed,
-                    bool *password_changed,
-                    char *netrcfile)
+static int parsenetrc(const char *host,
+                      char **loginp,
+                      char **passwordp,
+                      bool *login_changed,
+                      bool *password_changed,
+                      char *netrcfile)
 {
   FILE *file;
-  int retcode = 1;
+  int retcode = NETRC_FILE_MISSING;
   char *login = *loginp;
   char *password = *passwordp;
   bool specific_login = (login && *login != 0);
   bool login_alloc = FALSE;
   bool password_alloc = FALSE;
-  bool netrc_alloc = FALSE;
   enum host_lookup_state state = NOTHING;
 
   char state_login = 0;      /* Found a login keyword */
@@ -73,51 +73,9 @@ int Curl_parsenetrc(const char *host,
   int state_our_login = FALSE;  /* With specific_login, found *our* login
                                    name */
 
-#define NETRC DOT_CHAR "netrc"
-
-  if(!netrcfile) {
-    bool home_alloc = FALSE;
-    char *home = curl_getenv("HOME"); /* portable environment reader */
-    if(home) {
-      home_alloc = TRUE;
-#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
-    }
-    else {
-      struct passwd pw, *pw_res;
-      char pwbuf[1024];
-      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
-         && pw_res) {
-        home = strdup(pw.pw_dir);
-        if(!home)
-          return -1;
-        home_alloc = TRUE;
-      }
-#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
-    }
-    else {
-      struct passwd *pw;
-      pw = getpwuid(geteuid());
-      if(pw) {
-        home = pw->pw_dir;
-      }
-#endif
-    }
-
-    if(!home)
-      return retcode; /* no home directory found (or possibly out of memory) */
-
-    netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
-    if(home_alloc)
-      free(home);
-    if(!netrcfile) {
-      return -1;
-    }
-    netrc_alloc = TRUE;
-  }
+  DEBUGASSERT(netrcfile);
 
   file = fopen(netrcfile, FOPEN_READTEXT);
-  if(netrc_alloc)
-    free(netrcfile);
   if(file) {
     char *tok;
     char *tok_buf;
@@ -148,14 +106,14 @@ int Curl_parsenetrc(const char *host,
           }
           else if(strcasecompare("default", tok)) {
             state = HOSTVALID;
-            retcode = 0; /* we did find our host */
+            retcode = NETRC_SUCCESS; /* we did find our host */
           }
           break;
         case HOSTFOUND:
           if(strcasecompare(host, tok)) {
             /* and yes, this is our host! */
             state = HOSTVALID;
-            retcode = 0; /* we did find our host */
+            retcode = NETRC_SUCCESS; /* we did find our host */
           }
           else
             /* not our host */
@@ -174,7 +132,7 @@ int Curl_parsenetrc(const char *host,
               }
               login = strdup(tok);
               if(!login) {
-                retcode = -1; /* allocation failed */
+                retcode = NETRC_FAILED; /* allocation failed */
                 goto out;
               }
               login_alloc = TRUE;
@@ -190,7 +148,7 @@ int Curl_parsenetrc(const char *host,
               }
               password = strdup(tok);
               if(!password) {
-                retcode = -1; /* allocation failed */
+                retcode = NETRC_FAILED; /* allocation failed */
                 goto out;
               }
               password_alloc = TRUE;
@@ -215,6 +173,7 @@ int Curl_parsenetrc(const char *host,
 
     out:
     if(!retcode) {
+      /* success */
       *login_changed = FALSE;
       *password_changed = FALSE;
       if(login_alloc) {
@@ -242,4 +201,78 @@ int Curl_parsenetrc(const char *host,
   return retcode;
 }
 
+/*
+ * @unittest: 1304
+ *
+ * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
+ * in.
+ */
+int Curl_parsenetrc(const char *host,
+                    char **loginp,
+                    char **passwordp,
+                    bool *login_changed,
+                    bool *password_changed,
+                    char *netrcfile)
+{
+  int retcode = 1;
+  char *filealloc = NULL;
+
+  if(!netrcfile) {
+    char *home = NULL;
+    char *homea = curl_getenv("HOME"); /* portable environment reader */
+    if(homea) {
+      home = homea;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd pw, *pw_res;
+      char pwbuf[1024];
+      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
+         && pw_res) {
+        home = pw.pw_dir;
+      }
+#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd *pw;
+      pw = getpwuid(geteuid());
+      if(pw) {
+        home = pw->pw_dir;
+      }
+#endif
+    }
+
+    if(!home)
+      return retcode; /* no home directory found (or possibly out of
+                         memory) */
+
+    filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR);
+    if(!filealloc) {
+      free(homea);
+      return -1;
+    }
+    retcode = parsenetrc(host, loginp, passwordp, login_changed,
+                         password_changed, filealloc);
+    free(filealloc);
+#ifdef WIN32
+    if(retcode == NETRC_FILE_MISSING) {
+      /* fallback to the old-style "_netrc" file */
+      filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR);
+      if(!filealloc) {
+        free(homea);
+        return -1;
+      }
+      retcode = parsenetrc(host, loginp, passwordp, login_changed,
+                           password_changed, filealloc);
+      free(filealloc);
+    }
+#endif
+    free(homea);
+  }
+  else
+    retcode = parsenetrc(host, loginp, passwordp, login_changed,
+                         password_changed, netrcfile);
+  return retcode;
+}
+
 #endif
diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c
index eeab2c7a78..734ca5fa0c 100644
--- a/libs/libcurl/src/openldap.c
+++ b/libs/libcurl/src/openldap.c
@@ -151,7 +151,7 @@ static const char *url_errs[] = {
   "bad or missing extensions"
 };
 
-typedef struct ldapconninfo {
+struct ldapconninfo {
   LDAP *ld;
   Curl_recv *recv;  /* for stacking SSL handler */
   Curl_send *send;
@@ -160,7 +160,7 @@ typedef struct ldapconninfo {
   bool ssldone;
   bool sslinst;
   bool didbind;
-} ldapconninfo;
+};
 
 typedef struct ldapreqinfo {
   int msgid;
@@ -169,7 +169,7 @@ typedef struct ldapreqinfo {
 
 static CURLcode ldap_setup_connection(struct connectdata *conn)
 {
-  ldapconninfo *li;
+  struct ldapconninfo *li;
   LDAPURLDesc *lud;
   struct Curl_easy *data = conn->data;
   int rc, proto;
@@ -190,11 +190,11 @@ static CURLcode ldap_setup_connection(struct connectdata *conn)
   proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
   ldap_free_urldesc(lud);
 
-  li = calloc(1, sizeof(ldapconninfo));
+  li = calloc(1, sizeof(struct ldapconninfo));
   if(!li)
     return CURLE_OUT_OF_MEMORY;
   li->proto = proto;
-  conn->proto.generic = li;
+  conn->proto.ldapc = li;
   connkeep(conn, "OpenLDAP default");
   return CURLE_OK;
 }
@@ -205,7 +205,7 @@ static Sockbuf_IO ldapsb_tls;
 
 static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
   int rc, proto = LDAP_VERSION3;
   char hosturl[1024];
@@ -252,7 +252,7 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 
 static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
   LDAPMessage *msg = NULL;
   struct timeval tv = {0, 1}, *tvp;
@@ -357,7 +357,7 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
 
 static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   (void) dead_connection;
 
   if(li) {
@@ -365,7 +365,7 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
       ldap_unbind_ext(li->ld, NULL, NULL);
       li->ld = NULL;
     }
-    conn->proto.generic = NULL;
+    conn->proto.ldapc = NULL;
     free(li);
   }
   return CURLE_OK;
@@ -373,7 +373,7 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
 
 static CURLcode ldap_do(struct connectdata *conn, bool *done)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   ldapreqinfo *lr;
   CURLcode status = CURLE_OK;
   int rc = 0;
@@ -427,7 +427,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
   if(lr) {
     /* if there was a search in progress, abandon it */
     if(lr->msgid) {
-      ldapconninfo *li = conn->proto.generic;
+      struct ldapconninfo *li = conn->proto.ldapc;
       ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
       lr->msgid = 0;
     }
@@ -441,7 +441,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
 static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
                          size_t len, CURLcode *err)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
   ldapreqinfo *lr = data->req.protop;
   int rc, ret;
@@ -718,7 +718,7 @@ static ber_slen_t
 ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
 {
   struct connectdata *conn = sbiod->sbiod_pvt;
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   ber_slen_t ret;
   CURLcode err = CURLE_RECV_ERROR;
 
@@ -733,7 +733,7 @@ static ber_slen_t
 ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
 {
   struct connectdata *conn = sbiod->sbiod_pvt;
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   ber_slen_t ret;
   CURLcode err = CURLE_SEND_ERROR;
 
diff --git a/libs/libcurl/src/pingpong.c b/libs/libcurl/src/pingpong.c
index e9568ee3de..d0710053bd 100644
--- a/libs/libcurl/src/pingpong.c
+++ b/libs/libcurl/src/pingpong.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -60,12 +60,12 @@ time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
   /* Without a requested timeout, we only wait 'response_time' seconds for the
      full response to arrive before we bail out */
   timeout_ms = response_time -
-    Curl_timediff(Curl_now(), pp->response); /* spent time */
+    (time_t)Curl_timediff(Curl_now(), pp->response); /* spent time */
 
   if(data->set.timeout && !disconnecting) {
     /* if timeout is requested, find out how much remaining time we have */
     time_t timeout2_ms = data->set.timeout - /* timeout time */
-      Curl_timediff(Curl_now(), conn->now); /* spent time */
+      (time_t)Curl_timediff(Curl_now(), conn->now); /* spent time */
 
     /* pick the lowest number */
     timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
@@ -463,14 +463,9 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
 }
 
 int Curl_pp_getsock(struct pingpong *pp,
-                    curl_socket_t *socks,
-                    int numsocks)
+                    curl_socket_t *socks)
 {
   struct connectdata *conn = pp->conn;
-
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   socks[0] = conn->sock[FIRSTSOCKET];
 
   if(pp->sendleft) {
diff --git a/libs/libcurl/src/pingpong.h b/libs/libcurl/src/pingpong.h
index dbe1f8d3d7..849a7c0ff7 100644
--- a/libs/libcurl/src/pingpong.h
+++ b/libs/libcurl/src/pingpong.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -135,8 +135,7 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp);
 /* call this when a pingpong connection is disconnected */
 CURLcode Curl_pp_disconnect(struct pingpong *pp);
 
-int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks,
-                    int numsocks);
+int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks);
 
 
 /***********************************************************************
diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c
index a681d5213f..57c1373aa8 100644
--- a/libs/libcurl/src/pop3.c
+++ b/libs/libcurl/src/pop3.c
@@ -95,8 +95,7 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
 static CURLcode pop3_connect(struct connectdata *conn, bool *done);
 static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
 static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
-static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
 static CURLcode pop3_setup_connection(struct connectdata *conn);
 static CURLcode pop3_parse_url_options(struct connectdata *conn);
@@ -1055,10 +1054,9 @@ static CURLcode pop3_init(struct connectdata *conn)
 }
 
 /* For the POP3 "protocol connect" and "doing" phases only */
-static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.pop3c.pp, socks);
 }
 
 /***********************************************************************
diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c
index 9f953ef5a1..2aa9295993 100644
--- a/libs/libcurl/src/progress.c
+++ b/libs/libcurl/src/progress.c
@@ -26,6 +26,7 @@
 #include "sendf.h"
 #include "multiif.h"
 #include "progress.h"
+#include "timeval.h"
 #include "curl_printf.h"
 
 /* check rate limits within this many recent milliseconds, at minimum. */
@@ -168,7 +169,7 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
 void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
 {
   struct curltime now = Curl_now();
-  time_t *delta = NULL;
+  timediff_t *delta = NULL;
 
   switch(timer) {
   default:
@@ -238,6 +239,8 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
   data->progress.ul_limit_start.tv_usec = 0;
   data->progress.dl_limit_start.tv_sec = 0;
   data->progress.dl_limit_start.tv_usec = 0;
+  data->progress.downloaded = 0;
+  data->progress.uploaded = 0;
   /* clear all bits except HIDE and HEADERS_OUT */
   data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
   Curl_ratelimit(data, data->progress.start);
@@ -268,8 +271,8 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
                                   struct curltime now)
 {
   curl_off_t size = cursize - startsize;
-  time_t minimum;
-  time_t actual;
+  timediff_t minimum;
+  timediff_t actual;
 
   if(!limit || !size)
     return 0;
@@ -282,10 +285,10 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
     minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
   else {
     minimum = (time_t) (size / limit);
-    if(minimum < TIME_T_MAX/1000)
+    if(minimum < TIMEDIFF_T_MAX/1000)
       minimum *= 1000;
     else
-      minimum = TIME_T_MAX;
+      minimum = TIMEDIFF_T_MAX;
   }
 
   /*
diff --git a/libs/libcurl/src/quic.h b/libs/libcurl/src/quic.h
new file mode 100644
index 0000000000..6c132a3247
--- /dev/null
+++ b/libs/libcurl/src/quic.h
@@ -0,0 +1,53 @@
+#ifndef HEADER_CURL_QUIC_H
+#define HEADER_CURL_QUIC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef ENABLE_QUIC
+#ifdef USE_NGTCP2
+#include "vquic/ngtcp2.h"
+#endif
+#ifdef USE_QUICHE
+#include "vquic/quiche.h"
+#endif
+
+#include "urldata.h"
+
+/* functions provided by the specific backends */
+CURLcode Curl_quic_connect(struct connectdata *conn,
+                           curl_socket_t sockfd,
+                           int sockindex,
+                           const struct sockaddr *addr,
+                           socklen_t addrlen);
+CURLcode Curl_quic_is_connected(struct connectdata *conn,
+                                curl_socket_t sockfd,
+                                bool *connected);
+int Curl_quic_ver(char *p, size_t len);
+CURLcode Curl_quic_done_sending(struct connectdata *conn);
+
+#else /* ENABLE_QUIC */
+#define Curl_quic_done_sending(x)
+#endif /* !ENABLE_QUIC */
+
+#endif /* HEADER_CURL_QUIC_H */
diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c
index 25e194a233..bba4c16a1e 100644
--- a/libs/libcurl/src/rtsp.c
+++ b/libs/libcurl/src/rtsp.c
@@ -52,10 +52,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done);
 static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
 static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
 static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
-
-static int rtsp_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks);
+static int rtsp_getsock_do(struct connectdata *conn, curl_socket_t *socks);
 
 /*
  * Parse and write out any available RTP data.
@@ -77,11 +74,9 @@ static unsigned int rtsp_conncheck(struct connectdata *check,
    interface and then we're always _sending_ a request and thus we wait for
    the single socket to become writable only */
 static int rtsp_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks)
+                           curl_socket_t *socks)
 {
   /* write mode */
-  (void)numsocks; /* unused, we trust it to be at least 1 */
   socks[0] = conn->sock[FIRSTSOCKET];
   return GETSOCK_WRITESOCK(0);
 }
diff --git a/libs/libcurl/src/security.c b/libs/libcurl/src/security.c
index 550ea2da8d..c5e4e135df 100644
--- a/libs/libcurl/src/security.c
+++ b/libs/libcurl/src/security.c
@@ -191,7 +191,6 @@ static CURLcode read_data(struct connectdata *conn,
                           struct krb5buffer *buf)
 {
   int len;
-  void *tmp = NULL;
   CURLcode result;
 
   result = socket_read(fd, &len, sizeof(len));
@@ -201,12 +200,11 @@ static CURLcode read_data(struct connectdata *conn,
   if(len) {
     /* only realloc if there was a length */
     len = ntohl(len);
-    tmp = Curl_saferealloc(buf->data, len);
+    buf->data = Curl_saferealloc(buf->data, len);
   }
-  if(tmp == NULL)
+  if(!len || !buf->data)
     return CURLE_OUT_OF_MEMORY;
 
-  buf->data = tmp;
   result = socket_read(fd, buf->data, len);
   if(result)
     return result;
diff --git a/libs/libcurl/src/select.h b/libs/libcurl/src/select.h
index 9a1ba45a7d..f5652a74f7 100644
--- a/libs/libcurl/src/select.h
+++ b/libs/libcurl/src/select.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -77,9 +77,9 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
                       time_t timeout_ms);
 
 #define SOCKET_READABLE(x,z) \
-  Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
+  Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, (time_t)z)
 #define SOCKET_WRITABLE(x,z) \
-  Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
+  Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, (time_t)z)
 
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
 
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index 1dbf00faf7..8909035a97 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -809,6 +809,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     arg = va_arg(param, long);
     if(arg < CURL_HTTP_VERSION_NONE)
       return CURLE_BAD_FUNCTION_ARGUMENT;
+#ifdef ENABLE_QUIC
+    if(arg == CURL_HTTP_VERSION_3)
+      ;
+    else
+#endif
 #ifndef USE_NGHTTP2
     if(arg >= CURL_HTTP_VERSION_2)
       return CURLE_UNSUPPORTED_PROTOCOL;
@@ -1778,16 +1783,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     arg = va_arg(param, long);
 
     /* Obviously people are not reading documentation and too many thought
-       this argument took a boolean when it wasn't and misused it. We thus ban
-       1 as a sensible input and we warn about its use. Then we only have the
-       2 action internally stored as TRUE. */
-
-    if(1 == arg) {
-      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
-      return CURLE_BAD_FUNCTION_ARGUMENT;
-    }
-
-    data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
+       this argument took a boolean when it wasn't and misused it.
+       Treat 1 and 2 the same */
+    data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE);
 
     /* Update the current connection ssl_config. */
     if(data->conn) {
@@ -1802,17 +1800,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
      */
     arg = va_arg(param, long);
 
-    /* Obviously people are not reading documentation and too many thought
-       this argument took a boolean when it wasn't and misused it. We thus ban
-       1 as a sensible input and we warn about its use. Then we only have the
-       2 action internally stored as TRUE. */
-
-    if(1 == arg) {
-      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
-      return CURLE_BAD_FUNCTION_ARGUMENT;
-    }
-
-    data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
+    /* Treat both 1 and 2 as TRUE */
+    data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE);
 
     /* Update the current connection proxy_ssl_config. */
     if(data->conn) {
@@ -2402,6 +2391,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     break;
 #endif
 
+  case CURLOPT_SASL_AUTHZID:
+    /* Authorisation identity (identity to act as) */
+    result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
+                            va_arg(param, char *));
+    break;
+
   case CURLOPT_SASL_IR:
     /* Enable/disable SASL initial response */
     data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c
index 870244cb72..f66c05ca42 100644
--- a/libs/libcurl/src/smb.c
+++ b/libs/libcurl/src/smb.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2016-2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2016-2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -64,8 +64,7 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done);
 static CURLcode smb_done(struct connectdata *conn, CURLcode status,
                          bool premature);
 static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
-static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
-                       int numsocks);
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode smb_parse_url_path(struct connectdata *conn);
 
 /*
@@ -607,6 +606,7 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
 {
   struct smb_conn *smbc = &conn->proto.smbc;
   CURLcode result;
+  *msg = NULL; /* if it returns early */
 
   /* Check if there is data in the transfer buffer */
   if(!smbc->send_size && smbc->upload_size) {
@@ -936,12 +936,8 @@ static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
   return CURLE_OK;
 }
 
-static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
-                       int numsocks)
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   socks[0] = conn->sock[FIRSTSOCKET];
   return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
 }
diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c
index e10d0fbfc9..65220b0f68 100644
--- a/libs/libcurl/src/smtp.c
+++ b/libs/libcurl/src/smtp.c
@@ -95,8 +95,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
 static CURLcode smtp_connect(struct connectdata *conn, bool *done);
 static CURLcode smtp_disconnect(struct connectdata *conn, bool dead);
 static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done);
-static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
 static CURLcode smtp_setup_connection(struct connectdata *conn);
 static CURLcode smtp_parse_url_options(struct connectdata *conn);
@@ -715,7 +714,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
       result = CURLE_REMOTE_ACCESS_DENIED;
     }
   }
-  else {
+  else if(len >= 4) {
     line += 4;
     len -= 4;
 
@@ -786,6 +785,10 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
         result = smtp_perform_authentication(conn);
     }
   }
+  else {
+    failf(data, "Unexpectedly short EHLO response");
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
 
   return result;
 }
@@ -1114,10 +1117,9 @@ static CURLcode smtp_init(struct connectdata *conn)
 }
 
 /* For the SMTP "protocol connect" and "doing" phases only */
-static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.smtpc.pp, socks);
 }
 
 /***********************************************************************
diff --git a/libs/libcurl/src/ssh-libssh.c b/libs/libcurl/src/ssh-libssh.c
deleted file mode 100644
index ca13376775..0000000000
--- a/libs/libcurl/src/ssh-libssh.c
+++ /dev/null
@@ -1,2739 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2017 - 2019 Red Hat, Inc.
- *
- * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek,
- *          Robert Kolcun, Andreas Schneider
- *
- * 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_LIBSSH
-
-#include <limits.h>
-
-#include <libssh/libssh.h>
-#include <libssh/sftp.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef __VMS
-#include <in.h>
-#include <inet.h>
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "progress.h"
-#include "transfer.h"
-#include "escape.h"
-#include "http.h"               /* for HTTP proxy tunnel stuff */
-#include "ssh.h"
-#include "url.h"
-#include "speedcheck.h"
-#include "getinfo.h"
-#include "strdup.h"
-#include "strcase.h"
-#include "vtls/vtls.h"
-#include "connect.h"
-#include "strerror.h"
-#include "inet_ntop.h"
-#include "parsedate.h"          /* for the week day and month names */
-#include "sockaddr.h"           /* required for Curl_sockaddr_storage */
-#include "strtoofft.h"
-#include "multiif.h"
-#include "select.h"
-#include "warnless.h"
-
-/* for permission and open flags */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-#include "curl_path.h"
-
-/* 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)
-#endif
-
-/* Local functions: */
-static CURLcode myssh_connect(struct connectdata *conn, bool *done);
-static CURLcode myssh_multi_statemach(struct connectdata *conn,
-                                      bool *done);
-static CURLcode myssh_do_it(struct connectdata *conn, bool *done);
-
-static CURLcode scp_done(struct connectdata *conn,
-                         CURLcode, bool premature);
-static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done);
-static CURLcode scp_disconnect(struct connectdata *conn,
-                               bool dead_connection);
-
-static CURLcode sftp_done(struct connectdata *conn,
-                          CURLcode, bool premature);
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done);
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done);
-
-static void sftp_quote(struct connectdata *conn);
-static void sftp_quote_stat(struct connectdata *conn);
-
-static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock,
-                         int numsocks);
-
-static int myssh_perform_getsock(const struct connectdata *conn,
-                                 curl_socket_t *sock,
-                                 int numsocks);
-
-static CURLcode myssh_setup_connection(struct connectdata *conn);
-
-/*
- * SCP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_scp = {
-  "SCP",                        /* scheme */
-  myssh_setup_connection,       /* setup_connection */
-  myssh_do_it,                  /* do_it */
-  scp_done,                     /* done */
-  ZERO_NULL,                    /* do_more */
-  myssh_connect,                /* connect_it */
-  myssh_multi_statemach,        /* connecting */
-  scp_doing,                    /* doing */
-  myssh_getsock,                /* proto_getsock */
-  myssh_getsock,                /* doing_getsock */
-  ZERO_NULL,                    /* domore_getsock */
-  myssh_perform_getsock,        /* perform_getsock */
-  scp_disconnect,               /* disconnect */
-  ZERO_NULL,                    /* readwrite */
-  ZERO_NULL,                    /* connection_check */
-  PORT_SSH,                     /* defport */
-  CURLPROTO_SCP,                /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY    /* flags */
-};
-
-/*
- * SFTP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_sftp = {
-  "SFTP",                               /* scheme */
-  myssh_setup_connection,               /* setup_connection */
-  myssh_do_it,                          /* do_it */
-  sftp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  myssh_connect,                        /* connect_it */
-  myssh_multi_statemach,                /* connecting */
-  sftp_doing,                           /* doing */
-  myssh_getsock,                        /* proto_getsock */
-  myssh_getsock,                        /* doing_getsock */
-  ZERO_NULL,                            /* domore_getsock */
-  myssh_perform_getsock,                /* perform_getsock */
-  sftp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* readwrite */
-  ZERO_NULL,                            /* connection_check */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SFTP,                       /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
-  | PROTOPT_NOURLQUERY                  /* flags */
-};
-
-static CURLcode sftp_error_to_CURLE(int err)
-{
-  switch(err) {
-    case SSH_FX_OK:
-      return CURLE_OK;
-
-    case SSH_FX_NO_SUCH_FILE:
-    case SSH_FX_NO_SUCH_PATH:
-      return CURLE_REMOTE_FILE_NOT_FOUND;
-
-    case SSH_FX_PERMISSION_DENIED:
-    case SSH_FX_WRITE_PROTECT:
-      return CURLE_REMOTE_ACCESS_DENIED;
-
-    case SSH_FX_FILE_ALREADY_EXISTS:
-      return CURLE_REMOTE_FILE_EXISTS;
-
-    default:
-      break;
-  }
-
-  return CURLE_SSH;
-}
-
-#ifndef DEBUGBUILD
-#define state(x,y) mystate(x,y)
-#else
-#define state(x,y) mystate(x,y, __LINE__)
-#endif
-
-/*
- * SSH State machine related code
- */
-/* This is the ONLY way to change SSH state! */
-static void mystate(struct connectdata *conn, sshstate nowstate
-#ifdef DEBUGBUILD
-                    , int lineno
-#endif
-  )
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
-  /* for debug purposes */
-  static const char *const names[] = {
-    "SSH_STOP",
-    "SSH_INIT",
-    "SSH_S_STARTUP",
-    "SSH_HOSTKEY",
-    "SSH_AUTHLIST",
-    "SSH_AUTH_PKEY_INIT",
-    "SSH_AUTH_PKEY",
-    "SSH_AUTH_PASS_INIT",
-    "SSH_AUTH_PASS",
-    "SSH_AUTH_AGENT_INIT",
-    "SSH_AUTH_AGENT_LIST",
-    "SSH_AUTH_AGENT",
-    "SSH_AUTH_HOST_INIT",
-    "SSH_AUTH_HOST",
-    "SSH_AUTH_KEY_INIT",
-    "SSH_AUTH_KEY",
-    "SSH_AUTH_GSSAPI",
-    "SSH_AUTH_DONE",
-    "SSH_SFTP_INIT",
-    "SSH_SFTP_REALPATH",
-    "SSH_SFTP_QUOTE_INIT",
-    "SSH_SFTP_POSTQUOTE_INIT",
-    "SSH_SFTP_QUOTE",
-    "SSH_SFTP_NEXT_QUOTE",
-    "SSH_SFTP_QUOTE_STAT",
-    "SSH_SFTP_QUOTE_SETSTAT",
-    "SSH_SFTP_QUOTE_SYMLINK",
-    "SSH_SFTP_QUOTE_MKDIR",
-    "SSH_SFTP_QUOTE_RENAME",
-    "SSH_SFTP_QUOTE_RMDIR",
-    "SSH_SFTP_QUOTE_UNLINK",
-    "SSH_SFTP_QUOTE_STATVFS",
-    "SSH_SFTP_GETINFO",
-    "SSH_SFTP_FILETIME",
-    "SSH_SFTP_TRANS_INIT",
-    "SSH_SFTP_UPLOAD_INIT",
-    "SSH_SFTP_CREATE_DIRS_INIT",
-    "SSH_SFTP_CREATE_DIRS",
-    "SSH_SFTP_CREATE_DIRS_MKDIR",
-    "SSH_SFTP_READDIR_INIT",
-    "SSH_SFTP_READDIR",
-    "SSH_SFTP_READDIR_LINK",
-    "SSH_SFTP_READDIR_BOTTOM",
-    "SSH_SFTP_READDIR_DONE",
-    "SSH_SFTP_DOWNLOAD_INIT",
-    "SSH_SFTP_DOWNLOAD_STAT",
-    "SSH_SFTP_CLOSE",
-    "SSH_SFTP_SHUTDOWN",
-    "SSH_SCP_TRANS_INIT",
-    "SSH_SCP_UPLOAD_INIT",
-    "SSH_SCP_DOWNLOAD_INIT",
-    "SSH_SCP_DOWNLOAD",
-    "SSH_SCP_DONE",
-    "SSH_SCP_SEND_EOF",
-    "SSH_SCP_WAIT_EOF",
-    "SSH_SCP_WAIT_CLOSE",
-    "SSH_SCP_CHANNEL_FREE",
-    "SSH_SESSION_DISCONNECT",
-    "SSH_SESSION_FREE",
-    "QUIT"
-  };
-
-
-  if(sshc->state != nowstate) {
-    infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
-          (void *) sshc, names[sshc->state], names[nowstate],
-          lineno);
-  }
-#endif
-
-  sshc->state = nowstate;
-}
-
-/* Multiple options:
- * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5
- *    hash (90s style auth, not sure we should have it here)
- * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first
- *    use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE
- *    is returned by it.
- * 3. none of the above. We only accept if it is present on known hosts.
- *
- * Returns SSH_OK or SSH_ERROR.
- */
-static int myssh_is_known(struct connectdata *conn)
-{
-  int rc;
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  ssh_key pubkey;
-  size_t hlen;
-  unsigned char *hash = NULL;
-  char *base64 = NULL;
-  int vstate;
-  enum curl_khmatch keymatch;
-  struct curl_khkey foundkey;
-  curl_sshkeycallback func =
-    data->set.ssh_keyfunc;
-
-  rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
-  if(rc != SSH_OK)
-    return rc;
-
-  if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
-    rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
-                                &hash, &hlen);
-    if(rc != SSH_OK)
-      goto cleanup;
-
-    if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) ||
-       memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) {
-      rc = SSH_ERROR;
-      goto cleanup;
-    }
-
-    rc = SSH_OK;
-    goto cleanup;
-  }
-
-  if(data->set.ssl.primary.verifyhost != TRUE) {
-    rc = SSH_OK;
-    goto cleanup;
-  }
-
-  vstate = ssh_is_server_known(sshc->ssh_session);
-  switch(vstate) {
-    case SSH_SERVER_KNOWN_OK:
-      keymatch = CURLKHMATCH_OK;
-      break;
-    case SSH_SERVER_FILE_NOT_FOUND:
-      /* fallthrough */
-    case SSH_SERVER_NOT_KNOWN:
-      keymatch = CURLKHMATCH_MISSING;
-      break;
-  default:
-      keymatch = CURLKHMATCH_MISMATCH;
-      break;
-  }
-
-  if(func) { /* use callback to determine action */
-    rc = ssh_pki_export_pubkey_base64(pubkey, &base64);
-    if(rc != SSH_OK)
-      goto cleanup;
-
-    foundkey.key = base64;
-    foundkey.len = strlen(base64);
-
-    switch(ssh_key_type(pubkey)) {
-      case SSH_KEYTYPE_RSA:
-        foundkey.keytype = CURLKHTYPE_RSA;
-        break;
-      case SSH_KEYTYPE_RSA1:
-        foundkey.keytype = CURLKHTYPE_RSA1;
-        break;
-      case SSH_KEYTYPE_ECDSA:
-        foundkey.keytype = CURLKHTYPE_ECDSA;
-        break;
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0)
-      case SSH_KEYTYPE_ED25519:
-        foundkey.keytype = CURLKHTYPE_ED25519;
-        break;
-#endif
-      case SSH_KEYTYPE_DSS:
-        foundkey.keytype = CURLKHTYPE_DSS;
-        break;
-      default:
-        rc = SSH_ERROR;
-        goto cleanup;
-    }
-
-    /* we don't have anything equivalent to knownkey. Always NULL */
-    Curl_set_in_callback(data, true);
-    rc = func(data, NULL, &foundkey, /* from the remote host */
-              keymatch, data->set.ssh_keyfunc_userp);
-    Curl_set_in_callback(data, false);
-
-    switch(rc) {
-      case CURLKHSTAT_FINE_ADD_TO_FILE:
-        rc = ssh_write_knownhost(sshc->ssh_session);
-        if(rc != SSH_OK) {
-          goto cleanup;
-        }
-        break;
-      case CURLKHSTAT_FINE:
-        break;
-      default: /* REJECT/DEFER */
-        rc = SSH_ERROR;
-        goto cleanup;
-    }
-  }
-  else {
-    if(keymatch != CURLKHMATCH_OK) {
-      rc = SSH_ERROR;
-      goto cleanup;
-    }
-  }
-  rc = SSH_OK;
-
-cleanup:
-  if(hash)
-    ssh_clean_pubkey_hash(&hash);
-  ssh_key_free(pubkey);
-  return rc;
-}
-
-#define MOVE_TO_ERROR_STATE(_r) { \
-  state(conn, SSH_SESSION_DISCONNECT); \
-  sshc->actualcode = _r; \
-  rc = SSH_ERROR; \
-  break; \
-}
-
-#define MOVE_TO_SFTP_CLOSE_STATE() { \
-  state(conn, SSH_SFTP_CLOSE); \
-  sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \
-  rc = SSH_ERROR; \
-  break; \
-}
-
-#define MOVE_TO_LAST_AUTH \
-  if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
-    rc = SSH_OK; \
-    state(conn, SSH_AUTH_PASS_INIT); \
-    break; \
-  } \
-  else { \
-    MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
-  }
-
-#define MOVE_TO_TERTIARY_AUTH \
-  if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
-    rc = SSH_OK; \
-    state(conn, SSH_AUTH_KEY_INIT); \
-    break; \
-  } \
-  else { \
-    MOVE_TO_LAST_AUTH; \
-  }
-
-#define MOVE_TO_SECONDARY_AUTH \
-  if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
-    rc = SSH_OK; \
-    state(conn, SSH_AUTH_GSSAPI); \
-    break; \
-  } \
-  else { \
-    MOVE_TO_TERTIARY_AUTH; \
-  }
-
-static
-int myssh_auth_interactive(struct connectdata *conn)
-{
-  int rc;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  int nprompts;
-
-restart:
-  switch(sshc->kbd_state) {
-    case 0:
-      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
-      if(rc == SSH_AUTH_AGAIN)
-        return SSH_AGAIN;
-
-      if(rc != SSH_AUTH_INFO)
-        return SSH_ERROR;
-
-      nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
-      if(nprompts == SSH_ERROR || nprompts != 1)
-        return SSH_ERROR;
-
-      rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd);
-      if(rc < 0)
-        return SSH_ERROR;
-
-    /* FALLTHROUGH */
-    case 1:
-      sshc->kbd_state = 1;
-
-      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
-      if(rc == SSH_AUTH_AGAIN)
-        return SSH_AGAIN;
-      else if(rc == SSH_AUTH_SUCCESS)
-        rc = SSH_OK;
-      else if(rc == SSH_AUTH_INFO) {
-        nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
-        if(nprompts != 0)
-          return SSH_ERROR;
-
-        sshc->kbd_state = 2;
-        goto restart;
-      }
-      else
-        rc = SSH_ERROR;
-      break;
-    case 2:
-      sshc->kbd_state = 2;
-
-      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
-      if(rc == SSH_AUTH_AGAIN)
-        return SSH_AGAIN;
-      else if(rc == SSH_AUTH_SUCCESS)
-        rc = SSH_OK;
-      else
-        rc = SSH_ERROR;
-
-      break;
-    default:
-      return SSH_ERROR;
-  }
-
-  sshc->kbd_state = 0;
-  return rc;
-}
-
-/*
- * ssh_statemach_act() runs the SSH state machine as far as it can without
- * blocking and without reaching the end.  The data the pointer 'block' points
- * to will be set to TRUE if the libssh function returns SSH_AGAIN
- * meaning it wants to be called again when the socket is ready
- */
-static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
-{
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-  struct SSHPROTO *protop = data->req.protop;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  curl_socket_t sock = conn->sock[FIRSTSOCKET];
-  int rc = SSH_NO_ERROR, err;
-  char *new_readdir_line;
-  int seekerr = CURL_SEEKFUNC_OK;
-  const char *err_msg;
-  *block = 0;                   /* we're not blocking by default */
-
-  do {
-
-    switch(sshc->state) {
-    case SSH_INIT:
-      sshc->secondCreateDirs = 0;
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_OK;
-
-#if 0
-      ssh_set_log_level(SSH_LOG_PROTOCOL);
-#endif
-
-      /* Set libssh to non-blocking, since everything internally is
-         non-blocking */
-      ssh_set_blocking(sshc->ssh_session, 0);
-
-      state(conn, SSH_S_STARTUP);
-      /* FALLTHROUGH */
-
-    case SSH_S_STARTUP:
-      rc = ssh_connect(sshc->ssh_session);
-      if(rc == SSH_AGAIN)
-        break;
-
-      if(rc != SSH_OK) {
-        failf(data, "Failure establishing ssh session");
-        MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT);
-      }
-
-      state(conn, SSH_HOSTKEY);
-
-      /* FALLTHROUGH */
-    case SSH_HOSTKEY:
-
-      rc = myssh_is_known(conn);
-      if(rc != SSH_OK) {
-        MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION);
-      }
-
-      state(conn, SSH_AUTHLIST);
-      /* FALLTHROUGH */
-    case SSH_AUTHLIST:{
-        sshc->authed = FALSE;
-
-        rc = ssh_userauth_none(sshc->ssh_session, NULL);
-        if(rc == SSH_AUTH_AGAIN) {
-          rc = SSH_AGAIN;
-          break;
-        }
-
-        if(rc == SSH_AUTH_SUCCESS) {
-          sshc->authed = TRUE;
-          infof(data, "Authenticated with none\n");
-          state(conn, SSH_AUTH_DONE);
-          break;
-        }
-        else if(rc == SSH_AUTH_ERROR) {
-          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-        }
-
-        sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
-        if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
-          state(conn, SSH_AUTH_PKEY_INIT);
-          infof(data, "Authentication using SSH public key file\n");
-        }
-        else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
-          state(conn, SSH_AUTH_GSSAPI);
-        }
-        else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
-          state(conn, SSH_AUTH_KEY_INIT);
-        }
-        else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
-          state(conn, SSH_AUTH_PASS_INIT);
-        }
-        else {                  /* unsupported authentication method */
-          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-        }
-
-        break;
-      }
-    case SSH_AUTH_PKEY_INIT:
-      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
-        MOVE_TO_SECONDARY_AUTH;
-      }
-
-      /* Two choices, (1) private key was given on CMD,
-       * (2) use the "default" keys. */
-      if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
-        if(sshc->pubkey && !data->set.ssl.key_passwd) {
-          rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL,
-                                          sshc->pubkey);
-          if(rc == SSH_AUTH_AGAIN) {
-            rc = SSH_AGAIN;
-            break;
-          }
-
-          if(rc != SSH_OK) {
-            MOVE_TO_SECONDARY_AUTH;
-          }
-        }
-
-        rc = ssh_pki_import_privkey_file(data->
-                                         set.str[STRING_SSH_PRIVATE_KEY],
-                                         data->set.ssl.key_passwd, NULL,
-                                         NULL, &sshc->privkey);
-        if(rc != SSH_OK) {
-          failf(data, "Could not load private key file %s",
-                data->set.str[STRING_SSH_PRIVATE_KEY]);
-          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-          break;
-        }
-
-        state(conn, SSH_AUTH_PKEY);
-        break;
-
-      }
-      else {
-        rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
-                                         data->set.ssl.key_passwd);
-        if(rc == SSH_AUTH_AGAIN) {
-          rc = SSH_AGAIN;
-          break;
-        }
-        if(rc == SSH_AUTH_SUCCESS) {
-          rc = SSH_OK;
-          sshc->authed = TRUE;
-          infof(data, "Completed public key authentication\n");
-          state(conn, SSH_AUTH_DONE);
-          break;
-        }
-
-        MOVE_TO_SECONDARY_AUTH;
-      }
-      break;
-    case SSH_AUTH_PKEY:
-      rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey);
-      if(rc == SSH_AUTH_AGAIN) {
-        rc = SSH_AGAIN;
-        break;
-      }
-
-      if(rc == SSH_AUTH_SUCCESS) {
-        sshc->authed = TRUE;
-        infof(data, "Completed public key authentication\n");
-        state(conn, SSH_AUTH_DONE);
-        break;
-      }
-      else {
-        infof(data, "Failed public key authentication (rc: %d)\n", rc);
-        MOVE_TO_SECONDARY_AUTH;
-      }
-      break;
-
-    case SSH_AUTH_GSSAPI:
-      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
-        MOVE_TO_TERTIARY_AUTH;
-      }
-
-      rc = ssh_userauth_gssapi(sshc->ssh_session);
-      if(rc == SSH_AUTH_AGAIN) {
-        rc = SSH_AGAIN;
-        break;
-      }
-
-      if(rc == SSH_AUTH_SUCCESS) {
-        rc = SSH_OK;
-        sshc->authed = TRUE;
-        infof(data, "Completed gssapi authentication\n");
-        state(conn, SSH_AUTH_DONE);
-        break;
-      }
-
-      MOVE_TO_TERTIARY_AUTH;
-      break;
-
-    case SSH_AUTH_KEY_INIT:
-      if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) {
-        state(conn, SSH_AUTH_KEY);
-      }
-      else {
-        MOVE_TO_LAST_AUTH;
-      }
-      break;
-
-    case SSH_AUTH_KEY:
-
-      /* Authentication failed. Continue with keyboard-interactive now. */
-      rc = myssh_auth_interactive(conn);
-      if(rc == SSH_AGAIN) {
-        break;
-      }
-      if(rc == SSH_OK) {
-        sshc->authed = TRUE;
-        infof(data, "completed keyboard interactive authentication\n");
-      }
-      state(conn, SSH_AUTH_DONE);
-      break;
-
-    case SSH_AUTH_PASS_INIT:
-      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
-        /* Host key authentication is intentionally not implemented */
-        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-      }
-      state(conn, SSH_AUTH_PASS);
-      /* FALLTHROUGH */
-
-    case SSH_AUTH_PASS:
-      rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
-      if(rc == SSH_AUTH_AGAIN) {
-        rc = SSH_AGAIN;
-        break;
-      }
-
-      if(rc == SSH_AUTH_SUCCESS) {
-        sshc->authed = TRUE;
-        infof(data, "Completed password authentication\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-      }
-      break;
-
-    case SSH_AUTH_DONE:
-      if(!sshc->authed) {
-        failf(data, "Authentication failure");
-        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-        break;
-      }
-
-      /*
-       * At this point we have an authenticated ssh session.
-       */
-      infof(data, "Authentication complete\n");
-
-      Curl_pgrsTime(conn->data, TIMER_APPCONNECT);      /* SSH is connected */
-
-      conn->sockfd = sock;
-      conn->writesockfd = CURL_SOCKET_BAD;
-
-      if(conn->handler->protocol == CURLPROTO_SFTP) {
-        state(conn, SSH_SFTP_INIT);
-        break;
-      }
-      infof(data, "SSH CONNECT phase done\n");
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_INIT:
-      ssh_set_blocking(sshc->ssh_session, 1);
-
-      sshc->sftp_session = sftp_new(sshc->ssh_session);
-      if(!sshc->sftp_session) {
-        failf(data, "Failure initializing sftp session: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
-        break;
-      }
-
-      rc = sftp_init(sshc->sftp_session);
-      if(rc != SSH_OK) {
-        rc = sftp_get_error(sshc->sftp_session);
-        failf(data, "Failure initializing sftp session: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc));
-        break;
-      }
-      state(conn, SSH_SFTP_REALPATH);
-      /* FALLTHROUGH */
-    case SSH_SFTP_REALPATH:
-      /*
-       * Get the "home" directory
-       */
-      sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, ".");
-      if(sshc->homedir == NULL) {
-        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
-      }
-      conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
-
-      /* This is the last step in the SFTP connect phase. Do note that while
-         we get the homedir here, we get the "workingpath" in the DO action
-         since the homedir will remain the same between request but the
-         working path will not. */
-      DEBUGF(infof(data, "SSH CONNECT phase done\n"));
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_QUOTE_INIT:
-
-      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      if(data->set.quote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.quote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_SFTP_GETINFO);
-      }
-      break;
-
-    case SSH_SFTP_POSTQUOTE_INIT:
-      if(data->set.postquote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.postquote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_STOP);
-      }
-      break;
-
-    case SSH_SFTP_QUOTE:
-      /* Send any quote commands */
-      sftp_quote(conn);
-      break;
-
-    case SSH_SFTP_NEXT_QUOTE:
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-
-      sshc->quote_item = sshc->quote_item->next;
-
-      if(sshc->quote_item) {
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        if(sshc->nextstate != SSH_NO_STATE) {
-          state(conn, sshc->nextstate);
-          sshc->nextstate = SSH_NO_STATE;
-        }
-        else {
-          state(conn, SSH_SFTP_GETINFO);
-        }
-      }
-      break;
-
-    case SSH_SFTP_QUOTE_STAT:
-      sftp_quote_stat(conn);
-      break;
-
-    case SSH_SFTP_QUOTE_SETSTAT:
-      rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
-                        sshc->quote_attrs);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "Attempt to set SFTP stats failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        /* sshc->actualcode = sftp_error_to_CURLE(err);
-         * we do not send the actual error; we return
-         * the error the libssh2 backend is returning */
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_SYMLINK:
-      rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
-                        sshc->quote_path1);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "symlink command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_MKDIR:
-      rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
-                      (mode_t)data->set.new_directory_perms);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "mkdir command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RENAME:
-      rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
-                       sshc->quote_path2);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "rename command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RMDIR:
-      rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rmdir command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_UNLINK:
-      rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rm command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_STATVFS:
-    {
-      sftp_statvfs_t statvfs;
-
-      statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1);
-      if(!statvfs && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "statvfs command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      else if(statvfs) {
-        char *tmp = aprintf("statvfs:\n"
-                            "f_bsize: %llu\n" "f_frsize: %llu\n"
-                            "f_blocks: %llu\n" "f_bfree: %llu\n"
-                            "f_bavail: %llu\n" "f_files: %llu\n"
-                            "f_ffree: %llu\n" "f_favail: %llu\n"
-                            "f_fsid: %llu\n" "f_flag: %llu\n"
-                            "f_namemax: %llu\n",
-                            statvfs->f_bsize, statvfs->f_frsize,
-                            statvfs->f_blocks, statvfs->f_bfree,
-                            statvfs->f_bavail, statvfs->f_files,
-                            statvfs->f_ffree, statvfs->f_favail,
-                            statvfs->f_fsid, statvfs->f_flag,
-                            statvfs->f_namemax);
-        sftp_statvfs_free(statvfs);
-
-        if(!tmp) {
-          result = CURLE_OUT_OF_MEMORY;
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          break;
-        }
-
-        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-        free(tmp);
-        if(result) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-        }
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-    }
-
-    case SSH_SFTP_GETINFO:
-      if(data->set.get_filetime) {
-        state(conn, SSH_SFTP_FILETIME);
-      }
-      else {
-        state(conn, SSH_SFTP_TRANS_INIT);
-      }
-      break;
-
-    case SSH_SFTP_FILETIME:
-    {
-      sftp_attributes attrs;
-
-      attrs = sftp_stat(sshc->sftp_session, protop->path);
-      if(attrs != 0) {
-        data->info.filetime = attrs->mtime;
-        sftp_attributes_free(attrs);
-      }
-
-      state(conn, SSH_SFTP_TRANS_INIT);
-      break;
-    }
-
-    case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      else {
-        if(protop->path[strlen(protop->path)-1] == '/')
-          state(conn, SSH_SFTP_READDIR_INIT);
-        else
-          state(conn, SSH_SFTP_DOWNLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_UPLOAD_INIT:
-    {
-      int flags;
-
-      if(data->state.resume_from != 0) {
-        sftp_attributes attrs;
-
-        if(data->state.resume_from < 0) {
-          attrs = sftp_stat(sshc->sftp_session, protop->path);
-          if(attrs != 0) {
-            curl_off_t size = attrs->size;
-            if(size < 0) {
-              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-              MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME);
-            }
-            data->state.resume_from = attrs->size;
-
-            sftp_attributes_free(attrs);
-          }
-          else {
-            data->state.resume_from = 0;
-          }
-        }
-      }
-
-      if(data->set.ftp_append)
-        /* Try to open for append, but create if nonexisting */
-        flags = O_WRONLY|O_CREAT|O_APPEND;
-      else if(data->state.resume_from > 0)
-        /* If we have restart position then open for append */
-        flags = O_WRONLY|O_APPEND;
-      else
-        /* Clear file before writing (normal behaviour) */
-        flags = O_WRONLY|O_APPEND|O_CREAT|O_TRUNC;
-
-      if(sshc->sftp_file)
-        sftp_close(sshc->sftp_file);
-      sshc->sftp_file =
-        sftp_open(sshc->sftp_session, protop->path,
-                  flags, (mode_t)data->set.new_file_perms);
-      if(!sshc->sftp_file) {
-        err = sftp_get_error(sshc->sftp_session);
-
-        if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE ||
-             err == SSH_FX_NO_SUCH_PATH)) &&
-             (data->set.ftp_create_missing_dirs &&
-             (strlen(protop->path) > 1))) {
-               /* try to create the path remotely */
-               rc = 0;
-               sshc->secondCreateDirs = 1;
-               state(conn, SSH_SFTP_CREATE_DIRS_INIT);
-               break;
-        }
-        else {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-      }
-
-      /* If we have a restart point then we need to seek to the correct
-         position. */
-      if(data->state.resume_from > 0) {
-        /* Let's read off the proper amount of bytes from the input. */
-        if(conn->seek_func) {
-          Curl_set_in_callback(data, true);
-          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
-                                    SEEK_SET);
-          Curl_set_in_callback(data, false);
-        }
-
-        if(seekerr != CURL_SEEKFUNC_OK) {
-          curl_off_t passed = 0;
-
-          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
-            failf(data, "Could not seek stream");
-            return CURLE_FTP_COULDNT_USE_REST;
-          }
-          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-          do {
-            size_t readthisamountnow =
-              (data->state.resume_from - passed > data->set.buffer_size) ?
-              (size_t)data->set.buffer_size :
-              curlx_sotouz(data->state.resume_from - passed);
-
-            size_t actuallyread =
-              data->state.fread_func(data->state.buffer, 1,
-                                     readthisamountnow, data->state.in);
-
-            passed += actuallyread;
-            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-              /* this checks for greater-than only to make sure that the
-                 CURL_READFUNC_ABORT return code still aborts */
-              failf(data, "Failed to read data");
-              MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST);
-            }
-          } while(passed < data->state.resume_from);
-        }
-
-        /* now, decrease the size of the read */
-        if(data->state.infilesize > 0) {
-          data->state.infilesize -= data->state.resume_from;
-          data->req.size = data->state.infilesize;
-          Curl_pgrsSetUploadSize(data, data->state.infilesize);
-        }
-
-        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
-        if(rc != 0) {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-      }
-      if(data->state.infilesize > 0) {
-        data->req.size = data->state.infilesize;
-        Curl_pgrsSetUploadSize(data, data->state.infilesize);
-      }
-      /* upload data */
-      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      /* store this original bitmask setup to use later on if we can't
-         figure out a "real" bitmask */
-      sshc->orig_waitfor = data->req.keepon;
-
-      /* we want to use the _sending_ function even when the socket turns
-         out readable as the underlying libssh sftp send function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_OUT;
-
-      /* since we don't really wait for anything at this point, we want the
-         state machine to move on as soon as possible so we set a very short
-         timeout here */
-      Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
-      state(conn, SSH_STOP);
-      break;
-    }
-
-    case SSH_SFTP_CREATE_DIRS_INIT:
-      if(strlen(protop->path) > 1) {
-        sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */
-        state(conn, SSH_SFTP_CREATE_DIRS);
-      }
-      else {
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_CREATE_DIRS:
-      sshc->slash_pos = strchr(sshc->slash_pos, '/');
-      if(sshc->slash_pos) {
-        *sshc->slash_pos = 0;
-
-        infof(data, "Creating directory '%s'\n", protop->path);
-        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
-        break;
-      }
-      state(conn, SSH_SFTP_UPLOAD_INIT);
-      break;
-
-    case SSH_SFTP_CREATE_DIRS_MKDIR:
-      /* 'mode' - parameter is preliminary - default to 0644 */
-      rc = sftp_mkdir(sshc->sftp_session, protop->path,
-                      (mode_t)data->set.new_directory_perms);
-      *sshc->slash_pos = '/';
-      ++sshc->slash_pos;
-      if(rc < 0) {
-        /*
-         * Abort if failure wasn't that the dir already exists or the
-         * permission was denied (creation might succeed further down the
-         * path) - retry on unspecific FAILURE also
-         */
-        err = sftp_get_error(sshc->sftp_session);
-        if((err != SSH_FX_FILE_ALREADY_EXISTS) &&
-           (err != SSH_FX_FAILURE) &&
-           (err != SSH_FX_PERMISSION_DENIED)) {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-        rc = 0; /* clear rc and continue */
-      }
-      state(conn, SSH_SFTP_CREATE_DIRS);
-      break;
-
-    case SSH_SFTP_READDIR_INIT:
-      Curl_pgrsSetDownloadSize(data, -1);
-      if(data->set.opt_no_body) {
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      /*
-       * This is a directory that we are trying to get, so produce a directory
-       * listing
-       */
-      sshc->sftp_dir = sftp_opendir(sshc->sftp_session,
-                                    protop->path);
-      if(!sshc->sftp_dir) {
-        failf(data, "Could not open directory for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_SFTP_CLOSE_STATE();
-      }
-      state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR:
-
-      if(sshc->readdir_attrs)
-        sftp_attributes_free(sshc->readdir_attrs);
-
-      sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir);
-      if(sshc->readdir_attrs) {
-        sshc->readdir_filename = sshc->readdir_attrs->name;
-        sshc->readdir_longentry = sshc->readdir_attrs->longname;
-        sshc->readdir_len = strlen(sshc->readdir_filename);
-
-        if(data->set.ftp_list_only) {
-          char *tmpLine;
-
-          tmpLine = aprintf("%s\n", sshc->readdir_filename);
-          if(tmpLine == NULL) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-          result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                     tmpLine, sshc->readdir_len + 1);
-          free(tmpLine);
-
-          if(result) {
-            state(conn, SSH_STOP);
-            break;
-          }
-          /* since this counts what we send to the client, we include the
-             newline in this counter */
-          data->req.bytecount += sshc->readdir_len + 1;
-
-          /* output debug output if that is requested */
-          if(data->set.verbose) {
-            Curl_debug(data, CURLINFO_DATA_OUT,
-                       (char *)sshc->readdir_filename,
-                       sshc->readdir_len);
-          }
-        }
-        else {
-          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
-          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
-          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
-          if(!sshc->readdir_line) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-
-          memcpy(sshc->readdir_line, sshc->readdir_longentry,
-                 sshc->readdir_currLen);
-          if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
-             ((sshc->readdir_attrs->permissions & S_IFMT) ==
-              S_IFLNK)) {
-            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
-            if(sshc->readdir_linkPath == NULL) {
-              state(conn, SSH_SFTP_CLOSE);
-              sshc->actualcode = CURLE_OUT_OF_MEMORY;
-              break;
-            }
-
-            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path,
-                      sshc->readdir_filename);
-
-            state(conn, SSH_SFTP_READDIR_LINK);
-            break;
-          }
-          state(conn, SSH_SFTP_READDIR_BOTTOM);
-          break;
-        }
-      }
-      else if(sshc->readdir_attrs == NULL && sftp_dir_eof(sshc->sftp_dir)) {
-        state(conn, SSH_SFTP_READDIR_DONE);
-        break;
-      }
-      else {
-        failf(data, "Could not open remote file for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_SFTP_CLOSE_STATE();
-        break;
-      }
-      break;
-
-    case SSH_SFTP_READDIR_LINK:
-      if(sshc->readdir_link_attrs)
-        sftp_attributes_free(sshc->readdir_link_attrs);
-
-      sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session,
-                                            sshc->readdir_linkPath);
-      if(sshc->readdir_link_attrs == 0) {
-        failf(data, "Could not read symlink for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_SFTP_CLOSE_STATE();
-      }
-
-      if(sshc->readdir_link_attrs->name == NULL) {
-        sshc->readdir_tmp = sftp_readlink(sshc->sftp_session,
-                                          sshc->readdir_linkPath);
-        if(sshc->readdir_filename == NULL)
-          sshc->readdir_len = 0;
-        else
-          sshc->readdir_len = strlen(sshc->readdir_tmp);
-        sshc->readdir_longentry = NULL;
-        sshc->readdir_filename = sshc->readdir_tmp;
-      }
-      else {
-        sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
-        sshc->readdir_filename = sshc->readdir_link_attrs->name;
-        sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
-      }
-
-      Curl_safefree(sshc->readdir_linkPath);
-
-      /* get room for the filename and extra output */
-      sshc->readdir_totalLen += 4 + sshc->readdir_len;
-      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
-                                          sshc->readdir_totalLen);
-      if(!new_readdir_line) {
-        sshc->readdir_line = NULL;
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      sshc->readdir_line = new_readdir_line;
-
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen,
-                                         " -> %s",
-                                         sshc->readdir_filename);
-
-      sftp_attributes_free(sshc->readdir_link_attrs);
-      sshc->readdir_link_attrs = NULL;
-      sshc->readdir_filename = NULL;
-      sshc->readdir_longentry = NULL;
-
-      state(conn, SSH_SFTP_READDIR_BOTTOM);
-      /* FALLTHROUGH */
-    case SSH_SFTP_READDIR_BOTTOM:
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen, "\n");
-      result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                 sshc->readdir_line,
-                                 sshc->readdir_currLen);
-
-      if(!result) {
-
-        /* output debug output if that is requested */
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen);
-        }
-        data->req.bytecount += sshc->readdir_currLen;
-      }
-      Curl_safefree(sshc->readdir_line);
-      ssh_string_free_char(sshc->readdir_tmp);
-      sshc->readdir_tmp = NULL;
-
-      if(result) {
-        state(conn, SSH_STOP);
-      }
-      else
-        state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR_DONE:
-      sftp_closedir(sshc->sftp_dir);
-      sshc->sftp_dir = NULL;
-
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_INIT:
-      /*
-       * Work on getting the specified file
-       */
-      if(sshc->sftp_file)
-        sftp_close(sshc->sftp_file);
-
-      sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path,
-                                  O_RDONLY, (mode_t)data->set.new_file_perms);
-      if(!sshc->sftp_file) {
-        failf(data, "Could not open remote file for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-
-        MOVE_TO_SFTP_CLOSE_STATE();
-      }
-
-      state(conn, SSH_SFTP_DOWNLOAD_STAT);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_STAT:
-    {
-      sftp_attributes attrs;
-      curl_off_t size;
-
-      attrs = sftp_fstat(sshc->sftp_file);
-      if(!attrs ||
-              !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) ||
-              (attrs->size == 0)) {
-        /*
-         * sftp_fstat didn't return an error, so maybe the server
-         * just doesn't support stat()
-         * OR the server doesn't return a file size with a stat()
-         * OR file size is 0
-         */
-        data->req.size = -1;
-        data->req.maxdownload = -1;
-        Curl_pgrsSetDownloadSize(data, -1);
-        size = 0;
-      }
-      else {
-        size = attrs->size;
-
-        sftp_attributes_free(attrs);
-
-        if(size < 0) {
-          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-          return CURLE_BAD_DOWNLOAD_RESUME;
-        }
-        if(conn->data->state.use_range) {
-          curl_off_t from, to;
-          char *ptr;
-          char *ptr2;
-          CURLofft to_t;
-          CURLofft from_t;
-
-          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
-          if(from_t == CURL_OFFT_FLOW) {
-            return CURLE_RANGE_ERROR;
-          }
-          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
-            ptr++;
-          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
-          if(to_t == CURL_OFFT_FLOW) {
-            return CURLE_RANGE_ERROR;
-          }
-          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
-             || (to >= size)) {
-            to = size - 1;
-          }
-          if(from_t) {
-            /* from is relative to end of file */
-            from = size - to;
-            to = size - 1;
-          }
-          if(from > size) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")", from, size);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          if(from > to) {
-            from = to;
-            size = 0;
-          }
-          else {
-            size = to - from + 1;
-          }
-
-          rc = sftp_seek64(sshc->sftp_file, from);
-          if(rc != 0) {
-            MOVE_TO_SFTP_CLOSE_STATE();
-          }
-        }
-        data->req.size = size;
-        data->req.maxdownload = size;
-        Curl_pgrsSetDownloadSize(data, size);
-      }
-
-      /* We can resume if we can seek to the resume position */
-      if(data->state.resume_from) {
-        if(data->state.resume_from < 0) {
-          /* We're supposed to download the last abs(from) bytes */
-          if((curl_off_t)size < -data->state.resume_from) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, size);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          /* download from where? */
-          data->state.resume_from += size;
-        }
-        else {
-          if((curl_off_t)size < data->state.resume_from) {
-            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
-                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, size);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-        }
-        /* Does a completed file need to be seeked and started or closed ? */
-        /* Now store the number of bytes we are expected to download */
-        data->req.size = size - data->state.resume_from;
-        data->req.maxdownload = size - data->state.resume_from;
-        Curl_pgrsSetDownloadSize(data,
-                                 size - data->state.resume_from);
-
-        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
-        if(rc != 0) {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-      }
-    }
-
-    /* Setup the actual download */
-    if(data->req.size == 0) {
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      infof(data, "File already completely downloaded\n");
-      state(conn, SSH_STOP);
-      break;
-    }
-    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
-
-    /* not set by Curl_setup_transfer to preserve keepon bits */
-    conn->writesockfd = conn->sockfd;
-
-    /* we want to use the _receiving_ function even when the socket turns
-       out writableable as the underlying libssh recv function will deal
-       with both accordingly */
-    conn->cselect_bits = CURL_CSELECT_IN;
-
-    if(result) {
-      /* this should never occur; the close state should be entered
-         at the time the error occurs */
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->actualcode = result;
-    }
-    else {
-      sshc->sftp_recv_state = 0;
-      state(conn, SSH_STOP);
-    }
-    break;
-
-    case SSH_SFTP_CLOSE:
-      if(sshc->sftp_file) {
-        sftp_close(sshc->sftp_file);
-        sshc->sftp_file = NULL;
-      }
-      Curl_safefree(protop->path);
-
-      DEBUGF(infof(data, "SFTP DONE done\n"));
-
-      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
-         After nextstate is executed, the control should come back to
-         SSH_SFTP_CLOSE to pass the correct result back  */
-      if(sshc->nextstate != SSH_NO_STATE &&
-         sshc->nextstate != SSH_SFTP_CLOSE) {
-        state(conn, sshc->nextstate);
-        sshc->nextstate = SSH_SFTP_CLOSE;
-      }
-      else {
-        state(conn, SSH_STOP);
-        result = sshc->actualcode;
-      }
-      break;
-
-    case SSH_SFTP_SHUTDOWN:
-      /* during times we get here due to a broken transfer and then the
-         sftp_handle might not have been taken down so make sure that is done
-         before we proceed */
-
-      if(sshc->sftp_file) {
-        sftp_close(sshc->sftp_file);
-        sshc->sftp_file = NULL;
-      }
-
-      if(sshc->sftp_session) {
-        sftp_free(sshc->sftp_session);
-        sshc->sftp_session = NULL;
-      }
-
-      SSH_STRING_FREE_CHAR(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_DISCONNECT);
-      break;
-
-
-    case SSH_SCP_TRANS_INIT:
-      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
-      ssh_set_blocking(sshc->ssh_session, 1);
-
-      if(data->set.upload) {
-        if(data->state.infilesize < 0) {
-          failf(data, "SCP requires a known file size for upload");
-          sshc->actualcode = CURLE_UPLOAD_FAILED;
-          MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-        }
-
-        sshc->scp_session =
-          ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path);
-        state(conn, SSH_SCP_UPLOAD_INIT);
-      }
-      else {
-        sshc->scp_session =
-          ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path);
-        state(conn, SSH_SCP_DOWNLOAD_INIT);
-      }
-
-      if(!sshc->scp_session) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-      }
-
-      break;
-
-    case SSH_SCP_UPLOAD_INIT:
-
-      rc = ssh_scp_init(sshc->scp_session);
-      if(rc != SSH_OK) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-      }
-
-      rc = ssh_scp_push_file(sshc->scp_session, protop->path,
-                             data->state.infilesize,
-                             (int)data->set.new_file_perms);
-      if(rc != SSH_OK) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-      }
-
-      /* upload data */
-      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      /* store this original bitmask setup to use later on if we can't
-         figure out a "real" bitmask */
-      sshc->orig_waitfor = data->req.keepon;
-
-      /* we want to use the _sending_ function even when the socket turns
-         out readable as the underlying libssh scp send function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_OUT;
-
-      state(conn, SSH_STOP);
-
-      break;
-
-    case SSH_SCP_DOWNLOAD_INIT:
-
-      rc = ssh_scp_init(sshc->scp_session);
-      if(rc != SSH_OK) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
-      }
-      state(conn, SSH_SCP_DOWNLOAD);
-      /* FALLTHROUGH */
-
-    case SSH_SCP_DOWNLOAD:{
-        curl_off_t bytecount;
-
-        rc = ssh_scp_pull_request(sshc->scp_session);
-        if(rc != SSH_SCP_REQUEST_NEWFILE) {
-          err_msg = ssh_get_error(sshc->ssh_session);
-          failf(conn->data, "%s", err_msg);
-          MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND);
-          break;
-        }
-
-        /* download data */
-        bytecount = ssh_scp_request_get_size(sshc->scp_session);
-        data->req.maxdownload = (curl_off_t) bytecount;
-        Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
-
-        /* not set by Curl_setup_transfer to preserve keepon bits */
-        conn->writesockfd = conn->sockfd;
-
-        /* we want to use the _receiving_ function even when the socket turns
-           out writableable as the underlying libssh recv function will deal
-           with both accordingly */
-        conn->cselect_bits = CURL_CSELECT_IN;
-
-        state(conn, SSH_STOP);
-        break;
-      }
-    case SSH_SCP_DONE:
-      if(data->set.upload)
-        state(conn, SSH_SCP_SEND_EOF);
-      else
-        state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_SEND_EOF:
-      if(sshc->scp_session) {
-        rc = ssh_scp_close(sshc->scp_session);
-        if(rc == SSH_AGAIN) {
-          /* Currently the ssh_scp_close handles waiting for EOF in
-           * blocking way.
-           */
-          break;
-        }
-        if(rc != SSH_OK) {
-          infof(data, "Failed to close libssh scp channel: %s\n",
-                ssh_get_error(sshc->ssh_session));
-        }
-      }
-
-      state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_CHANNEL_FREE:
-      if(sshc->scp_session) {
-        ssh_scp_free(sshc->scp_session);
-        sshc->scp_session = NULL;
-      }
-      DEBUGF(infof(data, "SCP DONE phase complete\n"));
-
-      ssh_set_blocking(sshc->ssh_session, 0);
-
-      state(conn, SSH_SESSION_DISCONNECT);
-      /* FALLTHROUGH */
-
-    case SSH_SESSION_DISCONNECT:
-      /* during weird times when we've been prematurely aborted, the channel
-         is still alive when we reach this state and we MUST kill the channel
-         properly first */
-      if(sshc->scp_session) {
-        ssh_scp_free(sshc->scp_session);
-        sshc->scp_session = NULL;
-      }
-
-      ssh_disconnect(sshc->ssh_session);
-
-      SSH_STRING_FREE_CHAR(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_FREE);
-      /* FALLTHROUGH */
-    case SSH_SESSION_FREE:
-      if(sshc->ssh_session) {
-        ssh_free(sshc->ssh_session);
-        sshc->ssh_session = NULL;
-      }
-
-      /* worst-case scenario cleanup */
-
-      DEBUGASSERT(sshc->ssh_session == NULL);
-      DEBUGASSERT(sshc->scp_session == NULL);
-
-      if(sshc->readdir_tmp) {
-        ssh_string_free_char(sshc->readdir_tmp);
-        sshc->readdir_tmp = NULL;
-      }
-
-      if(sshc->quote_attrs)
-        sftp_attributes_free(sshc->quote_attrs);
-
-      if(sshc->readdir_attrs)
-        sftp_attributes_free(sshc->readdir_attrs);
-
-      if(sshc->readdir_link_attrs)
-        sftp_attributes_free(sshc->readdir_link_attrs);
-
-      if(sshc->privkey)
-        ssh_key_free(sshc->privkey);
-      if(sshc->pubkey)
-        ssh_key_free(sshc->pubkey);
-
-      Curl_safefree(sshc->rsa_pub);
-      Curl_safefree(sshc->rsa);
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      Curl_safefree(sshc->readdir_line);
-      Curl_safefree(sshc->readdir_linkPath);
-      SSH_STRING_FREE_CHAR(sshc->homedir);
-
-      /* the code we are about to return */
-      result = sshc->actualcode;
-
-      memset(sshc, 0, sizeof(struct ssh_conn));
-
-      connclose(conn, "SSH session free");
-      sshc->state = SSH_SESSION_FREE;   /* current */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_QUIT:
-      /* fallthrough, just stop! */
-    default:
-      /* internal error */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-
-    }
-  } while(!rc && (sshc->state != SSH_STOP));
-
-
-  if(rc == SSH_AGAIN) {
-    /* we would block, we need to wait for the socket to be ready (in the
-       right direction too)! */
-    *block = TRUE;
-  }
-
-  return result;
-}
-
-
-/* called by the multi interface to figure out what socket(s) to wait for and
-   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
-static int myssh_perform_getsock(const struct connectdata *conn,
-                                 curl_socket_t *sock,  /* points to numsocks
-                                                          number of sockets */
-                                 int numsocks)
-{
-  int bitmap = GETSOCK_BLANK;
-  (void) numsocks;
-
-  sock[0] = conn->sock[FIRSTSOCKET];
-
-  if(conn->waitfor & KEEP_RECV)
-    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
-
-  if(conn->waitfor & KEEP_SEND)
-    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
-
-  return bitmap;
-}
-
-/* Generic function called by the multi interface to figure out what socket(s)
-   to wait for and for what actions during the DOING and PROTOCONNECT states*/
-static int myssh_getsock(struct connectdata *conn,
-                         curl_socket_t *sock,  /* points to numsocks
-                                                   number of sockets */
-                         int numsocks)
-{
-  /* if we know the direction we can use the generic *_getsock() function even
-     for the protocol_connect and doing states */
-  return myssh_perform_getsock(conn, sock, numsocks);
-}
-
-static void myssh_block2waitfor(struct connectdata *conn, bool block)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  /* If it didn't block, or nothing was returned by ssh_get_poll_flags
-   * have the original set */
-  conn->waitfor = sshc->orig_waitfor;
-
-  if(block) {
-    int dir = ssh_get_poll_flags(sshc->ssh_session);
-    if(dir & SSH_READ_PENDING) {
-      /* translate the libssh define bits into our own bit defines */
-      conn->waitfor = KEEP_RECV;
-    }
-    else if(dir & SSH_WRITE_PENDING) {
-      conn->waitfor = KEEP_SEND;
-    }
-  }
-}
-
-/* called repeatedly until done from multi.c */
-static CURLcode myssh_multi_statemach(struct connectdata *conn,
-                                      bool *done)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  bool block;    /* we store the status and use that to provide a ssh_getsock()
-                    implementation */
-  CURLcode result = myssh_statemach_act(conn, &block);
-
-  *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
-  myssh_block2waitfor(conn, block);
-
-  return result;
-}
-
-static CURLcode myssh_block_statemach(struct connectdata *conn,
-                                      bool disconnect)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-
-  while((sshc->state != SSH_STOP) && !result) {
-    bool block;
-    timediff_t left = 1000;
-    struct curltime now = Curl_now();
-
-    result = myssh_statemach_act(conn, &block);
-    if(result)
-      break;
-
-    if(!disconnect) {
-      if(Curl_pgrsUpdate(conn))
-        return CURLE_ABORTED_BY_CALLBACK;
-
-      result = Curl_speedcheck(data, now);
-      if(result)
-        break;
-
-      left = Curl_timeleft(data, NULL, FALSE);
-      if(left < 0) {
-        failf(data, "Operation timed out");
-        return CURLE_OPERATION_TIMEDOUT;
-      }
-    }
-
-    if(!result && block) {
-      curl_socket_t fd_read = conn->sock[FIRSTSOCKET];
-      /* wait for the socket to become ready */
-      (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD,
-                               CURL_SOCKET_BAD, left > 1000 ? 1000 : left);
-    }
-
-  }
-
-  return result;
-}
-
-/*
- * SSH setup connection
- */
-static CURLcode myssh_setup_connection(struct connectdata *conn)
-{
-  struct SSHPROTO *ssh;
-
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
-  if(!ssh)
-    return CURLE_OUT_OF_MEMORY;
-
-  return CURLE_OK;
-}
-
-static Curl_recv scp_recv, sftp_recv;
-static Curl_send scp_send, sftp_send;
-
-/*
- * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
- * do protocol-specific actions at connect-time.
- */
-static CURLcode myssh_connect(struct connectdata *conn, bool *done)
-{
-  struct ssh_conn *ssh;
-  CURLcode result;
-  curl_socket_t sock = conn->sock[FIRSTSOCKET];
-  struct Curl_easy *data = conn->data;
-
-  /* initialize per-handle data if not already */
-  if(!data->req.protop)
-    myssh_setup_connection(conn);
-
-  /* We default to persistent connections. We set this already in this connect
-     function to make the re-use checks properly be able to check this bit. */
-  connkeep(conn, "SSH default");
-
-  if(conn->handler->protocol & CURLPROTO_SCP) {
-    conn->recv[FIRSTSOCKET] = scp_recv;
-    conn->send[FIRSTSOCKET] = scp_send;
-  }
-  else {
-    conn->recv[FIRSTSOCKET] = sftp_recv;
-    conn->send[FIRSTSOCKET] = sftp_send;
-  }
-
-  ssh = &conn->proto.sshc;
-
-  ssh->ssh_session = ssh_new();
-  if(ssh->ssh_session == NULL) {
-    failf(data, "Failure initialising ssh session");
-    return CURLE_FAILED_INIT;
-  }
-
-  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
-
-  if(conn->user) {
-    infof(data, "User: %s\n", conn->user);
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
-  }
-
-  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-    infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]);
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS,
-                    data->set.str[STRING_SSH_KNOWNHOSTS]);
-  }
-
-  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
-  if(conn->remote_port)
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT,
-                    &conn->remote_port);
-
-  if(data->set.ssh_compression) {
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION,
-                    "zlib,zlib@openssh.com,none");
-  }
-
-  ssh->privkey = NULL;
-  ssh->pubkey = NULL;
-
-  if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
-    int rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
-                                        &ssh->pubkey);
-    if(rc != SSH_OK) {
-      failf(data, "Could not load public key file");
-      /* ignore */
-    }
-  }
-
-  /* we do not verify here, we do it at the state machine,
-   * after connection */
-
-  state(conn, SSH_INIT);
-
-  result = myssh_multi_statemach(conn, done);
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
-{
-  CURLcode result;
-
-  result = myssh_multi_statemach(conn, dophase_done);
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/*
- ***********************************************************************
- *
- * scp_perform()
- *
- * This is the actual DO function for SCP. Get a file according to
- * the options previously setup.
- */
-
-static
-CURLcode scp_perform(struct connectdata *conn,
-                     bool *connected, bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE;        /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SCP_TRANS_INIT);
-
-  result = myssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
-{
-  CURLcode result;
-  bool connected = 0;
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  *done = FALSE;                /* default to false */
-
-  data->req.size = -1;          /* make sure this is unknown at this point */
-
-  sshc->actualcode = CURLE_OK;  /* reset error code */
-  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
-                                   variable */
-
-  Curl_pgrsSetUploadCounter(data, 0);
-  Curl_pgrsSetDownloadCounter(data, 0);
-  Curl_pgrsSetUploadSize(data, -1);
-  Curl_pgrsSetDownloadSize(data, -1);
-
-  if(conn->handler->protocol & CURLPROTO_SCP)
-    result = scp_perform(conn, &connected, done);
-  else
-    result = sftp_perform(conn, &connected, done);
-
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode scp_disconnect(struct connectdata *conn,
-                               bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  struct ssh_conn *ssh = &conn->proto.sshc;
-  (void) dead_connection;
-
-  if(ssh->ssh_session) {
-    /* only if there's a session still around to use! */
-
-    state(conn, SSH_SESSION_DISCONNECT);
-
-    result = myssh_block_statemach(conn, TRUE);
-  }
-
-  return result;
-}
-
-/* generic done function for both SCP and SFTP called from their specific
-   done functions */
-static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
-{
-  CURLcode result = CURLE_OK;
-  struct SSHPROTO *protop = conn->data->req.protop;
-
-  if(!status) {
-    /* run the state-machine */
-    result = myssh_block_statemach(conn, FALSE);
-  }
-  else
-    result = status;
-
-  if(protop)
-    Curl_safefree(protop->path);
-  if(Curl_pgrsDone(conn))
-    return CURLE_ABORTED_BY_CALLBACK;
-
-  conn->data->req.keepon = 0;   /* clear all bits */
-  return result;
-}
-
-
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
-                         bool premature)
-{
-  (void) premature;             /* not used */
-
-  if(!status)
-    state(conn, SSH_SCP_DONE);
-
-  return myssh_done(conn, status);
-
-}
-
-static ssize_t scp_send(struct connectdata *conn, int sockindex,
-                        const void *mem, size_t len, CURLcode *err)
-{
-  int rc;
-  (void) sockindex; /* we only support SCP on the fixed known primary socket */
-  (void) err;
-
-  rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len);
-
-#if 0
-  /* The following code is misleading, mostly added as wishful thinking
-   * that libssh at some point will implement non-blocking ssh_scp_write/read.
-   * Currently rc can only be number of bytes read or SSH_ERROR. */
-  myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE);
-
-  if(rc == SSH_AGAIN) {
-    *err = CURLE_AGAIN;
-    return 0;
-  }
-  else
-#endif
-  if(rc != SSH_OK) {
-    *err = CURLE_SSH;
-    return -1;
-  }
-
-  return len;
-}
-
-static ssize_t scp_recv(struct connectdata *conn, int sockindex,
-                        char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void) err;
-  (void) sockindex; /* we only support SCP on the fixed known primary socket */
-
-  /* libssh returns int */
-  nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len);
-
-#if 0
-  /* The following code is misleading, mostly added as wishful thinking
-   * that libssh at some point will implement non-blocking ssh_scp_write/read.
-   * Currently rc can only be SSH_OK or SSH_ERROR. */
-
-  myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE);
-  if(nread == SSH_AGAIN) {
-    *err = CURLE_AGAIN;
-    nread = -1;
-  }
-#endif
-
-  return nread;
-}
-
-/*
- * =============== SFTP ===============
- */
-
-/*
- ***********************************************************************
- *
- * sftp_perform()
- *
- * This is the actual DO function for SFTP. Get a file/directory according to
- * the options previously setup.
- */
-
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE; /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SFTP_QUOTE_INIT);
-
-  /* run the state-machine */
-  result = myssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done)
-{
-  CURLcode result = myssh_multi_statemach(conn, dophase_done);
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  (void) dead_connection;
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
-
-  if(conn->proto.sshc.ssh_session) {
-    /* only if there's a session still around to use! */
-    state(conn, SSH_SFTP_SHUTDOWN);
-    result = myssh_block_statemach(conn, TRUE);
-  }
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
-
-  return result;
-
-}
-
-static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
-                               bool premature)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  if(!status) {
-    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
-       errors that could happen due to open file handles during POSTQUOTE
-       operation */
-    if(!premature && conn->data->set.postquote && !conn->bits.retry)
-      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
-    state(conn, SSH_SFTP_CLOSE);
-  }
-  return myssh_done(conn, status);
-}
-
-/* return number of sent bytes */
-static ssize_t sftp_send(struct connectdata *conn, int sockindex,
-                         const void *mem, size_t len, CURLcode *err)
-{
-  ssize_t nwrite;
-  (void)sockindex;
-
-  nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
-
-  myssh_block2waitfor(conn, FALSE);
-
-#if 0 /* not returned by libssh on write */
-  if(nwrite == SSH_AGAIN) {
-    *err = CURLE_AGAIN;
-    nwrite = 0;
-  }
-  else
-#endif
-  if(nwrite < 0) {
-    *err = CURLE_SSH;
-    nwrite = -1;
-  }
-
-  return nwrite;
-}
-
-/*
- * Return number of received (decrypted) bytes
- * or <0 on error
- */
-static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
-                         char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void)sockindex;
-
-  DEBUGASSERT(len < CURL_MAX_READ_SIZE);
-
-  switch(conn->proto.sshc.sftp_recv_state) {
-    case 0:
-      conn->proto.sshc.sftp_file_index =
-            sftp_async_read_begin(conn->proto.sshc.sftp_file,
-                                  (uint32_t)len);
-      if(conn->proto.sshc.sftp_file_index < 0) {
-        *err = CURLE_RECV_ERROR;
-        return -1;
-      }
-
-      /* FALLTHROUGH */
-    case 1:
-      conn->proto.sshc.sftp_recv_state = 1;
-
-      nread = sftp_async_read(conn->proto.sshc.sftp_file,
-                              mem, (uint32_t)len,
-                              conn->proto.sshc.sftp_file_index);
-
-      myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE);
-
-      if(nread == SSH_AGAIN) {
-        *err = CURLE_AGAIN;
-        return -1;
-      }
-      else if(nread < 0) {
-        *err = CURLE_RECV_ERROR;
-        return -1;
-      }
-
-      conn->proto.sshc.sftp_recv_state = 0;
-      return nread;
-
-    default:
-      /* we never reach here */
-      return -1;
-  }
-}
-
-static void sftp_quote(struct connectdata *conn)
-{
-  const char *cp;
-  struct Curl_easy *data = conn->data;
-  struct SSHPROTO *protop = data->req.protop;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result;
-
-  /*
-   * Support some of the "FTP" commands
-   */
-  char *cmd = sshc->quote_item->data;
-  sshc->acceptfail = FALSE;
-
-  /* if a command starts with an asterisk, which a legal SFTP command never
-     can, the command will be allowed to fail without it causing any
-     aborts or cancels etc. It will cause libcurl to act as if the command
-     is successful, whatever the server reponds. */
-
-  if(cmd[0] == '*') {
-    cmd++;
-    sshc->acceptfail = TRUE;
-  }
-
-  if(strcasecompare("pwd", cmd)) {
-    /* output debug output if that is requested */
-    char *tmp = aprintf("257 \"%s\" is current directory.\n",
-                        protop->path);
-    if(!tmp) {
-      sshc->actualcode = CURLE_OUT_OF_MEMORY;
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      return;
-    }
-    if(data->set.verbose) {
-      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
-      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
-    }
-    /* this sends an FTP-like "header" to the header callback so that the
-       current directory can be read very similar to how it is read when
-       using ordinary FTP. */
-    result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-    free(tmp);
-    if(result) {
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-    }
-    else
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-    return;
-  }
-
-  /*
-   * the arguments following the command must be separated from the
-   * command with a space so we can check for it unconditionally
-   */
-  cp = strchr(cmd, ' ');
-  if(cp == NULL) {
-    failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
-    state(conn, SSH_SFTP_CLOSE);
-    sshc->nextstate = SSH_NO_STATE;
-    sshc->actualcode = CURLE_QUOTE_ERROR;
-    return;
-  }
-
-  /*
-   * also, every command takes at least one argument so we get that
-   * first argument right now
-   */
-  result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
-  if(result) {
-    if(result == CURLE_OUT_OF_MEMORY)
-      failf(data, "Out of memory");
-    else
-      failf(data, "Syntax error: Bad first parameter");
-    state(conn, SSH_SFTP_CLOSE);
-    sshc->nextstate = SSH_NO_STATE;
-    sshc->actualcode = result;
-    return;
-  }
-
-  /*
-   * SFTP is a binary protocol, so we don't send text commands
-   * to the server. Instead, we scan for commands used by
-   * OpenSSH's sftp program and call the appropriate libssh
-   * functions.
-   */
-  if(strncasecompare(cmd, "chgrp ", 6) ||
-     strncasecompare(cmd, "chmod ", 6) ||
-     strncasecompare(cmd, "chown ", 6)) {
-    /* attribute change */
-
-    /* sshc->quote_path1 contains the mode to set */
-    /* get the destination */
-    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-    if(result) {
-      if(result == CURLE_OUT_OF_MEMORY)
-        failf(data, "Out of memory");
-      else
-        failf(data, "Syntax error in chgrp/chmod/chown: "
-              "Bad second parameter");
-      Curl_safefree(sshc->quote_path1);
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-      return;
-    }
-    sshc->quote_attrs = NULL;
-    state(conn, SSH_SFTP_QUOTE_STAT);
-    return;
-  }
-  if(strncasecompare(cmd, "ln ", 3) ||
-     strncasecompare(cmd, "symlink ", 8)) {
-    /* symbolic linking */
-    /* sshc->quote_path1 is the source */
-    /* get the destination */
-    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-    if(result) {
-      if(result == CURLE_OUT_OF_MEMORY)
-        failf(data, "Out of memory");
-      else
-        failf(data, "Syntax error in ln/symlink: Bad second parameter");
-      Curl_safefree(sshc->quote_path1);
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-      return;
-    }
-    state(conn, SSH_SFTP_QUOTE_SYMLINK);
-    return;
-  }
-  else if(strncasecompare(cmd, "mkdir ", 6)) {
-    /* create dir */
-    state(conn, SSH_SFTP_QUOTE_MKDIR);
-    return;
-  }
-  else if(strncasecompare(cmd, "rename ", 7)) {
-    /* rename file */
-    /* first param is the source path */
-    /* second param is the dest. path */
-    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-    if(result) {
-      if(result == CURLE_OUT_OF_MEMORY)
-        failf(data, "Out of memory");
-      else
-        failf(data, "Syntax error in rename: Bad second parameter");
-      Curl_safefree(sshc->quote_path1);
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-      return;
-    }
-    state(conn, SSH_SFTP_QUOTE_RENAME);
-    return;
-  }
-  else if(strncasecompare(cmd, "rmdir ", 6)) {
-    /* delete dir */
-    state(conn, SSH_SFTP_QUOTE_RMDIR);
-    return;
-  }
-  else if(strncasecompare(cmd, "rm ", 3)) {
-    state(conn, SSH_SFTP_QUOTE_UNLINK);
-    return;
-  }
-#ifdef HAS_STATVFS_SUPPORT
-  else if(strncasecompare(cmd, "statvfs ", 8)) {
-    state(conn, SSH_SFTP_QUOTE_STATVFS);
-    return;
-  }
-#endif
-
-  failf(data, "Unknown SFTP command");
-  Curl_safefree(sshc->quote_path1);
-  Curl_safefree(sshc->quote_path2);
-  state(conn, SSH_SFTP_CLOSE);
-  sshc->nextstate = SSH_NO_STATE;
-  sshc->actualcode = CURLE_QUOTE_ERROR;
-}
-
-static void sftp_quote_stat(struct connectdata *conn)
-{
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  char *cmd = sshc->quote_item->data;
-  sshc->acceptfail = FALSE;
-
-  /* if a command starts with an asterisk, which a legal SFTP command never
-     can, the command will be allowed to fail without it causing any
-     aborts or cancels etc. It will cause libcurl to act as if the command
-     is successful, whatever the server reponds. */
-
-  if(cmd[0] == '*') {
-    cmd++;
-    sshc->acceptfail = TRUE;
-  }
-
-  /* We read the file attributes, store them in sshc->quote_attrs
-   * and modify them accordingly to command. Then we switch to
-   * QUOTE_SETSTAT state to write new ones.
-   */
-
-  if(sshc->quote_attrs)
-    sftp_attributes_free(sshc->quote_attrs);
-  sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2);
-  if(sshc->quote_attrs == NULL) {
-    Curl_safefree(sshc->quote_path1);
-    Curl_safefree(sshc->quote_path2);
-    failf(data, "Attempt to get SFTP stats failed: %d",
-          sftp_get_error(sshc->sftp_session));
-    state(conn, SSH_SFTP_CLOSE);
-    sshc->nextstate = SSH_NO_STATE;
-    sshc->actualcode = CURLE_QUOTE_ERROR;
-    return;
-  }
-
-  /* Now set the new attributes... */
-  if(strncasecompare(cmd, "chgrp", 5)) {
-    sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
-    if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-        !sshc->acceptfail) {
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      failf(data, "Syntax error: chgrp gid not a number");
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_QUOTE_ERROR;
-      return;
-    }
-    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
-  }
-  else if(strncasecompare(cmd, "chmod", 5)) {
-    mode_t perms;
-    perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8);
-    /* permissions are octal */
-    if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) {
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      failf(data, "Syntax error: chmod permissions not a number");
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_QUOTE_ERROR;
-      return;
-    }
-    sshc->quote_attrs->permissions = perms;
-    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
-  }
-  else if(strncasecompare(cmd, "chown", 5)) {
-    sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
-    if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-        !sshc->acceptfail) {
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      failf(data, "Syntax error: chown uid not a number");
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_QUOTE_ERROR;
-      return;
-    }
-    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
-  }
-
-  /* Now send the completed structure... */
-  state(conn, SSH_SFTP_QUOTE_SETSTAT);
-  return;
-}
-
-
-#endif                          /* USE_LIBSSH */
diff --git a/libs/libcurl/src/ssh.c b/libs/libcurl/src/ssh.c
deleted file mode 100644
index a265c3c9ad..0000000000
--- a/libs/libcurl/src/ssh.c
+++ /dev/null
@@ -1,3337 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * 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.
- *
- ***************************************************************************/
-
-/* #define CURL_LIBSSH2_DEBUG */
-
-#include "curl_setup.h"
-
-#ifdef USE_LIBSSH2
-
-#include <limits.h>
-
-#include <libssh2.h>
-#include <libssh2_sftp.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef __VMS
-#include <in.h>
-#include <inet.h>
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "progress.h"
-#include "transfer.h"
-#include "escape.h"
-#include "http.h" /* for HTTP proxy tunnel stuff */
-#include "ssh.h"
-#include "url.h"
-#include "speedcheck.h"
-#include "getinfo.h"
-#include "strdup.h"
-#include "strcase.h"
-#include "vtls/vtls.h"
-#include "connect.h"
-#include "strerror.h"
-#include "inet_ntop.h"
-#include "parsedate.h" /* for the week day and month names */
-#include "sockaddr.h" /* required for Curl_sockaddr_storage */
-#include "strtoofft.h"
-#include "multiif.h"
-#include "select.h"
-#include "warnless.h"
-#include "curl_path.h"
-
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-
-#if LIBSSH2_VERSION_NUM >= 0x010206
-/* libssh2_sftp_statvfs and friends were added in 1.2.6 */
-#define HAS_STATVFS_SUPPORT 1
-#endif
-
-#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
-
-#define sftp_libssh2_realpath(s,p,t,m) \
-        libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
-                                (t), (m), LIBSSH2_SFTP_REALPATH)
-
-
-/* Local functions: */
-static const char *sftp_libssh2_strerror(int err);
-static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
-static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
-static LIBSSH2_FREE_FUNC(my_libssh2_free);
-
-static CURLcode ssh_connect(struct connectdata *conn, bool *done);
-static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
-static CURLcode ssh_do(struct connectdata *conn, bool *done);
-
-static CURLcode scp_done(struct connectdata *conn,
-                         CURLcode, bool premature);
-static CURLcode scp_doing(struct connectdata *conn,
-                          bool *dophase_done);
-static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
-
-static CURLcode sftp_done(struct connectdata *conn,
-                          CURLcode, bool premature);
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done);
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done);
-
-static int ssh_getsock(struct connectdata *conn,
-                       curl_socket_t *sock, /* points to numsocks number
-                                               of sockets */
-                       int numsocks);
-
-static int ssh_perform_getsock(const struct connectdata *conn,
-                               curl_socket_t *sock, /* points to numsocks
-                                                       number of sockets */
-                               int numsocks);
-
-static CURLcode ssh_setup_connection(struct connectdata *conn);
-
-/*
- * SCP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_scp = {
-  "SCP",                                /* scheme */
-  ssh_setup_connection,                 /* setup_connection */
-  ssh_do,                               /* do_it */
-  scp_done,                             /* done */
-  ZERO_NULL,                            /* do_more */
-  ssh_connect,                          /* connect_it */
-  ssh_multi_statemach,                  /* connecting */
-  scp_doing,                            /* doing */
-  ssh_getsock,                          /* proto_getsock */
-  ssh_getsock,                          /* doing_getsock */
-  ZERO_NULL,                            /* domore_getsock */
-  ssh_perform_getsock,                  /* perform_getsock */
-  scp_disconnect,                       /* disconnect */
-  ZERO_NULL,                            /* readwrite */
-  ZERO_NULL,                            /* connection_check */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SCP,                        /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
-  | PROTOPT_NOURLQUERY                  /* flags */
-};
-
-
-/*
- * SFTP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_sftp = {
-  "SFTP",                               /* scheme */
-  ssh_setup_connection,                 /* setup_connection */
-  ssh_do,                               /* do_it */
-  sftp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  ssh_connect,                          /* connect_it */
-  ssh_multi_statemach,                  /* connecting */
-  sftp_doing,                           /* doing */
-  ssh_getsock,                          /* proto_getsock */
-  ssh_getsock,                          /* doing_getsock */
-  ZERO_NULL,                            /* domore_getsock */
-  ssh_perform_getsock,                  /* perform_getsock */
-  sftp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* readwrite */
-  ZERO_NULL,                            /* connection_check */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SFTP,                       /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
-  | PROTOPT_NOURLQUERY                  /* flags */
-};
-
-static void
-kbd_callback(const char *name, int name_len, const char *instruction,
-             int instruction_len, int num_prompts,
-             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
-             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
-             void **abstract)
-{
-  struct connectdata *conn = (struct connectdata *)*abstract;
-
-#ifdef CURL_LIBSSH2_DEBUG
-  fprintf(stderr, "name=%s\n", name);
-  fprintf(stderr, "name_len=%d\n", name_len);
-  fprintf(stderr, "instruction=%s\n", instruction);
-  fprintf(stderr, "instruction_len=%d\n", instruction_len);
-  fprintf(stderr, "num_prompts=%d\n", num_prompts);
-#else
-  (void)name;
-  (void)name_len;
-  (void)instruction;
-  (void)instruction_len;
-#endif  /* CURL_LIBSSH2_DEBUG */
-  if(num_prompts == 1) {
-    responses[0].text = strdup(conn->passwd);
-    responses[0].length = curlx_uztoui(strlen(conn->passwd));
-  }
-  (void)prompts;
-  (void)abstract;
-} /* kbd_callback */
-
-static CURLcode sftp_libssh2_error_to_CURLE(int err)
-{
-  switch(err) {
-    case LIBSSH2_FX_OK:
-      return CURLE_OK;
-
-    case LIBSSH2_FX_NO_SUCH_FILE:
-    case LIBSSH2_FX_NO_SUCH_PATH:
-      return CURLE_REMOTE_FILE_NOT_FOUND;
-
-    case LIBSSH2_FX_PERMISSION_DENIED:
-    case LIBSSH2_FX_WRITE_PROTECT:
-    case LIBSSH2_FX_LOCK_CONFlICT:
-      return CURLE_REMOTE_ACCESS_DENIED;
-
-    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
-    case LIBSSH2_FX_QUOTA_EXCEEDED:
-      return CURLE_REMOTE_DISK_FULL;
-
-    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
-      return CURLE_REMOTE_FILE_EXISTS;
-
-    case LIBSSH2_FX_DIR_NOT_EMPTY:
-      return CURLE_QUOTE_ERROR;
-
-    default:
-      break;
-  }
-
-  return CURLE_SSH;
-}
-
-static CURLcode libssh2_session_error_to_CURLE(int err)
-{
-  switch(err) {
-    /* Ordered by order of appearance in libssh2.h */
-    case LIBSSH2_ERROR_NONE:
-      return CURLE_OK;
-
-    /* This is the error returned by libssh2_scp_recv2
-     * on unknown file */
-    case LIBSSH2_ERROR_SCP_PROTOCOL:
-      return CURLE_REMOTE_FILE_NOT_FOUND;
-
-    case LIBSSH2_ERROR_SOCKET_NONE:
-      return CURLE_COULDNT_CONNECT;
-
-    case LIBSSH2_ERROR_ALLOC:
-      return CURLE_OUT_OF_MEMORY;
-
-    case LIBSSH2_ERROR_SOCKET_SEND:
-      return CURLE_SEND_ERROR;
-
-    case LIBSSH2_ERROR_HOSTKEY_INIT:
-    case LIBSSH2_ERROR_HOSTKEY_SIGN:
-    case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
-    case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
-      return CURLE_PEER_FAILED_VERIFICATION;
-
-    case LIBSSH2_ERROR_PASSWORD_EXPIRED:
-      return CURLE_LOGIN_DENIED;
-
-    case LIBSSH2_ERROR_SOCKET_TIMEOUT:
-    case LIBSSH2_ERROR_TIMEOUT:
-      return CURLE_OPERATION_TIMEDOUT;
-
-    case LIBSSH2_ERROR_EAGAIN:
-      return CURLE_AGAIN;
-  }
-
-  return CURLE_SSH;
-}
-
-static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
-{
-  (void)abstract; /* arg not used */
-  return malloc(count);
-}
-
-static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
-{
-  (void)abstract; /* arg not used */
-  return realloc(ptr, count);
-}
-
-static LIBSSH2_FREE_FUNC(my_libssh2_free)
-{
-  (void)abstract; /* arg not used */
-  if(ptr) /* ssh2 agent sometimes call free with null ptr */
-    free(ptr);
-}
-
-/*
- * SSH State machine related code
- */
-/* This is the ONLY way to change SSH state! */
-static void state(struct connectdata *conn, sshstate nowstate)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
-  /* for debug purposes */
-  static const char * const names[] = {
-    "SSH_STOP",
-    "SSH_INIT",
-    "SSH_S_STARTUP",
-    "SSH_HOSTKEY",
-    "SSH_AUTHLIST",
-    "SSH_AUTH_PKEY_INIT",
-    "SSH_AUTH_PKEY",
-    "SSH_AUTH_PASS_INIT",
-    "SSH_AUTH_PASS",
-    "SSH_AUTH_AGENT_INIT",
-    "SSH_AUTH_AGENT_LIST",
-    "SSH_AUTH_AGENT",
-    "SSH_AUTH_HOST_INIT",
-    "SSH_AUTH_HOST",
-    "SSH_AUTH_KEY_INIT",
-    "SSH_AUTH_KEY",
-    "SSH_AUTH_GSSAPI",
-    "SSH_AUTH_DONE",
-    "SSH_SFTP_INIT",
-    "SSH_SFTP_REALPATH",
-    "SSH_SFTP_QUOTE_INIT",
-    "SSH_SFTP_POSTQUOTE_INIT",
-    "SSH_SFTP_QUOTE",
-    "SSH_SFTP_NEXT_QUOTE",
-    "SSH_SFTP_QUOTE_STAT",
-    "SSH_SFTP_QUOTE_SETSTAT",
-    "SSH_SFTP_QUOTE_SYMLINK",
-    "SSH_SFTP_QUOTE_MKDIR",
-    "SSH_SFTP_QUOTE_RENAME",
-    "SSH_SFTP_QUOTE_RMDIR",
-    "SSH_SFTP_QUOTE_UNLINK",
-    "SSH_SFTP_QUOTE_STATVFS",
-    "SSH_SFTP_GETINFO",
-    "SSH_SFTP_FILETIME",
-    "SSH_SFTP_TRANS_INIT",
-    "SSH_SFTP_UPLOAD_INIT",
-    "SSH_SFTP_CREATE_DIRS_INIT",
-    "SSH_SFTP_CREATE_DIRS",
-    "SSH_SFTP_CREATE_DIRS_MKDIR",
-    "SSH_SFTP_READDIR_INIT",
-    "SSH_SFTP_READDIR",
-    "SSH_SFTP_READDIR_LINK",
-    "SSH_SFTP_READDIR_BOTTOM",
-    "SSH_SFTP_READDIR_DONE",
-    "SSH_SFTP_DOWNLOAD_INIT",
-    "SSH_SFTP_DOWNLOAD_STAT",
-    "SSH_SFTP_CLOSE",
-    "SSH_SFTP_SHUTDOWN",
-    "SSH_SCP_TRANS_INIT",
-    "SSH_SCP_UPLOAD_INIT",
-    "SSH_SCP_DOWNLOAD_INIT",
-    "SSH_SCP_DOWNLOAD",
-    "SSH_SCP_DONE",
-    "SSH_SCP_SEND_EOF",
-    "SSH_SCP_WAIT_EOF",
-    "SSH_SCP_WAIT_CLOSE",
-    "SSH_SCP_CHANNEL_FREE",
-    "SSH_SESSION_DISCONNECT",
-    "SSH_SESSION_FREE",
-    "QUIT"
-  };
-
-  /* a precaution to make sure the lists are in sync */
-  DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
-
-  if(sshc->state != nowstate) {
-    infof(conn->data, "SFTP %p state change from %s to %s\n",
-          (void *)sshc, names[sshc->state], names[nowstate]);
-  }
-#endif
-
-  sshc->state = nowstate;
-}
-
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-static int sshkeycallback(struct Curl_easy *easy,
-                          const struct curl_khkey *knownkey, /* known */
-                          const struct curl_khkey *foundkey, /* found */
-                          enum curl_khmatch match,
-                          void *clientp)
-{
-  (void)easy;
-  (void)knownkey;
-  (void)foundkey;
-  (void)clientp;
-
-  /* we only allow perfect matches, and we reject everything else */
-  return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
-}
-#endif
-
-/*
- * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
- * with 32bit size_t.
- */
-#ifdef HAVE_LIBSSH2_SFTP_SEEK64
-#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
-#else
-#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
-#endif
-
-/*
- * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
- * architectures so we check of the necessary function is present.
- */
-#ifndef HAVE_LIBSSH2_SCP_SEND64
-#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
-#else
-#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
-                                             (libssh2_uint64_t)d, 0, 0)
-#endif
-
-/*
- * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
- */
-#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
-#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
-#endif
-
-static CURLcode ssh_knownhost(struct connectdata *conn)
-{
-  CURLcode result = CURLE_OK;
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-  struct Curl_easy *data = conn->data;
-
-  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-    /* we're asked to verify the host against a file */
-    struct ssh_conn *sshc = &conn->proto.sshc;
-    int rc;
-    int keytype;
-    size_t keylen;
-    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
-                                                    &keylen, &keytype);
-    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
-    int keybit = 0;
-
-    if(remotekey) {
-      /*
-       * A subject to figure out is what host name we need to pass in here.
-       * What host name does OpenSSH store in its file if an IDN name is
-       * used?
-       */
-      struct libssh2_knownhost *host;
-      enum curl_khmatch keymatch;
-      curl_sshkeycallback func =
-        data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
-      struct curl_khkey knownkey;
-      struct curl_khkey *knownkeyp = NULL;
-      struct curl_khkey foundkey;
-
-      keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
-        LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
-
-#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);
-#else
-      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>");
-
-      /* 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 '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;
-
-      /* 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! */
-      rc = CURLKHSTAT_REJECT;
-
-    switch(rc) {
-    default: /* unknown return codes will equal reject */
-      /* FALLTHROUGH */
-    case CURLKHSTAT_REJECT:
-      state(conn, SSH_SESSION_FREE);
-      /* FALLTHROUGH */
-    case CURLKHSTAT_DEFER:
-      /* DEFER means bail out but keep the SSH_HOSTKEY state */
-      result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
-      break;
-    case CURLKHSTAT_FINE:
-    case CURLKHSTAT_FINE_ADD_TO_FILE:
-      /* proceed */
-      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
-        /* the found host+key didn't match but has been told to be fine
-           anyway so we add it in memory */
-        int addrc = libssh2_knownhost_add(sshc->kh,
-                                          conn->host.name, NULL,
-                                          remotekey, keylen,
-                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
-                                          keybit, NULL);
-        if(addrc)
-          infof(data, "Warning adding the known host %s failed!\n",
-                conn->host.name);
-        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
-          /* now we write the entire in-memory list of known hosts to the
-             known_hosts file */
-          int wrc =
-            libssh2_knownhost_writefile(sshc->kh,
-                                        data->set.str[STRING_SSH_KNOWNHOSTS],
-                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
-          if(wrc) {
-            infof(data, "Warning, writing %s failed!\n",
-                  data->set.str[STRING_SSH_KNOWNHOSTS]);
-          }
-        }
-      }
-      break;
-    }
-  }
-#else /* HAVE_LIBSSH2_KNOWNHOST_API */
-  (void)conn;
-#endif
-  return result;
-}
-
-static CURLcode ssh_check_fingerprint(struct connectdata *conn)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  struct Curl_easy *data = conn->data;
-  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
-  char md5buffer[33];
-
-  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
-      LIBSSH2_HOSTKEY_HASH_MD5);
-
-  if(fingerprint) {
-    /* The fingerprint points to static storage (!), don't free() it. */
-    int i;
-    for(i = 0; i < 16; i++)
-      msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
-    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
-  }
-
-  /* Before we authenticate we check the hostkey's MD5 fingerprint
-   * against a known fingerprint, if available.
-   */
-  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
-    if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
-      if(fingerprint)
-        failf(data,
-            "Denied establishing ssh session: mismatch md5 fingerprint. "
-            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
-      else
-        failf(data,
-            "Denied establishing ssh session: md5 fingerprint not available");
-      state(conn, SSH_SESSION_FREE);
-      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
-      return sshc->actualcode;
-    }
-    infof(data, "MD5 checksum match!\n");
-    /* as we already matched, we skip the check for known hosts */
-    return CURLE_OK;
-  }
-  return ssh_knownhost(conn);
-}
-
-/*
- * ssh_statemach_act() runs the SSH state machine as far as it can without
- * blocking and without reaching the end.  The data the pointer 'block' points
- * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
- * meaning it wants to be called again when the socket is ready
- */
-
-static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
-{
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-  struct SSHPROTO *sftp_scp = data->req.protop;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  curl_socket_t sock = conn->sock[FIRSTSOCKET];
-  char *new_readdir_line;
-  int rc = LIBSSH2_ERROR_NONE;
-  int err;
-  int seekerr = CURL_SEEKFUNC_OK;
-  *block = 0; /* we're not blocking by default */
-
-  do {
-
-    switch(sshc->state) {
-    case SSH_INIT:
-      sshc->secondCreateDirs = 0;
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_OK;
-
-      /* Set libssh2 to non-blocking, since everything internally is
-         non-blocking */
-      libssh2_session_set_blocking(sshc->ssh_session, 0);
-
-      state(conn, SSH_S_STARTUP);
-      /* FALLTHROUGH */
-
-    case SSH_S_STARTUP:
-      rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc) {
-        char *err_msg = NULL;
-        (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
-        failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
-
-        state(conn, SSH_SESSION_FREE);
-        sshc->actualcode = CURLE_FAILED_INIT;
-        break;
-      }
-
-      state(conn, SSH_HOSTKEY);
-
-      /* FALLTHROUGH */
-    case SSH_HOSTKEY:
-      /*
-       * Before we authenticate we should check the hostkey's fingerprint
-       * against our known hosts. How that is handled (reading from file,
-       * whatever) is up to us.
-       */
-      result = ssh_check_fingerprint(conn);
-      if(!result)
-        state(conn, SSH_AUTHLIST);
-      /* ssh_check_fingerprint sets state appropriately on error */
-      break;
-
-    case SSH_AUTHLIST:
-      /*
-       * Figure out authentication methods
-       * NB: As soon as we have provided a username to an openssh server we
-       * must never change it later. Thus, always specify the correct username
-       * here, even though the libssh2 docs kind of indicate that it should be
-       * possible to get a 'generic' list (not user-specific) of authentication
-       * methods, presumably with a blank username. That won't work in my
-       * experience.
-       * So always specify it here.
-       */
-      sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
-                                             conn->user,
-                                             curlx_uztoui(strlen(conn->user)));
-
-      if(!sshc->authlist) {
-        if(libssh2_userauth_authenticated(sshc->ssh_session)) {
-          sshc->authed = TRUE;
-          infof(data, "SSH user accepted with no authentication\n");
-          state(conn, SSH_AUTH_DONE);
-          break;
-        }
-        err = libssh2_session_last_errno(sshc->ssh_session);
-        if(err == LIBSSH2_ERROR_EAGAIN)
-          rc = LIBSSH2_ERROR_EAGAIN;
-        else {
-          state(conn, SSH_SESSION_FREE);
-          sshc->actualcode = libssh2_session_error_to_CURLE(err);
-        }
-        break;
-      }
-      infof(data, "SSH authentication methods available: %s\n",
-            sshc->authlist);
-
-      state(conn, SSH_AUTH_PKEY_INIT);
-      break;
-
-    case SSH_AUTH_PKEY_INIT:
-      /*
-       * Check the supported auth types in the order I feel is most secure
-       * with the requested type of authentication
-       */
-      sshc->authed = FALSE;
-
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
-         (strstr(sshc->authlist, "publickey") != NULL)) {
-        bool out_of_memory = FALSE;
-
-        sshc->rsa_pub = sshc->rsa = NULL;
-
-        if(data->set.str[STRING_SSH_PRIVATE_KEY])
-          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
-        else {
-          /* To ponder about: should really the lib be messing about with the
-             HOME environment variable etc? */
-          char *home = curl_getenv("HOME");
-
-          /* If no private key file is specified, try some common paths. */
-          if(home) {
-            /* Try ~/.ssh first. */
-            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
-            if(!sshc->rsa)
-              out_of_memory = TRUE;
-            else if(access(sshc->rsa, R_OK) != 0) {
-              Curl_safefree(sshc->rsa);
-              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
-              if(!sshc->rsa)
-                out_of_memory = TRUE;
-              else if(access(sshc->rsa, R_OK) != 0) {
-                Curl_safefree(sshc->rsa);
-              }
-            }
-            free(home);
-          }
-          if(!out_of_memory && !sshc->rsa) {
-            /* Nothing found; try the current dir. */
-            sshc->rsa = strdup("id_rsa");
-            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
-              Curl_safefree(sshc->rsa);
-              sshc->rsa = strdup("id_dsa");
-              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
-                Curl_safefree(sshc->rsa);
-                /* Out of guesses. Set to the empty string to avoid
-                 * surprising info messages. */
-                sshc->rsa = strdup("");
-              }
-            }
-          }
-        }
-
-        /*
-         * Unless the user explicitly specifies a public key file, let
-         * libssh2 extract the public key from the private key file.
-         * This is done by simply passing sshc->rsa_pub = NULL.
-         */
-        if(data->set.str[STRING_SSH_PUBLIC_KEY]
-           /* treat empty string the same way as NULL */
-           && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
-          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
-          if(!sshc->rsa_pub)
-            out_of_memory = TRUE;
-        }
-
-        if(out_of_memory || sshc->rsa == NULL) {
-          Curl_safefree(sshc->rsa);
-          Curl_safefree(sshc->rsa_pub);
-          state(conn, SSH_SESSION_FREE);
-          sshc->actualcode = CURLE_OUT_OF_MEMORY;
-          break;
-        }
-
-        sshc->passphrase = data->set.ssl.key_passwd;
-        if(!sshc->passphrase)
-          sshc->passphrase = "";
-
-        if(sshc->rsa_pub)
-          infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
-        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
-
-        state(conn, SSH_AUTH_PKEY);
-      }
-      else {
-        state(conn, SSH_AUTH_PASS_INIT);
-      }
-      break;
-
-    case SSH_AUTH_PKEY:
-      /* The function below checks if the files exists, no need to stat() here.
-       */
-      rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
-                                                  conn->user,
-                                                  curlx_uztoui(
-                                                    strlen(conn->user)),
-                                                  sshc->rsa_pub,
-                                                  sshc->rsa, sshc->passphrase);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-
-      Curl_safefree(sshc->rsa_pub);
-      Curl_safefree(sshc->rsa);
-
-      if(rc == 0) {
-        sshc->authed = TRUE;
-        infof(data, "Initialized SSH public key authentication\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        char *err_msg = NULL;
-        (void)libssh2_session_last_error(sshc->ssh_session,
-                                         &err_msg, NULL, 0);
-        infof(data, "SSH public key authentication failed: %s\n", err_msg);
-        state(conn, SSH_AUTH_PASS_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      break;
-
-    case SSH_AUTH_PASS_INIT:
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
-         (strstr(sshc->authlist, "password") != NULL)) {
-        state(conn, SSH_AUTH_PASS);
-      }
-      else {
-        state(conn, SSH_AUTH_HOST_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      break;
-
-    case SSH_AUTH_PASS:
-      rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
-                                        curlx_uztoui(strlen(conn->user)),
-                                        conn->passwd,
-                                        curlx_uztoui(strlen(conn->passwd)),
-                                        NULL);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc == 0) {
-        sshc->authed = TRUE;
-        infof(data, "Initialized password authentication\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        state(conn, SSH_AUTH_HOST_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      break;
-
-    case SSH_AUTH_HOST_INIT:
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
-         (strstr(sshc->authlist, "hostbased") != NULL)) {
-        state(conn, SSH_AUTH_HOST);
-      }
-      else {
-        state(conn, SSH_AUTH_AGENT_INIT);
-      }
-      break;
-
-    case SSH_AUTH_HOST:
-      state(conn, SSH_AUTH_AGENT_INIT);
-      break;
-
-    case SSH_AUTH_AGENT_INIT:
-#ifdef HAVE_LIBSSH2_AGENT_API
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
-         && (strstr(sshc->authlist, "publickey") != NULL)) {
-
-        /* Connect to the ssh-agent */
-        /* The agent could be shared by a curl thread i believe
-           but nothing obvious as keys can be added/removed at any time */
-        if(!sshc->ssh_agent) {
-          sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
-          if(!sshc->ssh_agent) {
-            infof(data, "Could not create agent object\n");
-
-            state(conn, SSH_AUTH_KEY_INIT);
-            break;
-          }
-        }
-
-        rc = libssh2_agent_connect(sshc->ssh_agent);
-        if(rc == LIBSSH2_ERROR_EAGAIN)
-          break;
-        if(rc < 0) {
-          infof(data, "Failure connecting to agent\n");
-          state(conn, SSH_AUTH_KEY_INIT);
-          rc = 0; /* clear rc and continue */
-        }
-        else {
-          state(conn, SSH_AUTH_AGENT_LIST);
-        }
-      }
-      else
-#endif /* HAVE_LIBSSH2_AGENT_API */
-        state(conn, SSH_AUTH_KEY_INIT);
-      break;
-
-    case SSH_AUTH_AGENT_LIST:
-#ifdef HAVE_LIBSSH2_AGENT_API
-      rc = libssh2_agent_list_identities(sshc->ssh_agent);
-
-      if(rc == LIBSSH2_ERROR_EAGAIN)
-        break;
-      if(rc < 0) {
-        infof(data, "Failure requesting identities to agent\n");
-        state(conn, SSH_AUTH_KEY_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      else {
-        state(conn, SSH_AUTH_AGENT);
-        sshc->sshagent_prev_identity = NULL;
-      }
-#endif
-      break;
-
-    case SSH_AUTH_AGENT:
-#ifdef HAVE_LIBSSH2_AGENT_API
-      /* as prev_identity evolves only after an identity user auth finished we
-         can safely request it again as long as EAGAIN is returned here or by
-         libssh2_agent_userauth */
-      rc = libssh2_agent_get_identity(sshc->ssh_agent,
-                                      &sshc->sshagent_identity,
-                                      sshc->sshagent_prev_identity);
-      if(rc == LIBSSH2_ERROR_EAGAIN)
-        break;
-
-      if(rc == 0) {
-        rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
-                                    sshc->sshagent_identity);
-
-        if(rc < 0) {
-          if(rc != LIBSSH2_ERROR_EAGAIN) {
-            /* tried and failed? go to next identity */
-            sshc->sshagent_prev_identity = sshc->sshagent_identity;
-          }
-          break;
-        }
-      }
-
-      if(rc < 0)
-        infof(data, "Failure requesting identities to agent\n");
-      else if(rc == 1)
-        infof(data, "No identity would match\n");
-
-      if(rc == LIBSSH2_ERROR_NONE) {
-        sshc->authed = TRUE;
-        infof(data, "Agent based authentication successful\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        state(conn, SSH_AUTH_KEY_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-#endif
-      break;
-
-    case SSH_AUTH_KEY_INIT:
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
-         && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
-        state(conn, SSH_AUTH_KEY);
-      }
-      else {
-        state(conn, SSH_AUTH_DONE);
-      }
-      break;
-
-    case SSH_AUTH_KEY:
-      /* Authentication failed. Continue with keyboard-interactive now. */
-      rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
-                                                    conn->user,
-                                                    curlx_uztoui(
-                                                      strlen(conn->user)),
-                                                    &kbd_callback);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc == 0) {
-        sshc->authed = TRUE;
-        infof(data, "Initialized keyboard interactive authentication\n");
-      }
-      state(conn, SSH_AUTH_DONE);
-      break;
-
-    case SSH_AUTH_DONE:
-      if(!sshc->authed) {
-        failf(data, "Authentication failure");
-        state(conn, SSH_SESSION_FREE);
-        sshc->actualcode = CURLE_LOGIN_DENIED;
-        break;
-      }
-
-      /*
-       * At this point we have an authenticated ssh session.
-       */
-      infof(data, "Authentication complete\n");
-
-      Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
-
-      conn->sockfd = sock;
-      conn->writesockfd = CURL_SOCKET_BAD;
-
-      if(conn->handler->protocol == CURLPROTO_SFTP) {
-        state(conn, SSH_SFTP_INIT);
-        break;
-      }
-      infof(data, "SSH CONNECT phase done\n");
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_INIT:
-      /*
-       * Start the libssh2 sftp session
-       */
-      sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
-      if(!sshc->sftp_session) {
-        char *err_msg = NULL;
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-
-        (void)libssh2_session_last_error(sshc->ssh_session,
-                                         &err_msg, NULL, 0);
-        failf(data, "Failure initializing sftp session: %s", err_msg);
-        state(conn, SSH_SESSION_FREE);
-        sshc->actualcode = CURLE_FAILED_INIT;
-        break;
-      }
-      state(conn, SSH_SFTP_REALPATH);
-      break;
-
-    case SSH_SFTP_REALPATH:
-    {
-      char tempHome[PATH_MAX];
-
-      /*
-       * Get the "home" directory
-       */
-      rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
-                                 tempHome, PATH_MAX-1);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc > 0) {
-        /* It seems that this string is not always NULL terminated */
-        tempHome[rc] = '\0';
-        sshc->homedir = strdup(tempHome);
-        if(!sshc->homedir) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->actualcode = CURLE_OUT_OF_MEMORY;
-          break;
-        }
-        conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
-      }
-      else {
-        /* Return the error type */
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        if(err)
-          result = sftp_libssh2_error_to_CURLE(err);
-        else
-          /* in this case, the error wasn't in the SFTP level but for example
-             a time-out or similar */
-          result = CURLE_SSH;
-        sshc->actualcode = result;
-        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
-                     err, (int)result));
-        state(conn, SSH_STOP);
-        break;
-      }
-    }
-    /* This is the last step in the SFTP connect phase. Do note that while
-       we get the homedir here, we get the "workingpath" in the DO action
-       since the homedir will remain the same between request but the
-       working path will not. */
-    DEBUGF(infof(data, "SSH CONNECT phase done\n"));
-    state(conn, SSH_STOP);
-    break;
-
-    case SSH_SFTP_QUOTE_INIT:
-
-      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      if(data->set.quote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.quote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_SFTP_GETINFO);
-      }
-      break;
-
-    case SSH_SFTP_POSTQUOTE_INIT:
-      if(data->set.postquote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.postquote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_STOP);
-      }
-      break;
-
-    case SSH_SFTP_QUOTE:
-      /* Send any quote commands */
-    {
-      const char *cp;
-
-      /*
-       * Support some of the "FTP" commands
-       *
-       * 'sshc->quote_item' is already verified to be non-NULL before it
-       * switched to this state.
-       */
-      char *cmd = sshc->quote_item->data;
-      sshc->acceptfail = FALSE;
-
-      /* if a command starts with an asterisk, which a legal SFTP command never
-         can, the command will be allowed to fail without it causing any
-         aborts or cancels etc. It will cause libcurl to act as if the command
-         is successful, whatever the server reponds. */
-
-      if(cmd[0] == '*') {
-        cmd++;
-        sshc->acceptfail = TRUE;
-      }
-
-      if(strcasecompare("pwd", cmd)) {
-        /* output debug output if that is requested */
-        char *tmp = aprintf("257 \"%s\" is current directory.\n",
-                            sftp_scp->path);
-        if(!tmp) {
-          result = CURLE_OUT_OF_MEMORY;
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          break;
-        }
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
-          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
-        }
-        /* this sends an FTP-like "header" to the header callback so that the
-           current directory can be read very similar to how it is read when
-           using ordinary FTP. */
-        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-        free(tmp);
-        if(result) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-        }
-        else
-          state(conn, SSH_SFTP_NEXT_QUOTE);
-        break;
-      }
-      {
-        /*
-         * the arguments following the command must be separated from the
-         * command with a space so we can check for it unconditionally
-         */
-        cp = strchr(cmd, ' ');
-        if(cp == NULL) {
-          failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-
-        /*
-         * also, every command takes at least one argument so we get that
-         * first argument right now
-         */
-        result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
-        if(result) {
-          if(result == CURLE_OUT_OF_MEMORY)
-            failf(data, "Out of memory");
-          else
-            failf(data, "Syntax error: Bad first parameter");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-          break;
-        }
-
-        /*
-         * SFTP is a binary protocol, so we don't send text commands
-         * to the server. Instead, we scan for commands used by
-         * OpenSSH's sftp program and call the appropriate libssh2
-         * functions.
-         */
-        if(strncasecompare(cmd, "chgrp ", 6) ||
-           strncasecompare(cmd, "chmod ", 6) ||
-           strncasecompare(cmd, "chown ", 6) ) {
-          /* attribute change */
-
-          /* sshc->quote_path1 contains the mode to set */
-          /* get the destination */
-          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-          if(result) {
-            if(result == CURLE_OUT_OF_MEMORY)
-              failf(data, "Out of memory");
-            else
-              failf(data, "Syntax error in chgrp/chmod/chown: "
-                    "Bad second parameter");
-            Curl_safefree(sshc->quote_path1);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->nextstate = SSH_NO_STATE;
-            sshc->actualcode = result;
-            break;
-          }
-          memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-          state(conn, SSH_SFTP_QUOTE_STAT);
-          break;
-        }
-        if(strncasecompare(cmd, "ln ", 3) ||
-           strncasecompare(cmd, "symlink ", 8)) {
-          /* symbolic linking */
-          /* sshc->quote_path1 is the source */
-          /* get the destination */
-          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-          if(result) {
-            if(result == CURLE_OUT_OF_MEMORY)
-              failf(data, "Out of memory");
-            else
-              failf(data,
-                    "Syntax error in ln/symlink: Bad second parameter");
-            Curl_safefree(sshc->quote_path1);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->nextstate = SSH_NO_STATE;
-            sshc->actualcode = result;
-            break;
-          }
-          state(conn, SSH_SFTP_QUOTE_SYMLINK);
-          break;
-        }
-        else if(strncasecompare(cmd, "mkdir ", 6)) {
-          /* create dir */
-          state(conn, SSH_SFTP_QUOTE_MKDIR);
-          break;
-        }
-        else if(strncasecompare(cmd, "rename ", 7)) {
-          /* rename file */
-          /* first param is the source path */
-          /* second param is the dest. path */
-          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-          if(result) {
-            if(result == CURLE_OUT_OF_MEMORY)
-              failf(data, "Out of memory");
-            else
-              failf(data, "Syntax error in rename: Bad second parameter");
-            Curl_safefree(sshc->quote_path1);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->nextstate = SSH_NO_STATE;
-            sshc->actualcode = result;
-            break;
-          }
-          state(conn, SSH_SFTP_QUOTE_RENAME);
-          break;
-        }
-        else if(strncasecompare(cmd, "rmdir ", 6)) {
-          /* delete dir */
-          state(conn, SSH_SFTP_QUOTE_RMDIR);
-          break;
-        }
-        else if(strncasecompare(cmd, "rm ", 3)) {
-          state(conn, SSH_SFTP_QUOTE_UNLINK);
-          break;
-        }
-#ifdef HAS_STATVFS_SUPPORT
-        else if(strncasecompare(cmd, "statvfs ", 8)) {
-          state(conn, SSH_SFTP_QUOTE_STATVFS);
-          break;
-        }
-#endif
-
-        failf(data, "Unknown SFTP command");
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-    }
-    break;
-
-    case SSH_SFTP_NEXT_QUOTE:
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-
-      sshc->quote_item = sshc->quote_item->next;
-
-      if(sshc->quote_item) {
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        if(sshc->nextstate != SSH_NO_STATE) {
-          state(conn, sshc->nextstate);
-          sshc->nextstate = SSH_NO_STATE;
-        }
-        else {
-          state(conn, SSH_SFTP_GETINFO);
-        }
-      }
-      break;
-
-    case SSH_SFTP_QUOTE_STAT:
-    {
-      char *cmd = sshc->quote_item->data;
-      sshc->acceptfail = FALSE;
-
-      /* if a command starts with an asterisk, which a legal SFTP command never
-         can, the command will be allowed to fail without it causing any
-         aborts or cancels etc. It will cause libcurl to act as if the command
-         is successful, whatever the server reponds. */
-
-      if(cmd[0] == '*') {
-        cmd++;
-        sshc->acceptfail = TRUE;
-      }
-
-      if(!strncasecompare(cmd, "chmod", 5)) {
-        /* Since chown and chgrp only set owner OR group but libssh2 wants to
-         * set them both at once, we need to obtain the current ownership
-         * first.  This takes an extra protocol round trip.
-         */
-        rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
-                                  curlx_uztoui(strlen(sshc->quote_path2)),
-                                  LIBSSH2_SFTP_STAT,
-                                  &sshc->quote_attrs);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
-          err = sftp_libssh2_last_error(sshc->sftp_session);
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Attempt to get SFTP stats failed: %s",
-                sftp_libssh2_strerror(err));
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-
-      /* Now set the new attributes... */
-      if(strncasecompare(cmd, "chgrp", 5)) {
-        sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
-        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
-        if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-           !sshc->acceptfail) {
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Syntax error: chgrp gid not a number");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-      else if(strncasecompare(cmd, "chmod", 5)) {
-        sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
-        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
-        /* permissions are octal */
-        if(sshc->quote_attrs.permissions == 0 &&
-           !ISDIGIT(sshc->quote_path1[0])) {
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Syntax error: chmod permissions not a number");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-      else if(strncasecompare(cmd, "chown", 5)) {
-        sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
-        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
-        if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-           !sshc->acceptfail) {
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Syntax error: chown uid not a number");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-
-      /* Now send the completed structure... */
-      state(conn, SSH_SFTP_QUOTE_SETSTAT);
-      break;
-    }
-
-    case SSH_SFTP_QUOTE_SETSTAT:
-      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
-                                curlx_uztoui(strlen(sshc->quote_path2)),
-                                LIBSSH2_SFTP_SETSTAT,
-                                &sshc->quote_attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "Attempt to set SFTP stats failed: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_SYMLINK:
-      rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
-                                   curlx_uztoui(strlen(sshc->quote_path1)),
-                                   sshc->quote_path2,
-                                   curlx_uztoui(strlen(sshc->quote_path2)),
-                                   LIBSSH2_SFTP_SYMLINK);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "symlink command failed: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_MKDIR:
-      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
-                                 curlx_uztoui(strlen(sshc->quote_path1)),
-                                 data->set.new_directory_perms);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RENAME:
-      rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
-                                  curlx_uztoui(strlen(sshc->quote_path1)),
-                                  sshc->quote_path2,
-                                  curlx_uztoui(strlen(sshc->quote_path2)),
-                                  LIBSSH2_SFTP_RENAME_OVERWRITE |
-                                  LIBSSH2_SFTP_RENAME_ATOMIC |
-                                  LIBSSH2_SFTP_RENAME_NATIVE);
-
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RMDIR:
-      rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
-                                 curlx_uztoui(strlen(sshc->quote_path1)));
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_UNLINK:
-      rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
-                                  curlx_uztoui(strlen(sshc->quote_path1)));
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-#ifdef HAS_STATVFS_SUPPORT
-    case SSH_SFTP_QUOTE_STATVFS:
-    {
-      LIBSSH2_SFTP_STATVFS statvfs;
-      rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
-                                curlx_uztoui(strlen(sshc->quote_path1)),
-                                &statvfs);
-
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      else if(rc == 0) {
-        char *tmp = aprintf("statvfs:\n"
-                            "f_bsize: %llu\n" "f_frsize: %llu\n"
-                            "f_blocks: %llu\n" "f_bfree: %llu\n"
-                            "f_bavail: %llu\n" "f_files: %llu\n"
-                            "f_ffree: %llu\n" "f_favail: %llu\n"
-                            "f_fsid: %llu\n" "f_flag: %llu\n"
-                            "f_namemax: %llu\n",
-                            statvfs.f_bsize, statvfs.f_frsize,
-                            statvfs.f_blocks, statvfs.f_bfree,
-                            statvfs.f_bavail, statvfs.f_files,
-                            statvfs.f_ffree, statvfs.f_favail,
-                            statvfs.f_fsid, statvfs.f_flag,
-                            statvfs.f_namemax);
-        if(!tmp) {
-          result = CURLE_OUT_OF_MEMORY;
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          break;
-        }
-
-        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-        free(tmp);
-        if(result) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-        }
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-    }
-#endif
-    case SSH_SFTP_GETINFO:
-    {
-      if(data->set.get_filetime) {
-        state(conn, SSH_SFTP_FILETIME);
-      }
-      else {
-        state(conn, SSH_SFTP_TRANS_INIT);
-      }
-      break;
-    }
-
-    case SSH_SFTP_FILETIME:
-    {
-      LIBSSH2_SFTP_ATTRIBUTES attrs;
-
-      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
-                                curlx_uztoui(strlen(sftp_scp->path)),
-                                LIBSSH2_SFTP_STAT, &attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc == 0) {
-        data->info.filetime = attrs.mtime;
-      }
-
-      state(conn, SSH_SFTP_TRANS_INIT);
-      break;
-    }
-
-    case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      else {
-        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
-          state(conn, SSH_SFTP_READDIR_INIT);
-        else
-          state(conn, SSH_SFTP_DOWNLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_UPLOAD_INIT:
-    {
-      unsigned long flags;
-      /*
-       * NOTE!!!  libssh2 requires that the destination path is a full path
-       *          that includes the destination file and name OR ends in a "/"
-       *          If this is not done the destination file will be named the
-       *          same name as the last directory in the path.
-       */
-
-      if(data->state.resume_from != 0) {
-        LIBSSH2_SFTP_ATTRIBUTES attrs;
-        if(data->state.resume_from < 0) {
-          rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
-                                    curlx_uztoui(strlen(sftp_scp->path)),
-                                    LIBSSH2_SFTP_STAT, &attrs);
-          if(rc == LIBSSH2_ERROR_EAGAIN) {
-            break;
-          }
-          if(rc) {
-            data->state.resume_from = 0;
-          }
-          else {
-            curl_off_t size = attrs.filesize;
-            if(size < 0) {
-              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-              return CURLE_BAD_DOWNLOAD_RESUME;
-            }
-            data->state.resume_from = attrs.filesize;
-          }
-        }
-      }
-
-      if(data->set.ftp_append)
-        /* Try to open for append, but create if nonexisting */
-        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
-      else if(data->state.resume_from > 0)
-        /* If we have restart position then open for append */
-        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
-      else
-        /* Clear file before writing (normal behaviour) */
-        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
-
-      sshc->sftp_handle =
-        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
-                             curlx_uztoui(strlen(sftp_scp->path)),
-                             flags, data->set.new_file_perms,
-                             LIBSSH2_SFTP_OPENFILE);
-
-      if(!sshc->sftp_handle) {
-        rc = libssh2_session_last_errno(sshc->ssh_session);
-
-        if(LIBSSH2_ERROR_EAGAIN == rc)
-          break;
-
-        if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
-          /* only when there was an SFTP protocol error can we extract
-             the sftp error! */
-          err = sftp_libssh2_last_error(sshc->sftp_session);
-        else
-          err = -1; /* not an sftp error at all */
-
-        if(sshc->secondCreateDirs) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->actualcode = err>= LIBSSH2_FX_OK?
-            sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
-          failf(data, "Creating the dir/file failed: %s",
-                sftp_libssh2_strerror(err));
-          break;
-        }
-        if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
-            (err == LIBSSH2_FX_FAILURE) ||
-            (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
-           (data->set.ftp_create_missing_dirs &&
-            (strlen(sftp_scp->path) > 1))) {
-          /* try to create the path remotely */
-          rc = 0; /* clear rc and continue */
-          sshc->secondCreateDirs = 1;
-          state(conn, SSH_SFTP_CREATE_DIRS_INIT);
-          break;
-        }
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = err>= LIBSSH2_FX_OK?
-          sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
-        if(!sshc->actualcode) {
-          /* Sometimes, for some reason libssh2_sftp_last_error() returns
-             zero even though libssh2_sftp_open() failed previously! We need
-             to work around that! */
-          sshc->actualcode = CURLE_SSH;
-          err = -1;
-        }
-        failf(data, "Upload failed: %s (%d/%d)",
-              err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
-              err, rc);
-        break;
-      }
-
-      /* If we have a restart point then we need to seek to the correct
-         position. */
-      if(data->state.resume_from > 0) {
-        /* Let's read off the proper amount of bytes from the input. */
-        if(conn->seek_func) {
-          Curl_set_in_callback(data, true);
-          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
-                                    SEEK_SET);
-          Curl_set_in_callback(data, false);
-        }
-
-        if(seekerr != CURL_SEEKFUNC_OK) {
-          curl_off_t passed = 0;
-
-          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
-            failf(data, "Could not seek stream");
-            return CURLE_FTP_COULDNT_USE_REST;
-          }
-          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-          do {
-            size_t readthisamountnow =
-              (data->state.resume_from - passed > data->set.buffer_size) ?
-              (size_t)data->set.buffer_size :
-              curlx_sotouz(data->state.resume_from - passed);
-
-            size_t actuallyread;
-            Curl_set_in_callback(data, true);
-            actuallyread = data->state.fread_func(data->state.buffer, 1,
-                                                  readthisamountnow,
-                                                  data->state.in);
-            Curl_set_in_callback(data, false);
-
-            passed += actuallyread;
-            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-              /* this checks for greater-than only to make sure that the
-                 CURL_READFUNC_ABORT return code still aborts */
-              failf(data, "Failed to read data");
-              return CURLE_FTP_COULDNT_USE_REST;
-            }
-          } while(passed < data->state.resume_from);
-        }
-
-        /* now, decrease the size of the read */
-        if(data->state.infilesize > 0) {
-          data->state.infilesize -= data->state.resume_from;
-          data->req.size = data->state.infilesize;
-          Curl_pgrsSetUploadSize(data, data->state.infilesize);
-        }
-
-        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
-      }
-      if(data->state.infilesize > 0) {
-        data->req.size = data->state.infilesize;
-        Curl_pgrsSetUploadSize(data, data->state.infilesize);
-      }
-      /* upload data */
-      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      if(result) {
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = result;
-      }
-      else {
-        /* store this original bitmask setup to use later on if we can't
-           figure out a "real" bitmask */
-        sshc->orig_waitfor = data->req.keepon;
-
-        /* we want to use the _sending_ function even when the socket turns
-           out readable as the underlying libssh2 sftp send function will deal
-           with both accordingly */
-        conn->cselect_bits = CURL_CSELECT_OUT;
-
-        /* since we don't really wait for anything at this point, we want the
-           state machine to move on as soon as possible so we set a very short
-           timeout here */
-        Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
-        state(conn, SSH_STOP);
-      }
-      break;
-    }
-
-    case SSH_SFTP_CREATE_DIRS_INIT:
-      if(strlen(sftp_scp->path) > 1) {
-        sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
-        state(conn, SSH_SFTP_CREATE_DIRS);
-      }
-      else {
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_CREATE_DIRS:
-      sshc->slash_pos = strchr(sshc->slash_pos, '/');
-      if(sshc->slash_pos) {
-        *sshc->slash_pos = 0;
-
-        infof(data, "Creating directory '%s'\n", sftp_scp->path);
-        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
-        break;
-      }
-      state(conn, SSH_SFTP_UPLOAD_INIT);
-      break;
-
-    case SSH_SFTP_CREATE_DIRS_MKDIR:
-      /* 'mode' - parameter is preliminary - default to 0644 */
-      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
-                                 curlx_uztoui(strlen(sftp_scp->path)),
-                                 data->set.new_directory_perms);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      *sshc->slash_pos = '/';
-      ++sshc->slash_pos;
-      if(rc < 0) {
-        /*
-         * Abort if failure wasn't that the dir already exists or the
-         * permission was denied (creation might succeed further down the
-         * path) - retry on unspecific FAILURE also
-         */
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
-           (err != LIBSSH2_FX_FAILURE) &&
-           (err != LIBSSH2_FX_PERMISSION_DENIED)) {
-          result = sftp_libssh2_error_to_CURLE(err);
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->actualcode = result?result:CURLE_SSH;
-          break;
-        }
-        rc = 0; /* clear rc and continue */
-      }
-      state(conn, SSH_SFTP_CREATE_DIRS);
-      break;
-
-    case SSH_SFTP_READDIR_INIT:
-      Curl_pgrsSetDownloadSize(data, -1);
-      if(data->set.opt_no_body) {
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      /*
-       * This is a directory that we are trying to get, so produce a directory
-       * listing
-       */
-      sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
-                                               sftp_scp->path,
-                                               curlx_uztoui(
-                                                 strlen(sftp_scp->path)),
-                                               0, 0, LIBSSH2_SFTP_OPENDIR);
-      if(!sshc->sftp_handle) {
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        failf(data, "Could not open directory for reading: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        result = sftp_libssh2_error_to_CURLE(err);
-        sshc->actualcode = result?result:CURLE_SSH;
-        break;
-      }
-      sshc->readdir_filename = malloc(PATH_MAX + 1);
-      if(!sshc->readdir_filename) {
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      sshc->readdir_longentry = malloc(PATH_MAX + 1);
-      if(!sshc->readdir_longentry) {
-        Curl_safefree(sshc->readdir_filename);
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR:
-      rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
-                                   sshc->readdir_filename,
-                                   PATH_MAX,
-                                   sshc->readdir_longentry,
-                                   PATH_MAX,
-                                   &sshc->readdir_attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc > 0) {
-        sshc->readdir_len = (size_t) rc;
-        sshc->readdir_filename[sshc->readdir_len] = '\0';
-
-        if(data->set.ftp_list_only) {
-          char *tmpLine;
-
-          tmpLine = aprintf("%s\n", sshc->readdir_filename);
-          if(tmpLine == NULL) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-          result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                     tmpLine, sshc->readdir_len + 1);
-          free(tmpLine);
-
-          if(result) {
-            state(conn, SSH_STOP);
-            break;
-          }
-          /* since this counts what we send to the client, we include the
-             newline in this counter */
-          data->req.bytecount += sshc->readdir_len + 1;
-
-          /* output debug output if that is requested */
-          if(data->set.verbose) {
-            Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
-                       sshc->readdir_len);
-          }
-        }
-        else {
-          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
-          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
-          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
-          if(!sshc->readdir_line) {
-            Curl_safefree(sshc->readdir_filename);
-            Curl_safefree(sshc->readdir_longentry);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-
-          memcpy(sshc->readdir_line, sshc->readdir_longentry,
-                 sshc->readdir_currLen);
-          if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
-             ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
-              LIBSSH2_SFTP_S_IFLNK)) {
-            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
-            if(sshc->readdir_linkPath == NULL) {
-              Curl_safefree(sshc->readdir_filename);
-              Curl_safefree(sshc->readdir_longentry);
-              state(conn, SSH_SFTP_CLOSE);
-              sshc->actualcode = CURLE_OUT_OF_MEMORY;
-              break;
-            }
-
-            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
-                      sshc->readdir_filename);
-            state(conn, SSH_SFTP_READDIR_LINK);
-            break;
-          }
-          state(conn, SSH_SFTP_READDIR_BOTTOM);
-          break;
-        }
-      }
-      else if(rc == 0) {
-        Curl_safefree(sshc->readdir_filename);
-        Curl_safefree(sshc->readdir_longentry);
-        state(conn, SSH_SFTP_READDIR_DONE);
-        break;
-      }
-      else if(rc < 0) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        result = sftp_libssh2_error_to_CURLE(err);
-        sshc->actualcode = result?result:CURLE_SSH;
-        failf(data, "Could not open remote file for reading: %s :: %d",
-              sftp_libssh2_strerror(err),
-              libssh2_session_last_errno(sshc->ssh_session));
-        Curl_safefree(sshc->readdir_filename);
-        Curl_safefree(sshc->readdir_longentry);
-        state(conn, SSH_SFTP_CLOSE);
-        break;
-      }
-      break;
-
-    case SSH_SFTP_READDIR_LINK:
-      rc =
-        libssh2_sftp_symlink_ex(sshc->sftp_session,
-                                sshc->readdir_linkPath,
-                                curlx_uztoui(strlen(sshc->readdir_linkPath)),
-                                sshc->readdir_filename,
-                                PATH_MAX, LIBSSH2_SFTP_READLINK);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      sshc->readdir_len = (size_t) rc;
-      Curl_safefree(sshc->readdir_linkPath);
-
-      /* get room for the filename and extra output */
-      sshc->readdir_totalLen += 4 + sshc->readdir_len;
-      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
-                                          sshc->readdir_totalLen);
-      if(!new_readdir_line) {
-        sshc->readdir_line = NULL;
-        Curl_safefree(sshc->readdir_filename);
-        Curl_safefree(sshc->readdir_longentry);
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      sshc->readdir_line = new_readdir_line;
-
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen,
-                                         " -> %s",
-                                         sshc->readdir_filename);
-
-      state(conn, SSH_SFTP_READDIR_BOTTOM);
-      break;
-
-    case SSH_SFTP_READDIR_BOTTOM:
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen, "\n");
-      result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                 sshc->readdir_line,
-                                 sshc->readdir_currLen);
-
-      if(!result) {
-
-        /* output debug output if that is requested */
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen);
-        }
-        data->req.bytecount += sshc->readdir_currLen;
-      }
-      Curl_safefree(sshc->readdir_line);
-      if(result) {
-        state(conn, SSH_STOP);
-      }
-      else
-        state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR_DONE:
-      if(libssh2_sftp_closedir(sshc->sftp_handle) ==
-         LIBSSH2_ERROR_EAGAIN) {
-        rc = LIBSSH2_ERROR_EAGAIN;
-        break;
-      }
-      sshc->sftp_handle = NULL;
-      Curl_safefree(sshc->readdir_filename);
-      Curl_safefree(sshc->readdir_longentry);
-
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_INIT:
-      /*
-       * Work on getting the specified file
-       */
-      sshc->sftp_handle =
-        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
-                             curlx_uztoui(strlen(sftp_scp->path)),
-                             LIBSSH2_FXF_READ, data->set.new_file_perms,
-                             LIBSSH2_SFTP_OPENFILE);
-      if(!sshc->sftp_handle) {
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        failf(data, "Could not open remote file for reading: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        result = sftp_libssh2_error_to_CURLE(err);
-        sshc->actualcode = result?result:CURLE_SSH;
-        break;
-      }
-      state(conn, SSH_SFTP_DOWNLOAD_STAT);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_STAT:
-    {
-      LIBSSH2_SFTP_ATTRIBUTES attrs;
-
-      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
-                                curlx_uztoui(strlen(sftp_scp->path)),
-                                LIBSSH2_SFTP_STAT, &attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc ||
-         !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
-         (attrs.filesize == 0)) {
-        /*
-         * libssh2_sftp_open() didn't return an error, so maybe the server
-         * just doesn't support stat()
-         * OR the server doesn't return a file size with a stat()
-         * OR file size is 0
-         */
-        data->req.size = -1;
-        data->req.maxdownload = -1;
-        Curl_pgrsSetDownloadSize(data, -1);
-      }
-      else {
-        curl_off_t size = attrs.filesize;
-
-        if(size < 0) {
-          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-          return CURLE_BAD_DOWNLOAD_RESUME;
-        }
-        if(conn->data->state.use_range) {
-          curl_off_t from, to;
-          char *ptr;
-          char *ptr2;
-          CURLofft to_t;
-          CURLofft from_t;
-
-          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
-          if(from_t == CURL_OFFT_FLOW)
-            return CURLE_RANGE_ERROR;
-          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
-            ptr++;
-          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
-          if(to_t == CURL_OFFT_FLOW)
-            return CURLE_RANGE_ERROR;
-          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
-             || (to >= size)) {
-            to = size - 1;
-          }
-          if(from_t) {
-            /* from is relative to end of file */
-            from = size - to;
-            to = size - 1;
-          }
-          if(from > size) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          if(from > to) {
-            from = to;
-            size = 0;
-          }
-          else {
-            size = to - from + 1;
-          }
-
-          SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
-        }
-        data->req.size = size;
-        data->req.maxdownload = size;
-        Curl_pgrsSetDownloadSize(data, size);
-      }
-
-      /* We can resume if we can seek to the resume position */
-      if(data->state.resume_from) {
-        if(data->state.resume_from < 0) {
-          /* We're supposed to download the last abs(from) bytes */
-          if((curl_off_t)attrs.filesize < -data->state.resume_from) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, attrs.filesize);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          /* download from where? */
-          data->state.resume_from += attrs.filesize;
-        }
-        else {
-          if((curl_off_t)attrs.filesize < data->state.resume_from) {
-            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
-                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, attrs.filesize);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-        }
-        /* Does a completed file need to be seeked and started or closed ? */
-        /* Now store the number of bytes we are expected to download */
-        data->req.size = attrs.filesize - data->state.resume_from;
-        data->req.maxdownload = attrs.filesize - data->state.resume_from;
-        Curl_pgrsSetDownloadSize(data,
-                                 attrs.filesize - data->state.resume_from);
-        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
-      }
-    }
-
-    /* Setup the actual download */
-    if(data->req.size == 0) {
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      infof(data, "File already completely downloaded\n");
-      state(conn, SSH_STOP);
-      break;
-    }
-    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
-
-    /* not set by Curl_setup_transfer to preserve keepon bits */
-    conn->writesockfd = conn->sockfd;
-
-    /* we want to use the _receiving_ function even when the socket turns
-       out writableable as the underlying libssh2 recv function will deal
-       with both accordingly */
-    conn->cselect_bits = CURL_CSELECT_IN;
-
-    if(result) {
-      /* this should never occur; the close state should be entered
-         at the time the error occurs */
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->actualcode = result;
-    }
-    else {
-      state(conn, SSH_STOP);
-    }
-    break;
-
-    case SSH_SFTP_CLOSE:
-      if(sshc->sftp_handle) {
-        rc = libssh2_sftp_close(sshc->sftp_handle);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
-        }
-        sshc->sftp_handle = NULL;
-      }
-
-      Curl_safefree(sftp_scp->path);
-
-      DEBUGF(infof(data, "SFTP DONE done\n"));
-
-      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
-         After nextstate is executed, the control should come back to
-         SSH_SFTP_CLOSE to pass the correct result back  */
-      if(sshc->nextstate != SSH_NO_STATE &&
-         sshc->nextstate != SSH_SFTP_CLOSE) {
-        state(conn, sshc->nextstate);
-        sshc->nextstate = SSH_SFTP_CLOSE;
-      }
-      else {
-        state(conn, SSH_STOP);
-        result = sshc->actualcode;
-      }
-      break;
-
-    case SSH_SFTP_SHUTDOWN:
-      /* during times we get here due to a broken transfer and then the
-         sftp_handle might not have been taken down so make sure that is done
-         before we proceed */
-
-      if(sshc->sftp_handle) {
-        rc = libssh2_sftp_close(sshc->sftp_handle);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session, &err_msg,
-                                           NULL, 0);
-          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
-        }
-        sshc->sftp_handle = NULL;
-      }
-      if(sshc->sftp_session) {
-        rc = libssh2_sftp_shutdown(sshc->sftp_session);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          infof(data, "Failed to stop libssh2 sftp subsystem\n");
-        }
-        sshc->sftp_session = NULL;
-      }
-
-      Curl_safefree(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_DISCONNECT);
-      break;
-
-    case SSH_SCP_TRANS_INIT:
-      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      if(data->set.upload) {
-        if(data->state.infilesize < 0) {
-          failf(data, "SCP requires a known file size for upload");
-          sshc->actualcode = CURLE_UPLOAD_FAILED;
-          state(conn, SSH_SCP_CHANNEL_FREE);
-          break;
-        }
-        state(conn, SSH_SCP_UPLOAD_INIT);
-      }
-      else {
-        state(conn, SSH_SCP_DOWNLOAD_INIT);
-      }
-      break;
-
-    case SSH_SCP_UPLOAD_INIT:
-      /*
-       * libssh2 requires that the destination path is a full path that
-       * includes the destination file and name OR ends in a "/" .  If this is
-       * not done the destination file will be named the same name as the last
-       * directory in the path.
-       */
-      sshc->ssh_channel =
-        SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
-                 data->state.infilesize);
-      if(!sshc->ssh_channel) {
-        int ssh_err;
-        char *err_msg = NULL;
-
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-
-        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
-                                                   &err_msg, NULL, 0));
-        failf(conn->data, "%s", err_msg);
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
-        /* Map generic errors to upload failed */
-        if(sshc->actualcode == CURLE_SSH ||
-           sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
-          sshc->actualcode = CURLE_UPLOAD_FAILED;
-        break;
-      }
-
-      /* upload data */
-      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      if(result) {
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = result;
-      }
-      else {
-        /* store this original bitmask setup to use later on if we can't
-           figure out a "real" bitmask */
-        sshc->orig_waitfor = data->req.keepon;
-
-        /* we want to use the _sending_ function even when the socket turns
-           out readable as the underlying libssh2 scp send function will deal
-           with both accordingly */
-        conn->cselect_bits = CURL_CSELECT_OUT;
-
-        state(conn, SSH_STOP);
-      }
-      break;
-
-    case SSH_SCP_DOWNLOAD_INIT:
-    {
-      curl_off_t bytecount;
-
-      /*
-       * We must check the remote file; if it is a directory no values will
-       * be set in sb
-       */
-
-      /*
-       * If support for >2GB files exists, use it.
-       */
-
-      /* get a fresh new channel from the ssh layer */
-#if LIBSSH2_VERSION_NUM < 0x010700
-      struct stat sb;
-      memset(&sb, 0, sizeof(struct stat));
-      sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
-                                           sftp_scp->path, &sb);
-#else
-      libssh2_struct_stat sb;
-      memset(&sb, 0, sizeof(libssh2_struct_stat));
-      sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
-                                            sftp_scp->path, &sb);
-#endif
-
-      if(!sshc->ssh_channel) {
-        int ssh_err;
-        char *err_msg = NULL;
-
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-
-
-        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
-                                                   &err_msg, NULL, 0));
-        failf(conn->data, "%s", err_msg);
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
-        break;
-      }
-
-      /* download data */
-      bytecount = (curl_off_t)sb.st_size;
-      data->req.maxdownload =  (curl_off_t)sb.st_size;
-      Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->writesockfd = conn->sockfd;
-
-      /* we want to use the _receiving_ function even when the socket turns
-         out writableable as the underlying libssh2 recv function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_IN;
-
-      if(result) {
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = result;
-      }
-      else
-        state(conn, SSH_STOP);
-    }
-    break;
-
-    case SSH_SCP_DONE:
-      if(data->set.upload)
-        state(conn, SSH_SCP_SEND_EOF);
-      else
-        state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_SEND_EOF:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_send_eof(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to send libssh2 channel EOF: %d %s\n",
-                rc, err_msg);
-        }
-      }
-      state(conn, SSH_SCP_WAIT_EOF);
-      break;
-
-    case SSH_SCP_WAIT_EOF:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_wait_eof(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg);
-        }
-      }
-      state(conn, SSH_SCP_WAIT_CLOSE);
-      break;
-
-    case SSH_SCP_WAIT_CLOSE:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_wait_closed(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Channel failed to close: %d %s\n", rc, err_msg);
-        }
-      }
-      state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_CHANNEL_FREE:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_free(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
-                rc, err_msg);
-        }
-        sshc->ssh_channel = NULL;
-      }
-      DEBUGF(infof(data, "SCP DONE phase complete\n"));
-#if 0 /* PREV */
-      state(conn, SSH_SESSION_DISCONNECT);
-#endif
-      state(conn, SSH_STOP);
-      result = sshc->actualcode;
-      break;
-
-    case SSH_SESSION_DISCONNECT:
-      /* during weird times when we've been prematurely aborted, the channel
-         is still alive when we reach this state and we MUST kill the channel
-         properly first */
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_free(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
-                rc, err_msg);
-        }
-        sshc->ssh_channel = NULL;
-      }
-
-      if(sshc->ssh_session) {
-        rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to disconnect libssh2 session: %d %s\n",
-                rc, err_msg);
-        }
-      }
-
-      Curl_safefree(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_FREE);
-      break;
-
-    case SSH_SESSION_FREE:
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-      if(sshc->kh) {
-        libssh2_knownhost_free(sshc->kh);
-        sshc->kh = NULL;
-      }
-#endif
-
-#ifdef HAVE_LIBSSH2_AGENT_API
-      if(sshc->ssh_agent) {
-        rc = libssh2_agent_disconnect(sshc->ssh_agent);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to disconnect from libssh2 agent: %d %s\n",
-                rc, err_msg);
-        }
-        libssh2_agent_free(sshc->ssh_agent);
-        sshc->ssh_agent = NULL;
-
-        /* NB: there is no need to free identities, they are part of internal
-           agent stuff */
-        sshc->sshagent_identity = NULL;
-        sshc->sshagent_prev_identity = NULL;
-      }
-#endif
-
-      if(sshc->ssh_session) {
-        rc = libssh2_session_free(sshc->ssh_session);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg);
-        }
-        sshc->ssh_session = NULL;
-      }
-
-      /* worst-case scenario cleanup */
-
-      DEBUGASSERT(sshc->ssh_session == NULL);
-      DEBUGASSERT(sshc->ssh_channel == NULL);
-      DEBUGASSERT(sshc->sftp_session == NULL);
-      DEBUGASSERT(sshc->sftp_handle == NULL);
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-      DEBUGASSERT(sshc->kh == NULL);
-#endif
-#ifdef HAVE_LIBSSH2_AGENT_API
-      DEBUGASSERT(sshc->ssh_agent == NULL);
-#endif
-
-      Curl_safefree(sshc->rsa_pub);
-      Curl_safefree(sshc->rsa);
-
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-
-      Curl_safefree(sshc->homedir);
-
-      Curl_safefree(sshc->readdir_filename);
-      Curl_safefree(sshc->readdir_longentry);
-      Curl_safefree(sshc->readdir_line);
-      Curl_safefree(sshc->readdir_linkPath);
-
-      /* the code we are about to return */
-      result = sshc->actualcode;
-
-      memset(sshc, 0, sizeof(struct ssh_conn));
-
-      connclose(conn, "SSH session free");
-      sshc->state = SSH_SESSION_FREE; /* current */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_QUIT:
-      /* fallthrough, just stop! */
-    default:
-      /* internal error */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-    }
-
-  } while(!rc && (sshc->state != SSH_STOP));
-
-  if(rc == LIBSSH2_ERROR_EAGAIN) {
-    /* we would block, we need to wait for the socket to be ready (in the
-       right direction too)! */
-    *block = TRUE;
-  }
-
-  return result;
-}
-
-/* called by the multi interface to figure out what socket(s) to wait for and
-   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
-static int ssh_perform_getsock(const struct connectdata *conn,
-                               curl_socket_t *sock, /* points to numsocks
-                                                       number of sockets */
-                               int numsocks)
-{
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-  int bitmap = GETSOCK_BLANK;
-  (void)numsocks;
-
-  sock[0] = conn->sock[FIRSTSOCKET];
-
-  if(conn->waitfor & KEEP_RECV)
-    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
-
-  if(conn->waitfor & KEEP_SEND)
-    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
-
-  return bitmap;
-#else
-  /* if we don't know the direction we can use the generic *_getsock()
-     function even for the protocol_connect and doing states */
-  return Curl_single_getsock(conn, sock, numsocks);
-#endif
-}
-
-/* Generic function called by the multi interface to figure out what socket(s)
-   to wait for and for what actions during the DOING and PROTOCONNECT states*/
-static int ssh_getsock(struct connectdata *conn,
-                       curl_socket_t *sock, /* points to numsocks number
-                                               of sockets */
-                       int numsocks)
-{
-#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-  (void)conn;
-  (void)sock;
-  (void)numsocks;
-  /* if we don't know any direction we can just play along as we used to and
-     not provide any sensible info */
-  return GETSOCK_BLANK;
-#else
-  /* if we know the direction we can use the generic *_getsock() function even
-     for the protocol_connect and doing states */
-  return ssh_perform_getsock(conn, sock, numsocks);
-#endif
-}
-
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-/*
- * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
- * function is used to figure out in what direction and stores this info so
- * that the multi interface can take advantage of it. Make sure to call this
- * function in all cases so that when it _doesn't_ return EAGAIN we can
- * restore the default wait bits.
- */
-static void ssh_block2waitfor(struct connectdata *conn, bool block)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  int dir = 0;
-  if(block) {
-    dir = libssh2_session_block_directions(sshc->ssh_session);
-    if(dir) {
-      /* translate the libssh2 define bits into our own bit defines */
-      conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
-        ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
-    }
-  }
-  if(!dir)
-    /* It didn't block or libssh2 didn't reveal in which direction, put back
-       the original set */
-    conn->waitfor = sshc->orig_waitfor;
-}
-#else
-  /* no libssh2 directional support so we simply don't know */
-#define ssh_block2waitfor(x,y) Curl_nop_stmt
-#endif
-
-/* called repeatedly until done from multi.c */
-static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  bool block; /* we store the status and use that to provide a ssh_getsock()
-                 implementation */
-  do {
-    result = ssh_statemach_act(conn, &block);
-    *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
-    /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
-       try again */
-  } while(!result && !*done && !block);
-  ssh_block2waitfor(conn, block);
-
-  return result;
-}
-
-static CURLcode ssh_block_statemach(struct connectdata *conn,
-                                    bool disconnect)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-
-  while((sshc->state != SSH_STOP) && !result) {
-    bool block;
-    timediff_t left = 1000;
-    struct curltime now = Curl_now();
-
-    result = ssh_statemach_act(conn, &block);
-    if(result)
-      break;
-
-    if(!disconnect) {
-      if(Curl_pgrsUpdate(conn))
-        return CURLE_ABORTED_BY_CALLBACK;
-
-      result = Curl_speedcheck(data, now);
-      if(result)
-        break;
-
-      left = Curl_timeleft(data, NULL, FALSE);
-      if(left < 0) {
-        failf(data, "Operation timed out");
-        return CURLE_OPERATION_TIMEDOUT;
-      }
-    }
-
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-    if(!result && block) {
-      int dir = libssh2_session_block_directions(sshc->ssh_session);
-      curl_socket_t sock = conn->sock[FIRSTSOCKET];
-      curl_socket_t fd_read = CURL_SOCKET_BAD;
-      curl_socket_t fd_write = CURL_SOCKET_BAD;
-      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
-        fd_read = sock;
-      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
-        fd_write = sock;
-      /* wait for the socket to become ready */
-      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
-                              left>1000?1000:left); /* ignore result */
-    }
-#endif
-
-  }
-
-  return result;
-}
-
-/*
- * SSH setup and connection
- */
-static CURLcode ssh_setup_connection(struct connectdata *conn)
-{
-  struct SSHPROTO *ssh;
-
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
-  if(!ssh)
-    return CURLE_OUT_OF_MEMORY;
-
-  return CURLE_OK;
-}
-
-static Curl_recv scp_recv, sftp_recv;
-static Curl_send scp_send, sftp_send;
-
-/*
- * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
- * do protocol-specific actions at connect-time.
- */
-static CURLcode ssh_connect(struct connectdata *conn, bool *done)
-{
-#ifdef CURL_LIBSSH2_DEBUG
-  curl_socket_t sock;
-#endif
-  struct ssh_conn *ssh;
-  CURLcode result;
-  struct Curl_easy *data = conn->data;
-
-  /* initialize per-handle data if not already */
-  if(!data->req.protop)
-    ssh_setup_connection(conn);
-
-  /* We default to persistent connections. We set this already in this connect
-     function to make the re-use checks properly be able to check this bit. */
-  connkeep(conn, "SSH default");
-
-  if(conn->handler->protocol & CURLPROTO_SCP) {
-    conn->recv[FIRSTSOCKET] = scp_recv;
-    conn->send[FIRSTSOCKET] = scp_send;
-  }
-  else {
-    conn->recv[FIRSTSOCKET] = sftp_recv;
-    conn->send[FIRSTSOCKET] = sftp_send;
-  }
-  ssh = &conn->proto.sshc;
-
-#ifdef CURL_LIBSSH2_DEBUG
-  if(conn->user) {
-    infof(data, "User: %s\n", conn->user);
-  }
-  if(conn->passwd) {
-    infof(data, "Password: %s\n", conn->passwd);
-  }
-  sock = conn->sock[FIRSTSOCKET];
-#endif /* CURL_LIBSSH2_DEBUG */
-
-  ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
-                                             my_libssh2_free,
-                                             my_libssh2_realloc, conn);
-  if(ssh->ssh_session == NULL) {
-    failf(data, "Failure initialising ssh session");
-    return CURLE_FAILED_INIT;
-  }
-
-  if(data->set.ssh_compression) {
-#if LIBSSH2_VERSION_NUM >= 0x010208
-    if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
-#endif
-      infof(data, "Failed to enable compression for ssh session\n");
-  }
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-    int rc;
-    ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
-    if(!ssh->kh) {
-      libssh2_session_free(ssh->ssh_session);
-      return CURLE_FAILED_INIT;
-    }
-
-    /* read all known hosts from there */
-    rc = libssh2_knownhost_readfile(ssh->kh,
-                                    data->set.str[STRING_SSH_KNOWNHOSTS],
-                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
-    if(rc < 0)
-      infof(data, "Failed to read known hosts from %s\n",
-            data->set.str[STRING_SSH_KNOWNHOSTS]);
-  }
-#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
-
-#ifdef CURL_LIBSSH2_DEBUG
-  libssh2_trace(ssh->ssh_session, ~0);
-  infof(data, "SSH socket: %d\n", (int)sock);
-#endif /* CURL_LIBSSH2_DEBUG */
-
-  state(conn, SSH_INIT);
-
-  result = ssh_multi_statemach(conn, done);
-
-  return result;
-}
-
-/*
- ***********************************************************************
- *
- * scp_perform()
- *
- * This is the actual DO function for SCP. Get a file according to
- * the options previously setup.
- */
-
-static
-CURLcode scp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE; /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SCP_TRANS_INIT);
-
-  /* run the state-machine */
-  result = ssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode scp_doing(struct connectdata *conn,
-                               bool *dophase_done)
-{
-  CURLcode result;
-  result = ssh_multi_statemach(conn, dophase_done);
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/*
- * The DO function is generic for both protocols. There was previously two
- * separate ones but this way means less duplicated code.
- */
-
-static CURLcode ssh_do(struct connectdata *conn, bool *done)
-{
-  CURLcode result;
-  bool connected = 0;
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  *done = FALSE; /* default to false */
-
-  data->req.size = -1; /* make sure this is unknown at this point */
-
-  sshc->actualcode = CURLE_OK; /* reset error code */
-  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
-                                   variable */
-
-  Curl_pgrsSetUploadCounter(data, 0);
-  Curl_pgrsSetDownloadCounter(data, 0);
-  Curl_pgrsSetUploadSize(data, -1);
-  Curl_pgrsSetDownloadSize(data, -1);
-
-  if(conn->handler->protocol & CURLPROTO_SCP)
-    result = scp_perform(conn, &connected,  done);
-  else
-    result = sftp_perform(conn, &connected,  done);
-
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  struct ssh_conn *ssh = &conn->proto.sshc;
-  (void) dead_connection;
-
-  if(ssh->ssh_session) {
-    /* only if there's a session still around to use! */
-
-    state(conn, SSH_SESSION_DISCONNECT);
-
-    result = ssh_block_statemach(conn, TRUE);
-  }
-
-  return result;
-}
-
-/* generic done function for both SCP and SFTP called from their specific
-   done functions */
-static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
-{
-  CURLcode result = CURLE_OK;
-  struct SSHPROTO *sftp_scp = conn->data->req.protop;
-
-  if(!status) {
-    /* run the state-machine */
-    result = ssh_block_statemach(conn, FALSE);
-  }
-  else
-    result = status;
-
-  if(sftp_scp)
-    Curl_safefree(sftp_scp->path);
-  if(Curl_pgrsDone(conn))
-    return CURLE_ABORTED_BY_CALLBACK;
-
-  conn->data->req.keepon = 0; /* clear all bits */
-  return result;
-}
-
-
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
-                         bool premature)
-{
-  (void)premature; /* not used */
-
-  if(!status)
-    state(conn, SSH_SCP_DONE);
-
-  return ssh_done(conn, status);
-
-}
-
-static ssize_t scp_send(struct connectdata *conn, int sockindex,
-                        const void *mem, size_t len, CURLcode *err)
-{
-  ssize_t nwrite;
-  (void)sockindex; /* we only support SCP on the fixed known primary socket */
-
-  /* libssh2_channel_write() returns int! */
-  nwrite = (ssize_t)
-    libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
-
-  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-
-  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nwrite = 0;
-  }
-  else if(nwrite < LIBSSH2_ERROR_NONE) {
-    *err = libssh2_session_error_to_CURLE((int)nwrite);
-    nwrite = -1;
-  }
-
-  return nwrite;
-}
-
-static ssize_t scp_recv(struct connectdata *conn, int sockindex,
-                        char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void)sockindex; /* we only support SCP on the fixed known primary socket */
-
-  /* libssh2_channel_read() returns int */
-  nread = (ssize_t)
-    libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
-
-  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-  if(nread == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nread = -1;
-  }
-
-  return nread;
-}
-
-/*
- * =============== SFTP ===============
- */
-
-/*
- ***********************************************************************
- *
- * sftp_perform()
- *
- * This is the actual DO function for SFTP. Get a file/directory according to
- * the options previously setup.
- */
-
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE; /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SFTP_QUOTE_INIT);
-
-  /* run the state-machine */
-  result = ssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done)
-{
-  CURLcode result = ssh_multi_statemach(conn, dophase_done);
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  (void) dead_connection;
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
-
-  if(conn->proto.sshc.ssh_session) {
-    /* only if there's a session still around to use! */
-    state(conn, SSH_SFTP_SHUTDOWN);
-    result = ssh_block_statemach(conn, TRUE);
-  }
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
-
-  return result;
-
-}
-
-static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
-                               bool premature)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  if(!status) {
-    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
-       errors that could happen due to open file handles during POSTQUOTE
-       operation */
-    if(!premature && conn->data->set.postquote && !conn->bits.retry)
-      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
-    state(conn, SSH_SFTP_CLOSE);
-  }
-  return ssh_done(conn, status);
-}
-
-/* return number of sent bytes */
-static ssize_t sftp_send(struct connectdata *conn, int sockindex,
-                         const void *mem, size_t len, CURLcode *err)
-{
-  ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
-                       but is changed to ssize_t in 0.15. These days we don't
-                       support libssh2 0.15*/
-  (void)sockindex;
-
-  nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
-
-  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-
-  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nwrite = 0;
-  }
-  else if(nwrite < LIBSSH2_ERROR_NONE) {
-    *err = libssh2_session_error_to_CURLE((int)nwrite);
-    nwrite = -1;
-  }
-
-  return nwrite;
-}
-
-/*
- * Return number of received (decrypted) bytes
- * or <0 on error
- */
-static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
-                         char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void)sockindex;
-
-  nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
-
-  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-
-  if(nread == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nread = -1;
-
-  }
-  else if(nread < 0) {
-    *err = libssh2_session_error_to_CURLE((int)nread);
-  }
-  return nread;
-}
-
-static const char *sftp_libssh2_strerror(int err)
-{
-  switch(err) {
-    case LIBSSH2_FX_NO_SUCH_FILE:
-      return "No such file or directory";
-
-    case LIBSSH2_FX_PERMISSION_DENIED:
-      return "Permission denied";
-
-    case LIBSSH2_FX_FAILURE:
-      return "Operation failed";
-
-    case LIBSSH2_FX_BAD_MESSAGE:
-      return "Bad message from SFTP server";
-
-    case LIBSSH2_FX_NO_CONNECTION:
-      return "Not connected to SFTP server";
-
-    case LIBSSH2_FX_CONNECTION_LOST:
-      return "Connection to SFTP server lost";
-
-    case LIBSSH2_FX_OP_UNSUPPORTED:
-      return "Operation not supported by SFTP server";
-
-    case LIBSSH2_FX_INVALID_HANDLE:
-      return "Invalid handle";
-
-    case LIBSSH2_FX_NO_SUCH_PATH:
-      return "No such file or directory";
-
-    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
-      return "File already exists";
-
-    case LIBSSH2_FX_WRITE_PROTECT:
-      return "File is write protected";
-
-    case LIBSSH2_FX_NO_MEDIA:
-      return "No media";
-
-    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
-      return "Disk full";
-
-    case LIBSSH2_FX_QUOTA_EXCEEDED:
-      return "User quota exceeded";
-
-    case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
-      return "Unknown principle";
-
-    case LIBSSH2_FX_LOCK_CONFlICT:
-      return "File lock conflict";
-
-    case LIBSSH2_FX_DIR_NOT_EMPTY:
-      return "Directory not empty";
-
-    case LIBSSH2_FX_NOT_A_DIRECTORY:
-      return "Not a directory";
-
-    case LIBSSH2_FX_INVALID_FILENAME:
-      return "Invalid filename";
-
-    case LIBSSH2_FX_LINK_LOOP:
-      return "Link points to itself";
-  }
-  return "Unknown error in libssh2";
-}
-
-#endif /* USE_LIBSSH2 */
diff --git a/libs/libcurl/src/ssh.h b/libs/libcurl/src/ssh.h
index 0620aac328..3213c5a52e 100644
--- a/libs/libcurl/src/ssh.h
+++ b/libs/libcurl/src/ssh.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -239,7 +239,16 @@ extern const struct Curl_handler Curl_handler_sftp;
 
 extern const struct Curl_handler Curl_handler_scp;
 extern const struct Curl_handler Curl_handler_sftp;
-
 #endif /* USE_LIBSSH2 */
 
+#ifdef USE_SSH
+/* generic SSH backend functions */
+CURLcode Curl_ssh_init(void);
+void Curl_ssh_cleanup(void);
+size_t Curl_ssh_version(char *buffer, size_t buflen);
+#else
+/* for non-SSH builds */
+#define Curl_ssh_cleanup()
+#endif
+
 #endif /* HEADER_CURL_SSH_H */
diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c
index e273f3765c..d0650d80c5 100644
--- a/libs/libcurl/src/strerror.c
+++ b/libs/libcurl/src/strerror.c
@@ -311,6 +311,9 @@ curl_easy_strerror(CURLcode error)
   case CURLE_RECURSIVE_API_CALL:
     return "API function called from within callback";
 
+  case CURLE_AUTH_ERROR:
+    return "An authentication function returned an error";
+
     /* error codes not used by current libcurl */
   case CURLE_OBSOLETE20:
   case CURLE_OBSOLETE24:
diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c
index 289cda2825..346f293dc5 100644
--- a/libs/libcurl/src/tftp.c
+++ b/libs/libcurl/src/tftp.c
@@ -157,8 +157,7 @@ static CURLcode tftp_done(struct connectdata *conn,
 static CURLcode tftp_setup_connection(struct connectdata * conn);
 static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
 static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
-static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode tftp_translate_code(tftp_error_t error);
 
 
@@ -404,13 +403,14 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
   return CURLE_OK;
 }
 
-static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
-                              char *buf, const char *option)
+static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize,
+                                char *buf, const char *option)
 {
-  if(( strlen(option) + csize + 1) > (size_t)state->blksize)
-    return 0;
+  if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
+    return CURLE_TFTP_ILLEGAL;
   strcpy(buf, option);
-  return strlen(option) + 1;
+  *csize += strlen(option) + 1;
+  return CURLE_OK;
 }
 
 static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
@@ -511,26 +511,38 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
       else
         strcpy(buf, "0"); /* the destination is large enough */
 
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes,
-                                TFTP_OPTION_TSIZE);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes, buf);
+      result = tftp_option_add(state, &sbytes,
+                               (char *)state->spacket.data + sbytes,
+                               TFTP_OPTION_TSIZE);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes, buf);
+
       /* add blksize option */
       msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes,
-                                TFTP_OPTION_BLKSIZE);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes, buf);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes,
+                                 TFTP_OPTION_BLKSIZE);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes, buf);
 
       /* add timeout option */
       msnprintf(buf, sizeof(buf), "%d", state->retry_time);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes,
-                                TFTP_OPTION_INTERVAL);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes, buf);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes,
+                                 TFTP_OPTION_INTERVAL);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes, buf);
+
+      if(result != CURLE_OK) {
+        failf(data, "TFTP buffer too small for options");
+        free(filename);
+        return CURLE_TFTP_ILLEGAL;
+      }
     }
 
     /* the typecase for the 3rd argument is mostly for systems that do
@@ -973,6 +985,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
 {
   tftp_state_data_t *state;
   int blksize;
+  int need_blksize;
 
   blksize = TFTP_BLKSIZE_DEFAULT;
 
@@ -987,15 +1000,20 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
       return CURLE_TFTP_ILLEGAL;
   }
 
+  need_blksize = blksize;
+  /* default size is the fallback when no OACK is received */
+  if(need_blksize < TFTP_BLKSIZE_DEFAULT)
+    need_blksize = TFTP_BLKSIZE_DEFAULT;
+
   if(!state->rpacket.data) {
-    state->rpacket.data = calloc(1, blksize + 2 + 2);
+    state->rpacket.data = calloc(1, need_blksize + 2 + 2);
 
     if(!state->rpacket.data)
       return CURLE_OUT_OF_MEMORY;
   }
 
   if(!state->spacket.data) {
-    state->spacket.data = calloc(1, blksize + 2 + 2);
+    state->spacket.data = calloc(1, need_blksize + 2 + 2);
 
     if(!state->spacket.data)
       return CURLE_OUT_OF_MEMORY;
@@ -1009,7 +1027,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
   state->sockfd = state->conn->sock[FIRSTSOCKET];
   state->state = TFTP_STATE_START;
   state->error = TFTP_ERR_NONE;
-  state->blksize = blksize;
+  state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
   state->requested_blksize = blksize;
 
   ((struct sockaddr *)&state->local_addr)->sa_family =
@@ -1082,14 +1100,9 @@ static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
  * The getsock callback
  *
  **********************************************************/
-static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   socks[0] = conn->sock[FIRSTSOCKET];
-
   return GETSOCK_READSOCK(0);
 }
 
@@ -1376,7 +1389,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
   struct Curl_easy *data = conn->data;
   char *type;
 
-  conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
+  conn->transport = TRNSPRT_UDP;
 
   /* TFTP URLs support an extension like ";mode=<typecode>" that
    * we'll try to get now! */
diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c
index e2bd7fd143..9b05cf0512 100644
--- a/libs/libcurl/src/timeval.c
+++ b/libs/libcurl/src/timeval.c
@@ -174,14 +174,6 @@ struct curltime Curl_now(void)
 
 #endif
 
-#if SIZEOF_TIME_T < 8
-#define TIME_MAX INT_MAX
-#define TIME_MIN INT_MIN
-#else
-#define TIME_MAX 9223372036854775807LL
-#define TIME_MIN -9223372036854775807LL
-#endif
-
 /*
  * Returns: time difference in number of milliseconds. For too large diffs it
  * returns max value.
@@ -191,10 +183,10 @@ struct curltime Curl_now(void)
 timediff_t Curl_timediff(struct curltime newer, struct curltime older)
 {
   timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
-  if(diff >= (TIME_MAX/1000))
-    return TIME_MAX;
-  else if(diff <= (TIME_MIN/1000))
-    return TIME_MIN;
+  if(diff >= (TIMEDIFF_T_MAX/1000))
+    return TIMEDIFF_T_MAX;
+  else if(diff <= (TIMEDIFF_T_MIN/1000))
+    return TIMEDIFF_T_MIN;
   return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
 }
 
@@ -205,9 +197,9 @@ timediff_t Curl_timediff(struct curltime newer, struct curltime older)
 timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
 {
   timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
-  if(diff >= (TIME_MAX/1000000))
-    return TIME_MAX;
-  else if(diff <= (TIME_MIN/1000000))
-    return TIME_MIN;
+  if(diff >= (TIMEDIFF_T_MAX/1000000))
+    return TIMEDIFF_T_MAX;
+  else if(diff <= (TIMEDIFF_T_MIN/1000000))
+    return TIMEDIFF_T_MIN;
   return diff * 1000000 + newer.tv_usec-older.tv_usec;
 }
diff --git a/libs/libcurl/src/timeval.h b/libs/libcurl/src/timeval.h
index 96867d7139..53e063607c 100644
--- a/libs/libcurl/src/timeval.h
+++ b/libs/libcurl/src/timeval.h
@@ -24,13 +24,13 @@
 
 #include "curl_setup.h"
 
-#if SIZEOF_TIME_T < 8
-typedef int timediff_t;
-#define CURL_FORMAT_TIMEDIFF_T "d"
-#else
+/* Use a larger type even for 32 bit time_t systems so that we can keep
+   microsecond accuracy in it */
 typedef curl_off_t timediff_t;
 #define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T
-#endif
+
+#define TIMEDIFF_T_MAX CURL_OFF_T_MAX
+#define TIMEDIFF_T_MIN CURL_OFF_T_MIN
 
 struct curltime {
   time_t tv_sec; /* seconds */
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index b9bb5f6edd..ef0d806384 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.c
@@ -176,7 +176,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
 #ifndef CURL_DISABLE_HTTP
   if(data->state.trailers_state == TRAILERS_INITIALIZED) {
     struct curl_slist *trailers = NULL;
-    CURLcode c;
+    CURLcode result;
     int trailers_ret_code;
 
     /* at this point we already verified that the callback exists
@@ -195,17 +195,18 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
                                                    data->set.trailer_data);
     Curl_set_in_callback(data, false);
     if(trailers_ret_code == CURL_TRAILERFUNC_OK) {
-      c = Curl_http_compile_trailers(trailers, data->state.trailers_buf, data);
+      result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf,
+                                          data);
     }
     else {
       failf(data, "operation aborted by trailing headers callback");
       *nreadp = 0;
-      c = CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
     }
-    if(c != CURLE_OK) {
+    if(result) {
       Curl_add_buffer_free(&data->state.trailers_buf);
       curl_slist_free_all(trailers);
-      return c;
+      return result;
     }
     infof(data, "Successfully compiled trailers.\r\n");
     curl_slist_free_all(trailers);
@@ -497,7 +498,7 @@ static int data_pending(const struct connectdata *conn)
        TRUE. The thing is if we read everything, then http2_recv won't
        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);
+    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20);
 #else
     Curl_ssl_data_pending(conn, FIRSTSOCKET);
 #endif
@@ -601,7 +602,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
       nread = 0;
     }
 
-    if((k->bytecount == 0) && (k->writebytecount == 0)) {
+    if(!k->bytecount) {
       Curl_pgrsTime(data, TIMER_STARTTRANSFER);
       if(k->exp100 > EXP100_SEND_DATA)
         /* set time stamp to compare with when waiting for the 100 */
@@ -942,7 +943,9 @@ CURLcode Curl_done_sending(struct connectdata *conn,
 {
   k->keepon &= ~KEEP_SEND; /* we're done writing */
 
+  /* These functions should be moved into the handler struct! */
   Curl_http2_done_sending(conn);
+  Curl_quic_done_sending(conn);
 
   if(conn->bits.rewindaftersend) {
     CURLcode result = Curl_readrewind(conn);
@@ -1354,20 +1357,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
  * in the proper state to have this information available.
  */
 int Curl_single_getsock(const struct connectdata *conn,
-                        curl_socket_t *sock, /* points to numsocks number
-                                                of sockets */
-                        int numsocks)
+                        curl_socket_t *sock)
 {
   const struct Curl_easy *data = conn->data;
   int bitmap = GETSOCK_BLANK;
   unsigned sockindex = 0;
 
   if(conn->handler->perform_getsock)
-    return conn->handler->perform_getsock(conn, sock, numsocks);
-
-  if(numsocks < 2)
-    /* simple check but we might need two slots */
-    return GETSOCK_BLANK;
+    return conn->handler->perform_getsock(conn, sock);
 
   /* don't include HOLD and PAUSE connections */
   if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
diff --git a/libs/libcurl/src/transfer.h b/libs/libcurl/src/transfer.h
index da36f19f81..67fd91f25b 100644
--- a/libs/libcurl/src/transfer.h
+++ b/libs/libcurl/src/transfer.h
@@ -47,8 +47,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
                         struct Curl_easy *data, bool *done,
                         bool *comeback);
 int Curl_single_getsock(const struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks);
+                        curl_socket_t *socks);
 CURLcode Curl_readrewind(struct connectdata *conn);
 CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
                              size_t *nreadp);
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index 2b47b235de..b7cf7bedd3 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.c
@@ -112,7 +112,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "connect.h"
 #include "inet_ntop.h"
 #include "http_ntlm.h"
-#include "socks.h"
 #include "curl_rtmp.h"
 #include "gopher.h"
 #include "http_proxy.h"
@@ -546,7 +545,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
   set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
   set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
   set->maxage_conn = 118;
-  set->http09_allowed = TRUE;
+  set->http09_allowed = FALSE;
   set->httpversion =
 #ifdef USE_NGHTTP2
     CURL_HTTP_VERSION_2TLS
@@ -715,6 +714,7 @@ static void conn_free(struct connectdata *conn)
   Curl_safefree(conn->user);
   Curl_safefree(conn->passwd);
   Curl_safefree(conn->oauth_bearer);
+  Curl_safefree(conn->sasl_authzid);
   Curl_safefree(conn->options);
   Curl_safefree(conn->http_proxy.user);
   Curl_safefree(conn->socks_proxy.user);
@@ -972,7 +972,8 @@ static int call_extract_if_dead(struct connectdata *conn, void *param)
 static void prune_dead_connections(struct Curl_easy *data)
 {
   struct curltime now = Curl_now();
-  time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup);
+  timediff_t elapsed =
+    Curl_timediff(now, data->state.conn_cache->last_cleanup);
 
   if(elapsed >= 1000L) {
     struct prunedead prune;
@@ -1371,58 +1372,6 @@ ConnectionExists(struct Curl_easy *data,
   return FALSE; /* no matching connecting exists */
 }
 
-/* after a TCP connection to the proxy has been verified, this function does
-   the next magic step.
-
-   Note: this function's sub-functions call failf()
-
-*/
-CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
-{
-  CURLcode result = CURLE_OK;
-
-  if(conn->bits.socksproxy) {
-#ifndef CURL_DISABLE_PROXY
-    /* for the secondary socket (FTP), use the "connect to host"
-     * but ignore the "connect to port" (use the secondary port)
-     */
-    const char * const host = conn->bits.httpproxy ?
-                              conn->http_proxy.host.name :
-                              conn->bits.conn_to_host ?
-                              conn->conn_to_host.name :
-                              sockindex == SECONDARYSOCKET ?
-                              conn->secondaryhostname : conn->host.name;
-    const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
-                     sockindex == SECONDARYSOCKET ? conn->secondary_port :
-                     conn->bits.conn_to_port ? conn->conn_to_port :
-                     conn->remote_port;
-    conn->bits.socksproxy_connecting = TRUE;
-    switch(conn->socks_proxy.proxytype) {
-    case CURLPROXY_SOCKS5:
-    case CURLPROXY_SOCKS5_HOSTNAME:
-      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
-                         host, port, sockindex, conn);
-      break;
-
-    case CURLPROXY_SOCKS4:
-    case CURLPROXY_SOCKS4A:
-      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
-                           conn);
-      break;
-
-    default:
-      failf(conn->data, "unknown proxytype option given");
-      result = CURLE_COULDNT_CONNECT;
-    } /* switch proxytype */
-    conn->bits.socksproxy_connecting = FALSE;
-#else
-  (void)sockindex;
-#endif /* CURL_DISABLE_PROXY */
-  }
-
-  return result;
-}
-
 /*
  * verboseconnect() displays verbose information after a connect
  */
@@ -1439,127 +1388,6 @@ void Curl_verboseconnect(struct connectdata *conn)
 }
 #endif
 
-int Curl_protocol_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
-{
-  if(conn->handler->proto_getsock)
-    return conn->handler->proto_getsock(conn, socks, numsocks);
-  /* Backup getsock logic. Since there is a live socket in use, we must wait
-     for it or it will be removed from watching when the multi_socket API is
-     used. */
-  socks[0] = conn->sock[FIRSTSOCKET];
-  return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
-}
-
-int Curl_doing_getsock(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks)
-{
-  if(conn && conn->handler->doing_getsock)
-    return conn->handler->doing_getsock(conn, socks, numsocks);
-  return GETSOCK_BLANK;
-}
-
-/*
- * We are doing protocol-specific connecting and this is being called over and
- * over from the multi interface until the connection phase is done on
- * protocol layer.
- */
-
-CURLcode Curl_protocol_connecting(struct connectdata *conn,
-                                  bool *done)
-{
-  CURLcode result = CURLE_OK;
-
-  if(conn && conn->handler->connecting) {
-    *done = FALSE;
-    result = conn->handler->connecting(conn, done);
-  }
-  else
-    *done = TRUE;
-
-  return result;
-}
-
-/*
- * We are DOING this is being called over and over from the multi interface
- * until the DOING phase is done on protocol layer.
- */
-
-CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
-{
-  CURLcode result = CURLE_OK;
-
-  if(conn && conn->handler->doing) {
-    *done = FALSE;
-    result = conn->handler->doing(conn, done);
-  }
-  else
-    *done = TRUE;
-
-  return result;
-}
-
-/*
- * We have discovered that the TCP connection has been successful, we can now
- * proceed with some action.
- *
- */
-CURLcode Curl_protocol_connect(struct connectdata *conn,
-                               bool *protocol_done)
-{
-  CURLcode result = CURLE_OK;
-
-  *protocol_done = FALSE;
-
-  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
-    /* We already are connected, get back. This may happen when the connect
-       worked fine in the first call, like when we connect to a local server
-       or proxy. Note that we don't know if the protocol is actually done.
-
-       Unless this protocol doesn't have any protocol-connect callback, as
-       then we know we're done. */
-    if(!conn->handler->connecting)
-      *protocol_done = TRUE;
-
-    return CURLE_OK;
-  }
-
-  if(!conn->bits.protoconnstart) {
-
-    result = Curl_proxy_connect(conn, FIRSTSOCKET);
-    if(result)
-      return result;
-
-    if(CONNECT_FIRSTSOCKET_PROXY_SSL())
-      /* wait for HTTPS proxy SSL initialization to complete */
-      return CURLE_OK;
-
-    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
-       Curl_connect_ongoing(conn))
-      /* when using an HTTP tunnel proxy, await complete tunnel establishment
-         before proceeding further. Return CURLE_OK so we'll be called again */
-      return CURLE_OK;
-
-    if(conn->handler->connect_it) {
-      /* is there a protocol-specific connect() procedure? */
-
-      /* Call the protocol-specific connect function */
-      result = conn->handler->connect_it(conn, protocol_done);
-    }
-    else
-      *protocol_done = TRUE;
-
-    /* it has started, possibly even completed but that knowledge isn't stored
-       in this bit! */
-    if(!result)
-      conn->bits.protoconnstart = TRUE;
-  }
-
-  return result; /* pass back status */
-}
-
 /*
  * Helpers for IDNA conversions.
  */
@@ -1774,6 +1602,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
   conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
   conn->ip_version = data->set.ipver;
   conn->bits.connect_only = data->set.connect_only;
+  conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
 
 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
     defined(NTLM_WB_ENABLED)
@@ -2110,7 +1939,6 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
 {
   const struct Curl_handler * p;
   CURLcode result;
-  conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
 
   /* Perform setup complement if some. */
   p = conn->handler;
@@ -2860,8 +2688,7 @@ static CURLcode override_login(struct Curl_easy *data,
                           &netrc_user_changed, &netrc_passwd_changed,
                           data->set.str[STRING_NETRC_FILE]);
     if(ret > 0) {
-      infof(data, "Couldn't find host %s in the "
-            DOT_CHAR "netrc file; using defaults\n",
+      infof(data, "Couldn't find host %s in the .netrc file; using defaults\n",
             conn->host.name);
     }
     else if(ret < 0) {
@@ -3158,26 +2985,65 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
   if(data->asi && !host && (port == -1) &&
      (conn->handler->protocol == CURLPROTO_HTTPS)) {
     /* no connect_to match, try alt-svc! */
-    const char *nhost;
-    int nport;
-    enum alpnid nalpnid;
+    enum alpnid srcalpnid;
     bool hit;
+    struct altsvc *as;
+    const int allowed_versions = ( ALPN_h1
+#ifdef USE_NGHTTP2
+      | ALPN_h2
+#endif
+#ifdef ENABLE_QUIC
+      | ALPN_h3
+#endif
+      ) & data->asi->flags;
+
     host = conn->host.rawalloc;
+#ifdef USE_NGHTTP2
+    /* with h2 support, check that first */
+    srcalpnid = ALPN_h2;
     hit = Curl_altsvc_lookup(data->asi,
-                             ALPN_h1, host, conn->remote_port, /* from */
-                             &nalpnid, &nhost, &nport /* to */);
+                             srcalpnid, host, conn->remote_port, /* from */
+                             &as /* to */,
+                             allowed_versions);
+    if(!hit)
+#endif
+    {
+      srcalpnid = ALPN_h1;
+      hit = Curl_altsvc_lookup(data->asi,
+                               srcalpnid, host, conn->remote_port, /* from */
+                               &as /* to */,
+                               allowed_versions);
+    }
     if(hit) {
-      char *hostd = strdup((char *)nhost);
+      char *hostd = strdup((char *)as->dst.host);
       if(!hostd)
         return CURLE_OUT_OF_MEMORY;
       conn->conn_to_host.rawalloc = hostd;
       conn->conn_to_host.name = hostd;
       conn->bits.conn_to_host = TRUE;
-      conn->conn_to_port = nport;
+      conn->conn_to_port = as->dst.port;
       conn->bits.conn_to_port = TRUE;
+      conn->bits.altused = TRUE;
       infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n",
-            Curl_alpnid2str(ALPN_h1), host, conn->remote_port,
-            Curl_alpnid2str(nalpnid), hostd, nport);
+            Curl_alpnid2str(srcalpnid), host, conn->remote_port,
+            Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port);
+      if(srcalpnid != as->dst.alpnid) {
+        /* protocol version switch */
+        switch(as->dst.alpnid) {
+        case ALPN_h1:
+          conn->httpversion = 11;
+          break;
+        case ALPN_h2:
+          conn->httpversion = 20;
+          break;
+        case ALPN_h3:
+          conn->transport = TRNSPRT_QUIC;
+          conn->httpversion = 30;
+          break;
+        default: /* shouldn't be possible */
+          break;
+        }
+      }
     }
   }
 #endif
@@ -3464,6 +3330,14 @@ static CURLcode create_conn(struct Curl_easy *data,
     }
   }
 
+  if(data->set.str[STRING_SASL_AUTHZID]) {
+    conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]);
+    if(!conn->sasl_authzid) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
 #ifdef USE_UNIX_SOCKETS
   if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
     conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
@@ -4162,34 +4036,3 @@ static unsigned int get_protocol_family(unsigned int protocol)
 
   return family;
 }
-
-
-/*
- * Wrapper to call functions in Curl_conncache_foreach()
- *
- * Returns always 0.
- */
-static int conn_upkeep(struct connectdata *conn,
-                       void *param)
-{
-  /* Param is unused. */
-  (void)param;
-
-  if(conn->handler->connection_check) {
-    /* Do a protocol-specific keepalive check on the connection. */
-    conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
-  }
-
-  return 0; /* continue iteration */
-}
-
-CURLcode Curl_upkeep(struct conncache *conn_cache,
-                          void *data)
-{
-  /* Loop over every connection and make connection alive. */
-  Curl_conncache_foreach(data,
-                         conn_cache,
-                         data,
-                         conn_upkeep);
-  return CURLE_OK;
-}
diff --git a/libs/libcurl/src/url.h b/libs/libcurl/src/url.h
index 7c87432c94..f4d611adda 100644
--- a/libs/libcurl/src/url.h
+++ b/libs/libcurl/src/url.h
@@ -53,23 +53,12 @@ CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
 CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect);
 CURLcode Curl_disconnect(struct Curl_easy *data,
                          struct connectdata *, bool dead_connection);
-CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
-CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
 CURLcode Curl_setup_conn(struct connectdata *conn,
                          bool *protocol_done);
 void Curl_free_request_state(struct Curl_easy *data);
-
-int Curl_protocol_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks);
-int Curl_doing_getsock(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks);
 CURLcode Curl_parse_login_details(const char *login, const size_t len,
                                   char **userptr, char **passwdptr,
                                   char **optionsptr);
-CURLcode Curl_upkeep(struct conncache *conn_cache, void *data);
 
 const struct Curl_handler *Curl_builtin_scheme(const char *scheme);
 
@@ -77,8 +66,6 @@ const struct Curl_handler *Curl_builtin_scheme(const char *scheme);
 #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
                                              specified */
 
-CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
-
 #ifdef CURL_DISABLE_VERBOSE_STRINGS
 #define Curl_verboseconnect(x)  Curl_nop_stmt
 #else
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c
index d07e4f5dff..a0ee331dab 100644
--- a/libs/libcurl/src/urlapi.c
+++ b/libs/libcurl/src/urlapi.c
@@ -29,6 +29,7 @@
 #include "url.h"
 #include "escape.h"
 #include "curl_ctype.h"
+#include "inet_pton.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -591,20 +592,22 @@ static CURLUcode junkscan(char *part)
 
 static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
 {
-  const char *l = NULL; /* accepted characters */
   size_t len;
   size_t hlen = strlen(hostname);
 
   if(hostname[0] == '[') {
+    char dest[16]; /* fits a binary IPv6 address */
+    const char *l = "0123456789abcdefABCDEF:.";
     hostname++;
-    l = "0123456789abcdefABCDEF::.";
     hlen -= 2;
-  }
 
-  if(l) {
+    if(hostname[hlen] != ']')
+      return CURLUE_MALFORMED_INPUT;
+
     /* only valid letters are ok */
     len = strspn(hostname, l);
     if(hlen != len) {
+      hlen = len;
       if(hostname[len] == '%') {
         /* this could now be '%[zone id]' */
         char zoneid[16];
@@ -628,6 +631,12 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
         return CURLUE_MALFORMED_INPUT;
       /* hostname is fine */
     }
+#ifdef ENABLE_IPV6
+    hostname[hlen] = 0; /* end the address there */
+    if(1 != Curl_inet_pton(AF_INET6, hostname, dest))
+      return CURLUE_MALFORMED_INPUT;
+    hostname[hlen] = ']'; /* restore ending bracket */
+#endif
   }
   else {
     /* letters from the second string is not ok */
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index fdc185b228..acc1fd1b9d 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.h
@@ -129,6 +129,7 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
 #include "smb.h"
 #include "wildcard.h"
 #include "multihandle.h"
+#include "quic.h"
 
 #ifdef HAVE_GSSAPI
 # ifdef HAVE_GSSGNU
@@ -404,6 +405,7 @@ struct ConnectBits {
                          the first time on the first connect function call */
   bit close:1; /* if set, we close the connection after this request */
   bit reuse:1; /* if set, this is a re-used connection */
+  bit altused:1; /* this is an alt-svc "redirect" */
   bit conn_to_host:1; /* if set, this connection has a "connect to host"
                          that overrides the host in the URL */
   bit conn_to_port:1; /* if set, this connection has a "connect to port"
@@ -663,27 +665,23 @@ struct Curl_handler {
   /* Called from the multi interface during the PROTOCONNECT phase, and it
      should then return a proper fd set */
   int (*proto_getsock)(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks);
+                       curl_socket_t *socks);
 
   /* Called from the multi interface during the DOING phase, and it should
      then return a proper fd set */
   int (*doing_getsock)(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks);
+                       curl_socket_t *socks);
 
   /* Called from the multi interface during the DO_MORE phase, and it should
      then return a proper fd set */
   int (*domore_getsock)(struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks);
+                        curl_socket_t *socks);
 
   /* Called from the multi interface during the DO_DONE, PERFORM and
      WAITPERFORM phases, and it should then return a proper fd set. Not setting
      this will make libcurl use the generic default one. */
   int (*perform_getsock)(const struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks);
+                         curl_socket_t *socks);
 
   /* This function *MAY* be set to a protocol-dependent function that is run
    * by the curl_disconnect(), as a step in the disconnection.  If the handler
@@ -782,6 +780,8 @@ struct http_connect_state {
   bit close_connection:1;
 };
 
+struct ldapconninfo;
+
 /*
  * The connectdata struct contains all fields and variables that should be
  * unique for an entire connection.
@@ -831,7 +831,16 @@ struct connectdata {
 
   unsigned int scope_id;  /* Scope id for IPv6 */
 
-  int socktype;  /* SOCK_STREAM or SOCK_DGRAM */
+  enum {
+    TRNSPRT_TCP = 3,
+    TRNSPRT_UDP = 4,
+    TRNSPRT_QUIC = 5
+  } transport;
+
+#ifdef ENABLE_QUIC
+  struct quicsocket hequic[2]; /* two, for happy eyeballs! */
+  struct quicsocket *quic;
+#endif
 
   struct hostname host;
   char *hostname_resolve; /* host name to resolve to address, allocated */
@@ -870,7 +879,8 @@ struct connectdata {
   char *passwd;  /* password string, allocated */
   char *options; /* options string, allocated */
 
-  char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
+  char *oauth_bearer;     /* bearer token for OAuth 2.0, allocated */
+  char *sasl_authzid;     /* authorisation identity string, allocated */
 
   int httpversion;        /* the HTTP version*10 reported by the server */
   int rtspversion;        /* the RTSP version*10 reported by the server */
@@ -904,8 +914,8 @@ struct connectdata {
   struct curltime connecttime;
   /* The two fields below get set in Curl_connecthost */
   int num_addr; /* number of addresses to try to connect to */
-  time_t timeoutms_per_addr; /* how long time in milliseconds to spend on
-                                trying to connect to each IP address */
+  timediff_t timeoutms_per_addr; /* how long time in milliseconds to spend on
+                                    trying to connect to each IP address */
 
   const struct Curl_handler *handler; /* Connection's protocol handler */
   const struct Curl_handler *given;   /* The protocol first given */
@@ -1010,7 +1020,8 @@ struct connectdata {
     struct smtp_conn smtpc;
     struct rtsp_conn rtspc;
     struct smb_conn smbc;
-    void *generic; /* RTMP and LDAP use this */
+    void *rtmp;
+    struct ldapconninfo *ldapc;
   } proto;
 
   int cselect_bits; /* bitmask of socket events */
@@ -1065,6 +1076,7 @@ struct PureInfo {
   long numconnects; /* how many new connection did libcurl created */
   char *contenttype; /* the content type of the object */
   char *wouldredirect; /* URL this would've been redirected to if asked to */
+  curl_off_t retry_after; /* info from Retry-After: header */
 
   /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
      and, 'conn_local_port' are copied over from the connectdata struct in
@@ -1084,7 +1096,6 @@ struct PureInfo {
                                  OpenSSL, GnuTLS, Schannel, NSS and GSKit
                                  builds. Asked for with CURLOPT_CERTINFO
                                  / CURLINFO_CERTINFO */
-
   bit timecond:1;  /* set to TRUE if the time condition didn't match, which
                       thus made the document NOT get fetched */
 };
@@ -1103,17 +1114,17 @@ struct Progress {
   int width; /* screen width at download start */
   int flags; /* see progress.h */
 
-  time_t timespent;
+  timediff_t timespent;
 
   curl_off_t dlspeed;
   curl_off_t ulspeed;
 
-  time_t t_nslookup;
-  time_t t_connect;
-  time_t t_appconnect;
-  time_t t_pretransfer;
-  time_t t_starttransfer;
-  time_t t_redirect;
+  timediff_t t_nslookup;
+  timediff_t t_connect;
+  timediff_t t_appconnect;
+  timediff_t t_pretransfer;
+  timediff_t t_starttransfer;
+  timediff_t t_redirect;
 
   struct curltime start;
   struct curltime t_startsingle;
@@ -1221,6 +1232,7 @@ typedef enum {
   EXPIRE_SPEEDCHECK,
   EXPIRE_TIMEOUT,
   EXPIRE_TOOFAST,
+  EXPIRE_QUIC,
   EXPIRE_LAST /* not an actual timer, used as a marker only */
 } expire_id;
 
@@ -1492,6 +1504,10 @@ enum dupstring {
   STRING_DOH,                   /* CURLOPT_DOH_URL */
 #ifdef USE_ALTSVC
   STRING_ALTSVC,                /* CURLOPT_ALTSVC */
+#endif
+  STRING_SASL_AUTHZID,          /* CURLOPT_SASL_AUTHZID */
+#ifndef CURL_DISABLE_PROXY
+  STRING_TEMP_URL,              /* temp URL storage for proxy use */
 #endif
   /* -- end of zero-terminated strings -- */
 
diff --git a/libs/libcurl/src/vauth/digest_sspi.c b/libs/libcurl/src/vauth/digest_sspi.c
index fe8093e8b3..a1090568b2 100644
--- a/libs/libcurl/src/vauth/digest_sspi.c
+++ b/libs/libcurl/src/vauth/digest_sspi.c
@@ -61,6 +61,11 @@ bool Curl_auth_is_digest_supported(void)
   status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -220,7 +225,10 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
     free(output_token);
     free(input_token);
 
-    return CURLE_RECV_ERROR;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Base64 encode the response */
@@ -607,7 +615,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
 
       Curl_safefree(digest->http_context);
 
-      return CURLE_OUT_OF_MEMORY;
+      if(status == SEC_E_INSUFFICIENT_MEMORY)
+        return CURLE_OUT_OF_MEMORY;
+
+      return CURLE_AUTH_ERROR;
     }
 
     output_token_len = resp_buf.cbBuffer;
diff --git a/libs/libcurl/src/vauth/krb5_gssapi.c b/libs/libcurl/src/vauth/krb5_gssapi.c
index ea0a5f1892..95bab0e2ee 100644
--- a/libs/libcurl/src/vauth/krb5_gssapi.c
+++ b/libs/libcurl/src/vauth/krb5_gssapi.c
@@ -121,7 +121,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
 
       free(spn);
 
-      return CURLE_OUT_OF_MEMORY;
+      return CURLE_AUTH_ERROR;
     }
 
     free(spn);
@@ -168,7 +168,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
     Curl_gss_log_error(data, "gss_init_sec_context() failed: ",
                        major_status, minor_status);
 
-    return CURLE_RECV_ERROR;
+    return CURLE_AUTH_ERROR;
   }
 
   if(output_token.value && output_token.length) {
@@ -252,7 +252,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
 
     free(chlg);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Convert the username from internal format to a displayable token */
@@ -264,7 +264,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
 
     free(chlg);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Setup the challenge "input" security buffer */
@@ -355,7 +355,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
 
     free(message);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Base64 encode the response */
diff --git a/libs/libcurl/src/vauth/krb5_sspi.c b/libs/libcurl/src/vauth/krb5_sspi.c
index 1f6e462bf7..98041d9156 100644
--- a/libs/libcurl/src/vauth/krb5_sspi.c
+++ b/libs/libcurl/src/vauth/krb5_sspi.c
@@ -58,6 +58,11 @@ bool Curl_auth_is_gssapi_supported(void)
                                               TEXT(SP_NAME_KERBEROS),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -217,8 +222,12 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
   /* Free the decoded challenge as it is not required anymore */
   free(chlg);
 
+  if(status == SEC_E_INSUFFICIENT_MEMORY) {
+    return CURLE_OUT_OF_MEMORY;
+  }
+
   if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
-    return CURLE_RECV_ERROR;
+    return CURLE_AUTH_ERROR;
   }
 
   if(memcmp(&context, krb5->context, sizeof(context))) {
@@ -309,7 +318,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
   if(status != SEC_E_OK) {
     free(chlg);
 
-    return CURLE_OUT_OF_MEMORY;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Get the fully qualified username back from the context */
@@ -319,7 +331,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
   if(status != SEC_E_OK) {
     free(chlg);
 
-    return CURLE_RECV_ERROR;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Setup the "input" security buffer */
@@ -438,7 +453,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
     free(message);
     free(trailer);
 
-    return CURLE_OUT_OF_MEMORY;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Allocate the encryption (wrap) buffer */
diff --git a/libs/libcurl/src/vauth/ntlm_sspi.c b/libs/libcurl/src/vauth/ntlm_sspi.c
index 589cca16c0..cd6cb79c14 100644
--- a/libs/libcurl/src/vauth/ntlm_sspi.c
+++ b/libs/libcurl/src/vauth/ntlm_sspi.c
@@ -56,6 +56,11 @@ bool Curl_auth_is_ntlm_supported(void)
   status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -169,8 +174,10 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
   if(status == SEC_I_COMPLETE_NEEDED ||
     status == SEC_I_COMPLETE_AND_CONTINUE)
     s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc);
+  else if(status == SEC_E_INSUFFICIENT_MEMORY)
+    return CURLE_OUT_OF_MEMORY;
   else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
-    return CURLE_RECV_ERROR;
+    return CURLE_AUTH_ERROR;
 
   /* Base64 encode the response */
   return Curl_base64_encode(data, (char *) ntlm->output_token,
@@ -316,7 +323,10 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
     infof(data, "NTLM handshake failure (type-3 message): Status=%x\n",
           status);
 
-    return CURLE_RECV_ERROR;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Base64 encode the response */
diff --git a/libs/libcurl/src/vauth/spnego_gssapi.c b/libs/libcurl/src/vauth/spnego_gssapi.c
index 5d43e11001..ed7ce029ec 100644
--- a/libs/libcurl/src/vauth/spnego_gssapi.c
+++ b/libs/libcurl/src/vauth/spnego_gssapi.c
@@ -121,7 +121,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
 
       free(spn);
 
-      return CURLE_OUT_OF_MEMORY;
+      return CURLE_AUTH_ERROR;
     }
 
     free(spn);
@@ -170,14 +170,14 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
     Curl_gss_log_error(data, "gss_init_sec_context() failed: ",
                        major_status, minor_status);
 
-    return CURLE_LOGIN_DENIED;
+    return CURLE_AUTH_ERROR;
   }
 
   if(!output_token.value || !output_token.length) {
     if(output_token.value)
       gss_release_buffer(&unused_status, &output_token);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Free previous token */
diff --git a/libs/libcurl/src/vauth/spnego_sspi.c b/libs/libcurl/src/vauth/spnego_sspi.c
index 4b21cc769e..b9c2cf7d62 100644
--- a/libs/libcurl/src/vauth/spnego_sspi.c
+++ b/libs/libcurl/src/vauth/spnego_sspi.c
@@ -59,6 +59,12 @@ bool Curl_auth_is_spnego_supported(void)
                                               TEXT(SP_NAME_NEGOTIATE),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -165,7 +171,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
                                          nego->p_identity, NULL, NULL,
                                          nego->credentials, &expiry);
     if(nego->status != SEC_E_OK)
-      return CURLE_LOGIN_DENIED;
+      return CURLE_AUTH_ERROR;
 
     /* Allocate our new context handle */
     nego->context = calloc(1, sizeof(CtxtHandle));
@@ -251,14 +257,25 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
     char buffer[STRERROR_LEN];
     failf(data, "InitializeSecurityContext failed: %s",
           Curl_sspi_strerror(nego->status, buffer, sizeof(buffer)));
-    return CURLE_OUT_OF_MEMORY;
+
+    if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   if(nego->status == SEC_I_COMPLETE_NEEDED ||
      nego->status == SEC_I_COMPLETE_AND_CONTINUE) {
     nego->status = s_pSecFn->CompleteAuthToken(nego->context, &resp_desc);
     if(GSS_ERROR(nego->status)) {
-      return CURLE_RECV_ERROR;
+      char buffer[STRERROR_LEN];
+      failf(data, "CompleteAuthToken failed: %s",
+            Curl_sspi_strerror(nego->status, buffer, sizeof(buffer)));
+
+      if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY)
+        return CURLE_OUT_OF_MEMORY;
+
+      return CURLE_AUTH_ERROR;
     }
   }
 
diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c
index 14b0531d37..ae2b09d310 100644
--- a/libs/libcurl/src/version.c
+++ b/libs/libcurl/src/version.c
@@ -27,6 +27,7 @@
 #include "vtls/vtls.h"
 #include "http2.h"
 #include "ssh.h"
+#include "quic.h"
 #include "curl_printf.h"
 
 #ifdef USE_ARES
@@ -53,18 +54,6 @@
 #include <librtmp/rtmp.h>
 #endif
 
-#ifdef USE_LIBSSH2
-#include <libssh2.h>
-#endif
-
-#ifdef HAVE_LIBSSH2_VERSION
-/* get it run-time if possible */
-#define CURL_LIBSSH2_VERSION libssh2_version(0)
-#else
-/* use build-time if run-time not possible */
-#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
-#endif
-
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #ifdef __SYMBIAN32__
@@ -102,7 +91,7 @@ static size_t brotli_version(char *buf, size_t bufsz)
 char *curl_version(void)
 {
   static bool initialized;
-  static char version[200];
+  static char version[250];
   char *ptr = version;
   size_t len;
   size_t left = sizeof(version);
@@ -172,18 +161,22 @@ char *curl_version(void)
   left -= len;
   ptr += len;
 #endif
-#ifdef USE_LIBSSH2
-  len = msnprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
+#ifdef USE_SSH
+  if(left) {
+    *ptr++=' ';
+    left--;
+  }
+  len = Curl_ssh_version(ptr, left);
   left -= len;
   ptr += len;
 #endif
-#ifdef USE_LIBSSH
-  len = msnprintf(ptr, left, " libssh/%s", CURL_LIBSSH_VERSION);
+#ifdef USE_NGHTTP2
+  len = Curl_http2_ver(ptr, left);
   left -= len;
   ptr += len;
 #endif
-#ifdef USE_NGHTTP2
-  len = Curl_http2_ver(ptr, left);
+#ifdef ENABLE_QUIC
+  len = Curl_quic_ver(ptr, left);
   left -= len;
   ptr += len;
 #endif
@@ -358,6 +351,9 @@ static curl_version_info_data version_info = {
 #if defined(USE_NGHTTP2)
   | CURL_VERSION_HTTP2
 #endif
+#if defined(ENABLE_QUIC)
+  | CURL_VERSION_HTTP3
+#endif
 #if defined(USE_UNIX_SOCKETS)
   | CURL_VERSION_UNIX_SOCKETS
 #endif
@@ -385,6 +381,9 @@ static curl_version_info_data version_info = {
   NULL, /* ssh lib version */
   0,    /* brotli_ver_num */
   NULL, /* brotli version */
+  0,    /* nghttp2 version number */
+  NULL, /* nghttp2 version string */
+  NULL  /* quic library string */
 };
 
 curl_version_info_data *curl_version_info(CURLversion stamp)
@@ -446,11 +445,8 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
 #endif /* _LIBICONV_VERSION */
 #endif
 
-#if defined(USE_LIBSSH2)
-  msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
-  version_info.libssh_version = ssh_buffer;
-#elif defined(USE_LIBSSH)
-  msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh/%s", CURL_LIBSSH_VERSION);
+#if defined(USE_SSH)
+  Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer));
   version_info.libssh_version = ssh_buffer;
 #endif
 
@@ -460,6 +456,22 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
   version_info.brotli_version = brotli_buffer;
 #endif
 
+#ifdef USE_NGHTTP2
+  {
+    nghttp2_info *h2 = nghttp2_version(0);
+    version_info.nghttp2_ver_num = h2->version_num;
+    version_info.nghttp2_version = h2->version_str;
+  }
+#endif
+
+#ifdef ENABLE_QUIC
+  {
+    static char quicbuffer[80];
+    Curl_quic_ver(quicbuffer, sizeof(quicbuffer));
+    version_info.quic_version = quicbuffer;
+  }
+#endif
+
   (void)stamp; /* avoid compiler warnings, we don't use this */
 
   initialized = true;
diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c
new file mode 100644
index 0000000000..76956a3c1f
--- /dev/null
+++ b/libs/libcurl/src/vssh/libssh.c
@@ -0,0 +1,2747 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2017 - 2019 Red Hat, Inc.
+ *
+ * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek,
+ *          Robert Kolcun, Andreas Schneider
+ *
+ * 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_LIBSSH
+
+#include <limits.h>
+
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h"               /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "strdup.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h"          /* for the week day and month names */
+#include "sockaddr.h"           /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+
+/* for permission and open flags */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+#include "curl_path.h"
+
+/* 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)
+#endif
+
+/* Local functions: */
+static CURLcode myssh_connect(struct connectdata *conn, bool *done);
+static CURLcode myssh_multi_statemach(struct connectdata *conn,
+                                      bool *done);
+static CURLcode myssh_do_it(struct connectdata *conn, bool *done);
+
+static CURLcode scp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn,
+                               bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done);
+
+static void sftp_quote(struct connectdata *conn);
+static void sftp_quote_stat(struct connectdata *conn);
+static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock);
+static int myssh_perform_getsock(const struct connectdata *conn,
+                                 curl_socket_t *sock);
+
+static CURLcode myssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                        /* scheme */
+  myssh_setup_connection,       /* setup_connection */
+  myssh_do_it,                  /* do_it */
+  scp_done,                     /* done */
+  ZERO_NULL,                    /* do_more */
+  myssh_connect,                /* connect_it */
+  myssh_multi_statemach,        /* connecting */
+  scp_doing,                    /* doing */
+  myssh_getsock,                /* proto_getsock */
+  myssh_getsock,                /* doing_getsock */
+  ZERO_NULL,                    /* domore_getsock */
+  myssh_perform_getsock,        /* perform_getsock */
+  scp_disconnect,               /* disconnect */
+  ZERO_NULL,                    /* readwrite */
+  ZERO_NULL,                    /* connection_check */
+  PORT_SSH,                     /* defport */
+  CURLPROTO_SCP,                /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY    /* flags */
+};
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  myssh_setup_connection,               /* setup_connection */
+  myssh_do_it,                          /* do_it */
+  sftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  myssh_connect,                        /* connect_it */
+  myssh_multi_statemach,                /* connecting */
+  sftp_doing,                           /* doing */
+  myssh_getsock,                        /* proto_getsock */
+  myssh_getsock,                        /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  myssh_perform_getsock,                /* perform_getsock */
+  sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+static CURLcode sftp_error_to_CURLE(int err)
+{
+  switch(err) {
+    case SSH_FX_OK:
+      return CURLE_OK;
+
+    case SSH_FX_NO_SUCH_FILE:
+    case SSH_FX_NO_SUCH_PATH:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case SSH_FX_PERMISSION_DENIED:
+    case SSH_FX_WRITE_PROTECT:
+      return CURLE_REMOTE_ACCESS_DENIED;
+
+    case SSH_FX_FILE_ALREADY_EXISTS:
+      return CURLE_REMOTE_FILE_EXISTS;
+
+    default:
+      break;
+  }
+
+  return CURLE_SSH;
+}
+
+#ifndef DEBUGBUILD
+#define state(x,y) mystate(x,y)
+#else
+#define state(x,y) mystate(x,y, __LINE__)
+#endif
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void mystate(struct connectdata *conn, sshstate nowstate
+#ifdef DEBUGBUILD
+                    , int lineno
+#endif
+  )
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char *const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_GSSAPI",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_QUOTE_STATVFS",
+    "SSH_SFTP_GETINFO",
+    "SSH_SFTP_FILETIME",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DOWNLOAD",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
+          (void *) sshc, names[sshc->state], names[nowstate],
+          lineno);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+/* Multiple options:
+ * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5
+ *    hash (90s style auth, not sure we should have it here)
+ * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first
+ *    use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE
+ *    is returned by it.
+ * 3. none of the above. We only accept if it is present on known hosts.
+ *
+ * Returns SSH_OK or SSH_ERROR.
+ */
+static int myssh_is_known(struct connectdata *conn)
+{
+  int rc;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  ssh_key pubkey;
+  size_t hlen;
+  unsigned char *hash = NULL;
+  char *base64 = NULL;
+  int vstate;
+  enum curl_khmatch keymatch;
+  struct curl_khkey foundkey;
+  curl_sshkeycallback func =
+    data->set.ssh_keyfunc;
+
+  rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
+  if(rc != SSH_OK)
+    return rc;
+
+  if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
+    rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
+                                &hash, &hlen);
+    if(rc != SSH_OK)
+      goto cleanup;
+
+    if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) ||
+       memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) {
+      rc = SSH_ERROR;
+      goto cleanup;
+    }
+
+    rc = SSH_OK;
+    goto cleanup;
+  }
+
+  if(data->set.ssl.primary.verifyhost != TRUE) {
+    rc = SSH_OK;
+    goto cleanup;
+  }
+
+  vstate = ssh_is_server_known(sshc->ssh_session);
+  switch(vstate) {
+    case SSH_SERVER_KNOWN_OK:
+      keymatch = CURLKHMATCH_OK;
+      break;
+    case SSH_SERVER_FILE_NOT_FOUND:
+      /* fallthrough */
+    case SSH_SERVER_NOT_KNOWN:
+      keymatch = CURLKHMATCH_MISSING;
+      break;
+  default:
+      keymatch = CURLKHMATCH_MISMATCH;
+      break;
+  }
+
+  if(func) { /* use callback to determine action */
+    rc = ssh_pki_export_pubkey_base64(pubkey, &base64);
+    if(rc != SSH_OK)
+      goto cleanup;
+
+    foundkey.key = base64;
+    foundkey.len = strlen(base64);
+
+    switch(ssh_key_type(pubkey)) {
+      case SSH_KEYTYPE_RSA:
+        foundkey.keytype = CURLKHTYPE_RSA;
+        break;
+      case SSH_KEYTYPE_RSA1:
+        foundkey.keytype = CURLKHTYPE_RSA1;
+        break;
+      case SSH_KEYTYPE_ECDSA:
+        foundkey.keytype = CURLKHTYPE_ECDSA;
+        break;
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0)
+      case SSH_KEYTYPE_ED25519:
+        foundkey.keytype = CURLKHTYPE_ED25519;
+        break;
+#endif
+      case SSH_KEYTYPE_DSS:
+        foundkey.keytype = CURLKHTYPE_DSS;
+        break;
+      default:
+        rc = SSH_ERROR;
+        goto cleanup;
+    }
+
+    /* we don't have anything equivalent to knownkey. Always NULL */
+    Curl_set_in_callback(data, true);
+    rc = func(data, NULL, &foundkey, /* from the remote host */
+              keymatch, data->set.ssh_keyfunc_userp);
+    Curl_set_in_callback(data, false);
+
+    switch(rc) {
+      case CURLKHSTAT_FINE_ADD_TO_FILE:
+        rc = ssh_write_knownhost(sshc->ssh_session);
+        if(rc != SSH_OK) {
+          goto cleanup;
+        }
+        break;
+      case CURLKHSTAT_FINE:
+        break;
+      default: /* REJECT/DEFER */
+        rc = SSH_ERROR;
+        goto cleanup;
+    }
+  }
+  else {
+    if(keymatch != CURLKHMATCH_OK) {
+      rc = SSH_ERROR;
+      goto cleanup;
+    }
+  }
+  rc = SSH_OK;
+
+cleanup:
+  if(hash)
+    ssh_clean_pubkey_hash(&hash);
+  ssh_key_free(pubkey);
+  return rc;
+}
+
+#define MOVE_TO_ERROR_STATE(_r) { \
+  state(conn, SSH_SESSION_DISCONNECT); \
+  sshc->actualcode = _r; \
+  rc = SSH_ERROR; \
+  break; \
+}
+
+#define MOVE_TO_SFTP_CLOSE_STATE() { \
+  state(conn, SSH_SFTP_CLOSE); \
+  sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \
+  rc = SSH_ERROR; \
+  break; \
+}
+
+#define MOVE_TO_LAST_AUTH \
+  if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
+    rc = SSH_OK; \
+    state(conn, SSH_AUTH_PASS_INIT); \
+    break; \
+  } \
+  else { \
+    MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
+  }
+
+#define MOVE_TO_TERTIARY_AUTH \
+  if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
+    rc = SSH_OK; \
+    state(conn, SSH_AUTH_KEY_INIT); \
+    break; \
+  } \
+  else { \
+    MOVE_TO_LAST_AUTH; \
+  }
+
+#define MOVE_TO_SECONDARY_AUTH \
+  if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
+    rc = SSH_OK; \
+    state(conn, SSH_AUTH_GSSAPI); \
+    break; \
+  } \
+  else { \
+    MOVE_TO_TERTIARY_AUTH; \
+  }
+
+static
+int myssh_auth_interactive(struct connectdata *conn)
+{
+  int rc;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  int nprompts;
+
+restart:
+  switch(sshc->kbd_state) {
+    case 0:
+      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
+      if(rc == SSH_AUTH_AGAIN)
+        return SSH_AGAIN;
+
+      if(rc != SSH_AUTH_INFO)
+        return SSH_ERROR;
+
+      nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
+      if(nprompts == SSH_ERROR || nprompts != 1)
+        return SSH_ERROR;
+
+      rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd);
+      if(rc < 0)
+        return SSH_ERROR;
+
+    /* FALLTHROUGH */
+    case 1:
+      sshc->kbd_state = 1;
+
+      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
+      if(rc == SSH_AUTH_AGAIN)
+        return SSH_AGAIN;
+      else if(rc == SSH_AUTH_SUCCESS)
+        rc = SSH_OK;
+      else if(rc == SSH_AUTH_INFO) {
+        nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
+        if(nprompts != 0)
+          return SSH_ERROR;
+
+        sshc->kbd_state = 2;
+        goto restart;
+      }
+      else
+        rc = SSH_ERROR;
+      break;
+    case 2:
+      sshc->kbd_state = 2;
+
+      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
+      if(rc == SSH_AUTH_AGAIN)
+        return SSH_AGAIN;
+      else if(rc == SSH_AUTH_SUCCESS)
+        rc = SSH_OK;
+      else
+        rc = SSH_ERROR;
+
+      break;
+    default:
+      return SSH_ERROR;
+  }
+
+  sshc->kbd_state = 0;
+  return rc;
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the libssh function returns SSH_AGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *protop = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int rc = SSH_NO_ERROR, err;
+  char *new_readdir_line;
+  int seekerr = CURL_SEEKFUNC_OK;
+  const char *err_msg;
+  *block = 0;                   /* we're not blocking by default */
+
+  do {
+
+    switch(sshc->state) {
+    case SSH_INIT:
+      sshc->secondCreateDirs = 0;
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_OK;
+
+#if 0
+      ssh_set_log_level(SSH_LOG_PROTOCOL);
+#endif
+
+      /* Set libssh to non-blocking, since everything internally is
+         non-blocking */
+      ssh_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_S_STARTUP);
+      /* FALLTHROUGH */
+
+    case SSH_S_STARTUP:
+      rc = ssh_connect(sshc->ssh_session);
+      if(rc == SSH_AGAIN)
+        break;
+
+      if(rc != SSH_OK) {
+        failf(data, "Failure establishing ssh session");
+        MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT);
+      }
+
+      state(conn, SSH_HOSTKEY);
+
+      /* FALLTHROUGH */
+    case SSH_HOSTKEY:
+
+      rc = myssh_is_known(conn);
+      if(rc != SSH_OK) {
+        MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION);
+      }
+
+      state(conn, SSH_AUTHLIST);
+      /* FALLTHROUGH */
+    case SSH_AUTHLIST:{
+        sshc->authed = FALSE;
+
+        rc = ssh_userauth_none(sshc->ssh_session, NULL);
+        if(rc == SSH_AUTH_AGAIN) {
+          rc = SSH_AGAIN;
+          break;
+        }
+
+        if(rc == SSH_AUTH_SUCCESS) {
+          sshc->authed = TRUE;
+          infof(data, "Authenticated with none\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+        else if(rc == SSH_AUTH_ERROR) {
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+        }
+
+        sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
+        if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
+          state(conn, SSH_AUTH_PKEY_INIT);
+          infof(data, "Authentication using SSH public key file\n");
+        }
+        else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
+          state(conn, SSH_AUTH_GSSAPI);
+        }
+        else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
+          state(conn, SSH_AUTH_KEY_INIT);
+        }
+        else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
+          state(conn, SSH_AUTH_PASS_INIT);
+        }
+        else {                  /* unsupported authentication method */
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+        }
+
+        break;
+      }
+    case SSH_AUTH_PKEY_INIT:
+      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
+        MOVE_TO_SECONDARY_AUTH;
+      }
+
+      /* Two choices, (1) private key was given on CMD,
+       * (2) use the "default" keys. */
+      if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
+        if(sshc->pubkey && !data->set.ssl.key_passwd) {
+          rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL,
+                                          sshc->pubkey);
+          if(rc == SSH_AUTH_AGAIN) {
+            rc = SSH_AGAIN;
+            break;
+          }
+
+          if(rc != SSH_OK) {
+            MOVE_TO_SECONDARY_AUTH;
+          }
+        }
+
+        rc = ssh_pki_import_privkey_file(data->
+                                         set.str[STRING_SSH_PRIVATE_KEY],
+                                         data->set.ssl.key_passwd, NULL,
+                                         NULL, &sshc->privkey);
+        if(rc != SSH_OK) {
+          failf(data, "Could not load private key file %s",
+                data->set.str[STRING_SSH_PRIVATE_KEY]);
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+          break;
+        }
+
+        state(conn, SSH_AUTH_PKEY);
+        break;
+
+      }
+      else {
+        rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
+                                         data->set.ssl.key_passwd);
+        if(rc == SSH_AUTH_AGAIN) {
+          rc = SSH_AGAIN;
+          break;
+        }
+        if(rc == SSH_AUTH_SUCCESS) {
+          rc = SSH_OK;
+          sshc->authed = TRUE;
+          infof(data, "Completed public key authentication\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+
+        MOVE_TO_SECONDARY_AUTH;
+      }
+      break;
+    case SSH_AUTH_PKEY:
+      rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey);
+      if(rc == SSH_AUTH_AGAIN) {
+        rc = SSH_AGAIN;
+        break;
+      }
+
+      if(rc == SSH_AUTH_SUCCESS) {
+        sshc->authed = TRUE;
+        infof(data, "Completed public key authentication\n");
+        state(conn, SSH_AUTH_DONE);
+        break;
+      }
+      else {
+        infof(data, "Failed public key authentication (rc: %d)\n", rc);
+        MOVE_TO_SECONDARY_AUTH;
+      }
+      break;
+
+    case SSH_AUTH_GSSAPI:
+      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
+        MOVE_TO_TERTIARY_AUTH;
+      }
+
+      rc = ssh_userauth_gssapi(sshc->ssh_session);
+      if(rc == SSH_AUTH_AGAIN) {
+        rc = SSH_AGAIN;
+        break;
+      }
+
+      if(rc == SSH_AUTH_SUCCESS) {
+        rc = SSH_OK;
+        sshc->authed = TRUE;
+        infof(data, "Completed gssapi authentication\n");
+        state(conn, SSH_AUTH_DONE);
+        break;
+      }
+
+      MOVE_TO_TERTIARY_AUTH;
+      break;
+
+    case SSH_AUTH_KEY_INIT:
+      if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) {
+        state(conn, SSH_AUTH_KEY);
+      }
+      else {
+        MOVE_TO_LAST_AUTH;
+      }
+      break;
+
+    case SSH_AUTH_KEY:
+
+      /* Authentication failed. Continue with keyboard-interactive now. */
+      rc = myssh_auth_interactive(conn);
+      if(rc == SSH_AGAIN) {
+        break;
+      }
+      if(rc == SSH_OK) {
+        sshc->authed = TRUE;
+        infof(data, "completed keyboard interactive authentication\n");
+      }
+      state(conn, SSH_AUTH_DONE);
+      break;
+
+    case SSH_AUTH_PASS_INIT:
+      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
+        /* Host key authentication is intentionally not implemented */
+        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+      }
+      state(conn, SSH_AUTH_PASS);
+      /* FALLTHROUGH */
+
+    case SSH_AUTH_PASS:
+      rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
+      if(rc == SSH_AUTH_AGAIN) {
+        rc = SSH_AGAIN;
+        break;
+      }
+
+      if(rc == SSH_AUTH_SUCCESS) {
+        sshc->authed = TRUE;
+        infof(data, "Completed password authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+      }
+      break;
+
+    case SSH_AUTH_DONE:
+      if(!sshc->authed) {
+        failf(data, "Authentication failure");
+        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+        break;
+      }
+
+      /*
+       * At this point we have an authenticated ssh session.
+       */
+      infof(data, "Authentication complete\n");
+
+      Curl_pgrsTime(conn->data, TIMER_APPCONNECT);      /* SSH is connected */
+
+      conn->sockfd = sock;
+      conn->writesockfd = CURL_SOCKET_BAD;
+
+      if(conn->handler->protocol == CURLPROTO_SFTP) {
+        state(conn, SSH_SFTP_INIT);
+        break;
+      }
+      infof(data, "SSH CONNECT phase done\n");
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_INIT:
+      ssh_set_blocking(sshc->ssh_session, 1);
+
+      sshc->sftp_session = sftp_new(sshc->ssh_session);
+      if(!sshc->sftp_session) {
+        failf(data, "Failure initializing sftp session: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+        break;
+      }
+
+      rc = sftp_init(sshc->sftp_session);
+      if(rc != SSH_OK) {
+        rc = sftp_get_error(sshc->sftp_session);
+        failf(data, "Failure initializing sftp session: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc));
+        break;
+      }
+      state(conn, SSH_SFTP_REALPATH);
+      /* FALLTHROUGH */
+    case SSH_SFTP_REALPATH:
+      /*
+       * Get the "home" directory
+       */
+      sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, ".");
+      if(sshc->homedir == NULL) {
+        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+      }
+      conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+
+      /* This is the last step in the SFTP connect phase. Do note that while
+         we get the homedir here, we get the "workingpath" in the DO action
+         since the homedir will remain the same between request but the
+         working path will not. */
+      DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_QUOTE_INIT:
+
+      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_GETINFO);
+      }
+      break;
+
+    case SSH_SFTP_POSTQUOTE_INIT:
+      if(data->set.postquote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.postquote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SFTP_QUOTE:
+      /* Send any quote commands */
+      sftp_quote(conn);
+      break;
+
+    case SSH_SFTP_NEXT_QUOTE:
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      sshc->quote_item = sshc->quote_item->next;
+
+      if(sshc->quote_item) {
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        if(sshc->nextstate != SSH_NO_STATE) {
+          state(conn, sshc->nextstate);
+          sshc->nextstate = SSH_NO_STATE;
+        }
+        else {
+          state(conn, SSH_SFTP_GETINFO);
+        }
+      }
+      break;
+
+    case SSH_SFTP_QUOTE_STAT:
+      sftp_quote_stat(conn);
+      break;
+
+    case SSH_SFTP_QUOTE_SETSTAT:
+      rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
+                        sshc->quote_attrs);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "Attempt to set SFTP stats failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        /* sshc->actualcode = sftp_error_to_CURLE(err);
+         * we do not send the actual error; we return
+         * the error the libssh2 backend is returning */
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_SYMLINK:
+      rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
+                        sshc->quote_path1);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "symlink command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_MKDIR:
+      rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
+                      (mode_t)data->set.new_directory_perms);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "mkdir command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RENAME:
+      rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
+                       sshc->quote_path2);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "rename command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RMDIR:
+      rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rmdir command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_UNLINK:
+      rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rm command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_STATVFS:
+    {
+      sftp_statvfs_t statvfs;
+
+      statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1);
+      if(!statvfs && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "statvfs command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      else if(statvfs) {
+        char *tmp = aprintf("statvfs:\n"
+                            "f_bsize: %llu\n" "f_frsize: %llu\n"
+                            "f_blocks: %llu\n" "f_bfree: %llu\n"
+                            "f_bavail: %llu\n" "f_files: %llu\n"
+                            "f_ffree: %llu\n" "f_favail: %llu\n"
+                            "f_fsid: %llu\n" "f_flag: %llu\n"
+                            "f_namemax: %llu\n",
+                            statvfs->f_bsize, statvfs->f_frsize,
+                            statvfs->f_blocks, statvfs->f_bfree,
+                            statvfs->f_bavail, statvfs->f_files,
+                            statvfs->f_ffree, statvfs->f_favail,
+                            statvfs->f_fsid, statvfs->f_flag,
+                            statvfs->f_namemax);
+        sftp_statvfs_free(statvfs);
+
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+    }
+
+    case SSH_SFTP_GETINFO:
+      if(data->set.get_filetime) {
+        state(conn, SSH_SFTP_FILETIME);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+
+    case SSH_SFTP_FILETIME:
+    {
+      sftp_attributes attrs;
+
+      attrs = sftp_stat(sshc->sftp_session, protop->path);
+      if(attrs != 0) {
+        data->info.filetime = attrs->mtime;
+        sftp_attributes_free(attrs);
+      }
+
+      state(conn, SSH_SFTP_TRANS_INIT);
+      break;
+    }
+
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(protop->path[strlen(protop->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_UPLOAD_INIT:
+    {
+      int flags;
+
+      if(data->state.resume_from != 0) {
+        sftp_attributes attrs;
+
+        if(data->state.resume_from < 0) {
+          attrs = sftp_stat(sshc->sftp_session, protop->path);
+          if(attrs != 0) {
+            curl_off_t size = attrs->size;
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME);
+            }
+            data->state.resume_from = attrs->size;
+
+            sftp_attributes_free(attrs);
+          }
+          else {
+            data->state.resume_from = 0;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = O_WRONLY|O_CREAT|O_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = O_WRONLY|O_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = O_WRONLY|O_CREAT|O_TRUNC;
+
+      if(sshc->sftp_file)
+        sftp_close(sshc->sftp_file);
+      sshc->sftp_file =
+        sftp_open(sshc->sftp_session, protop->path,
+                  flags, (mode_t)data->set.new_file_perms);
+      if(!sshc->sftp_file) {
+        err = sftp_get_error(sshc->sftp_session);
+
+        if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE ||
+             err == SSH_FX_NO_SUCH_PATH)) &&
+             (data->set.ftp_create_missing_dirs &&
+             (strlen(protop->path) > 1))) {
+               /* try to create the path remotely */
+               rc = 0;
+               sshc->secondCreateDirs = 1;
+               state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+               break;
+        }
+        else {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+      }
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        if(conn->seek_func) {
+          Curl_set_in_callback(data, true);
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+          Curl_set_in_callback(data, false);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed = 0;
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > data->set.buffer_size) ?
+              (size_t)data->set.buffer_size :
+              curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread =
+              data->state.fread_func(data->state.buffer, 1,
+                                     readthisamountnow, data->state.in);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST);
+            }
+          } while(passed < data->state.resume_from);
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
+        if(rc != 0) {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      /* store this original bitmask setup to use later on if we can't
+         figure out a "real" bitmask */
+      sshc->orig_waitfor = data->req.keepon;
+
+      /* we want to use the _sending_ function even when the socket turns
+         out readable as the underlying libssh sftp send function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_OUT;
+
+      /* since we don't really wait for anything at this point, we want the
+         state machine to move on as soon as possible so we set a very short
+         timeout here */
+      Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+      state(conn, SSH_STOP);
+      break;
+    }
+
+    case SSH_SFTP_CREATE_DIRS_INIT:
+      if(strlen(protop->path) > 1) {
+        sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */
+        state(conn, SSH_SFTP_CREATE_DIRS);
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS:
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
+        *sshc->slash_pos = 0;
+
+        infof(data, "Creating directory '%s'\n", protop->path);
+        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+        break;
+      }
+      state(conn, SSH_SFTP_UPLOAD_INIT);
+      break;
+
+    case SSH_SFTP_CREATE_DIRS_MKDIR:
+      /* 'mode' - parameter is preliminary - default to 0644 */
+      rc = sftp_mkdir(sshc->sftp_session, protop->path,
+                      (mode_t)data->set.new_directory_perms);
+      *sshc->slash_pos = '/';
+      ++sshc->slash_pos;
+      if(rc < 0) {
+        /*
+         * Abort if failure wasn't that the dir already exists or the
+         * permission was denied (creation might succeed further down the
+         * path) - retry on unspecific FAILURE also
+         */
+        err = sftp_get_error(sshc->sftp_session);
+        if((err != SSH_FX_FILE_ALREADY_EXISTS) &&
+           (err != SSH_FX_FAILURE) &&
+           (err != SSH_FX_PERMISSION_DENIED)) {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+        rc = 0; /* clear rc and continue */
+      }
+      state(conn, SSH_SFTP_CREATE_DIRS);
+      break;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /*
+       * This is a directory that we are trying to get, so produce a directory
+       * listing
+       */
+      sshc->sftp_dir = sftp_opendir(sshc->sftp_session,
+                                    protop->path);
+      if(!sshc->sftp_dir) {
+        failf(data, "Could not open directory for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_SFTP_CLOSE_STATE();
+      }
+      state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR:
+
+      if(sshc->readdir_attrs)
+        sftp_attributes_free(sshc->readdir_attrs);
+
+      sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir);
+      if(sshc->readdir_attrs) {
+        sshc->readdir_filename = sshc->readdir_attrs->name;
+        sshc->readdir_longentry = sshc->readdir_attrs->longname;
+        sshc->readdir_len = strlen(sshc->readdir_filename);
+
+        if(data->set.ftp_list_only) {
+          char *tmpLine;
+
+          tmpLine = aprintf("%s\n", sshc->readdir_filename);
+          if(tmpLine == NULL) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     tmpLine, sshc->readdir_len + 1);
+          free(tmpLine);
+
+          if(result) {
+            state(conn, SSH_STOP);
+            break;
+          }
+          /* since this counts what we send to the client, we include the
+             newline in this counter */
+          data->req.bytecount += sshc->readdir_len + 1;
+
+          /* output debug output if that is requested */
+          if(data->set.verbose) {
+            Curl_debug(data, CURLINFO_DATA_OUT,
+                       (char *)sshc->readdir_filename,
+                       sshc->readdir_len);
+          }
+        }
+        else {
+          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
+          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
+          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
+          if(!sshc->readdir_line) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+
+          memcpy(sshc->readdir_line, sshc->readdir_longentry,
+                 sshc->readdir_currLen);
+          if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
+             ((sshc->readdir_attrs->permissions & S_IFMT) ==
+              S_IFLNK)) {
+            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
+            if(sshc->readdir_linkPath == NULL) {
+              state(conn, SSH_SFTP_CLOSE);
+              sshc->actualcode = CURLE_OUT_OF_MEMORY;
+              break;
+            }
+
+            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path,
+                      sshc->readdir_filename);
+
+            state(conn, SSH_SFTP_READDIR_LINK);
+            break;
+          }
+          state(conn, SSH_SFTP_READDIR_BOTTOM);
+          break;
+        }
+      }
+      else if(sshc->readdir_attrs == NULL && sftp_dir_eof(sshc->sftp_dir)) {
+        state(conn, SSH_SFTP_READDIR_DONE);
+        break;
+      }
+      else {
+        failf(data, "Could not open remote file for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_SFTP_CLOSE_STATE();
+        break;
+      }
+      break;
+
+    case SSH_SFTP_READDIR_LINK:
+      if(sshc->readdir_link_attrs)
+        sftp_attributes_free(sshc->readdir_link_attrs);
+
+      sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session,
+                                            sshc->readdir_linkPath);
+      if(sshc->readdir_link_attrs == 0) {
+        failf(data, "Could not read symlink for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_SFTP_CLOSE_STATE();
+      }
+
+      if(sshc->readdir_link_attrs->name == NULL) {
+        sshc->readdir_tmp = sftp_readlink(sshc->sftp_session,
+                                          sshc->readdir_linkPath);
+        if(sshc->readdir_filename == NULL)
+          sshc->readdir_len = 0;
+        else
+          sshc->readdir_len = strlen(sshc->readdir_tmp);
+        sshc->readdir_longentry = NULL;
+        sshc->readdir_filename = sshc->readdir_tmp;
+      }
+      else {
+        sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
+        sshc->readdir_filename = sshc->readdir_link_attrs->name;
+        sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
+      }
+
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* get room for the filename and extra output */
+      sshc->readdir_totalLen += 4 + sshc->readdir_len;
+      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
+                                          sshc->readdir_totalLen);
+      if(!new_readdir_line) {
+        sshc->readdir_line = NULL;
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_line = new_readdir_line;
+
+      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+                                         sshc->readdir_currLen,
+                                         sshc->readdir_totalLen -
+                                         sshc->readdir_currLen,
+                                         " -> %s",
+                                         sshc->readdir_filename);
+
+      sftp_attributes_free(sshc->readdir_link_attrs);
+      sshc->readdir_link_attrs = NULL;
+      sshc->readdir_filename = NULL;
+      sshc->readdir_longentry = NULL;
+
+      state(conn, SSH_SFTP_READDIR_BOTTOM);
+      /* FALLTHROUGH */
+    case SSH_SFTP_READDIR_BOTTOM:
+      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+                                         sshc->readdir_currLen,
+                                         sshc->readdir_totalLen -
+                                         sshc->readdir_currLen, "\n");
+      result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                 sshc->readdir_line,
+                                 sshc->readdir_currLen);
+
+      if(!result) {
+
+        /* output debug output if that is requested */
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+                     sshc->readdir_currLen);
+        }
+        data->req.bytecount += sshc->readdir_currLen;
+      }
+      Curl_safefree(sshc->readdir_line);
+      ssh_string_free_char(sshc->readdir_tmp);
+      sshc->readdir_tmp = NULL;
+
+      if(result) {
+        state(conn, SSH_STOP);
+      }
+      else
+        state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR_DONE:
+      sftp_closedir(sshc->sftp_dir);
+      sshc->sftp_dir = NULL;
+
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_INIT:
+      /*
+       * Work on getting the specified file
+       */
+      if(sshc->sftp_file)
+        sftp_close(sshc->sftp_file);
+
+      sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path,
+                                  O_RDONLY, (mode_t)data->set.new_file_perms);
+      if(!sshc->sftp_file) {
+        failf(data, "Could not open remote file for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+
+        MOVE_TO_SFTP_CLOSE_STATE();
+      }
+
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_STAT:
+    {
+      sftp_attributes attrs;
+      curl_off_t size;
+
+      attrs = sftp_fstat(sshc->sftp_file);
+      if(!attrs ||
+              !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) ||
+              (attrs->size == 0)) {
+        /*
+         * sftp_fstat didn't return an error, so maybe the server
+         * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
+         */
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+        size = 0;
+      }
+      else {
+        size = attrs->size;
+
+        sftp_attributes_free(attrs);
+
+        if(size < 0) {
+          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        if(conn->data->state.use_range) {
+          curl_off_t from, to;
+          char *ptr;
+          char *ptr2;
+          CURLofft to_t;
+          CURLofft from_t;
+
+          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+          if(from_t == CURL_OFFT_FLOW) {
+            return CURLE_RANGE_ERROR;
+          }
+          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+            ptr++;
+          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
+          if(to_t == CURL_OFFT_FLOW) {
+            return CURLE_RANGE_ERROR;
+          }
+          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
+             || (to >= size)) {
+            to = size - 1;
+          }
+          if(from_t) {
+            /* from is relative to end of file */
+            from = size - to;
+            to = size - 1;
+          }
+          if(from > size) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")", from, size);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          if(from > to) {
+            from = to;
+            size = 0;
+          }
+          else {
+            size = to - from + 1;
+          }
+
+          rc = sftp_seek64(sshc->sftp_file, from);
+          if(rc != 0) {
+            MOVE_TO_SFTP_CLOSE_STATE();
+          }
+        }
+        data->req.size = size;
+        data->req.maxdownload = size;
+        Curl_pgrsSetDownloadSize(data, size);
+      }
+
+      /* We can resume if we can seek to the resume position */
+      if(data->state.resume_from) {
+        if(data->state.resume_from < 0) {
+          /* We're supposed to download the last abs(from) bytes */
+          if((curl_off_t)size < -data->state.resume_from) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, size);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          /* download from where? */
+          data->state.resume_from += size;
+        }
+        else {
+          if((curl_off_t)size < data->state.resume_from) {
+            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, size);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+        }
+        /* Does a completed file need to be seeked and started or closed ? */
+        /* Now store the number of bytes we are expected to download */
+        data->req.size = size - data->state.resume_from;
+        data->req.maxdownload = size - data->state.resume_from;
+        Curl_pgrsSetDownloadSize(data,
+                                 size - data->state.resume_from);
+
+        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
+        if(rc != 0) {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+      }
+    }
+
+    /* Setup the actual download */
+    if(data->req.size == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      infof(data, "File already completely downloaded\n");
+      state(conn, SSH_STOP);
+      break;
+    }
+    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
+
+    /* not set by Curl_setup_transfer to preserve keepon bits */
+    conn->writesockfd = conn->sockfd;
+
+    /* we want to use the _receiving_ function even when the socket turns
+       out writableable as the underlying libssh recv function will deal
+       with both accordingly */
+    conn->cselect_bits = CURL_CSELECT_IN;
+
+    if(result) {
+      /* this should never occur; the close state should be entered
+         at the time the error occurs */
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->actualcode = result;
+    }
+    else {
+      sshc->sftp_recv_state = 0;
+      state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SFTP_CLOSE:
+      if(sshc->sftp_file) {
+        sftp_close(sshc->sftp_file);
+        sshc->sftp_file = NULL;
+      }
+      Curl_safefree(protop->path);
+
+      DEBUGF(infof(data, "SFTP DONE done\n"));
+
+      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+         After nextstate is executed, the control should come back to
+         SSH_SFTP_CLOSE to pass the correct result back  */
+      if(sshc->nextstate != SSH_NO_STATE &&
+         sshc->nextstate != SSH_SFTP_CLOSE) {
+        state(conn, sshc->nextstate);
+        sshc->nextstate = SSH_SFTP_CLOSE;
+      }
+      else {
+        state(conn, SSH_STOP);
+        result = sshc->actualcode;
+      }
+      break;
+
+    case SSH_SFTP_SHUTDOWN:
+      /* during times we get here due to a broken transfer and then the
+         sftp_handle might not have been taken down so make sure that is done
+         before we proceed */
+
+      if(sshc->sftp_file) {
+        sftp_close(sshc->sftp_file);
+        sshc->sftp_file = NULL;
+      }
+
+      if(sshc->sftp_session) {
+        sftp_free(sshc->sftp_session);
+        sshc->sftp_session = NULL;
+      }
+
+      SSH_STRING_FREE_CHAR(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      break;
+
+
+    case SSH_SCP_TRANS_INIT:
+      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
+      ssh_set_blocking(sshc->ssh_session, 1);
+
+      if(data->set.upload) {
+        if(data->state.infilesize < 0) {
+          failf(data, "SCP requires a known file size for upload");
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+          MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+        }
+
+        sshc->scp_session =
+          ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path);
+        state(conn, SSH_SCP_UPLOAD_INIT);
+      }
+      else {
+        sshc->scp_session =
+          ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path);
+        state(conn, SSH_SCP_DOWNLOAD_INIT);
+      }
+
+      if(!sshc->scp_session) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+      }
+
+      break;
+
+    case SSH_SCP_UPLOAD_INIT:
+
+      rc = ssh_scp_init(sshc->scp_session);
+      if(rc != SSH_OK) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+      }
+
+      rc = ssh_scp_push_file(sshc->scp_session, protop->path,
+                             data->state.infilesize,
+                             (int)data->set.new_file_perms);
+      if(rc != SSH_OK) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+      }
+
+      /* upload data */
+      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      /* store this original bitmask setup to use later on if we can't
+         figure out a "real" bitmask */
+      sshc->orig_waitfor = data->req.keepon;
+
+      /* we want to use the _sending_ function even when the socket turns
+         out readable as the underlying libssh scp send function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_OUT;
+
+      state(conn, SSH_STOP);
+
+      break;
+
+    case SSH_SCP_DOWNLOAD_INIT:
+
+      rc = ssh_scp_init(sshc->scp_session);
+      if(rc != SSH_OK) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+      }
+      state(conn, SSH_SCP_DOWNLOAD);
+      /* FALLTHROUGH */
+
+    case SSH_SCP_DOWNLOAD:{
+        curl_off_t bytecount;
+
+        rc = ssh_scp_pull_request(sshc->scp_session);
+        if(rc != SSH_SCP_REQUEST_NEWFILE) {
+          err_msg = ssh_get_error(sshc->ssh_session);
+          failf(conn->data, "%s", err_msg);
+          MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND);
+          break;
+        }
+
+        /* download data */
+        bytecount = ssh_scp_request_get_size(sshc->scp_session);
+        data->req.maxdownload = (curl_off_t) bytecount;
+        Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
+
+        /* not set by Curl_setup_transfer to preserve keepon bits */
+        conn->writesockfd = conn->sockfd;
+
+        /* we want to use the _receiving_ function even when the socket turns
+           out writableable as the underlying libssh recv function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_IN;
+
+        state(conn, SSH_STOP);
+        break;
+      }
+    case SSH_SCP_DONE:
+      if(data->set.upload)
+        state(conn, SSH_SCP_SEND_EOF);
+      else
+        state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_SEND_EOF:
+      if(sshc->scp_session) {
+        rc = ssh_scp_close(sshc->scp_session);
+        if(rc == SSH_AGAIN) {
+          /* Currently the ssh_scp_close handles waiting for EOF in
+           * blocking way.
+           */
+          break;
+        }
+        if(rc != SSH_OK) {
+          infof(data, "Failed to close libssh scp channel: %s\n",
+                ssh_get_error(sshc->ssh_session));
+        }
+      }
+
+      state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_CHANNEL_FREE:
+      if(sshc->scp_session) {
+        ssh_scp_free(sshc->scp_session);
+        sshc->scp_session = NULL;
+      }
+      DEBUGF(infof(data, "SCP DONE phase complete\n"));
+
+      ssh_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      /* FALLTHROUGH */
+
+    case SSH_SESSION_DISCONNECT:
+      /* during weird times when we've been prematurely aborted, the channel
+         is still alive when we reach this state and we MUST kill the channel
+         properly first */
+      if(sshc->scp_session) {
+        ssh_scp_free(sshc->scp_session);
+        sshc->scp_session = NULL;
+      }
+
+      ssh_disconnect(sshc->ssh_session);
+
+      SSH_STRING_FREE_CHAR(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
+    case SSH_SESSION_FREE:
+      if(sshc->ssh_session) {
+        ssh_free(sshc->ssh_session);
+        sshc->ssh_session = NULL;
+      }
+
+      /* worst-case scenario cleanup */
+
+      DEBUGASSERT(sshc->ssh_session == NULL);
+      DEBUGASSERT(sshc->scp_session == NULL);
+
+      if(sshc->readdir_tmp) {
+        ssh_string_free_char(sshc->readdir_tmp);
+        sshc->readdir_tmp = NULL;
+      }
+
+      if(sshc->quote_attrs)
+        sftp_attributes_free(sshc->quote_attrs);
+
+      if(sshc->readdir_attrs)
+        sftp_attributes_free(sshc->readdir_attrs);
+
+      if(sshc->readdir_link_attrs)
+        sftp_attributes_free(sshc->readdir_link_attrs);
+
+      if(sshc->privkey)
+        ssh_key_free(sshc->privkey);
+      if(sshc->pubkey)
+        ssh_key_free(sshc->pubkey);
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      Curl_safefree(sshc->readdir_line);
+      Curl_safefree(sshc->readdir_linkPath);
+      SSH_STRING_FREE_CHAR(sshc->homedir);
+
+      /* the code we are about to return */
+      result = sshc->actualcode;
+
+      memset(sshc, 0, sizeof(struct ssh_conn));
+
+      connclose(conn, "SSH session free");
+      sshc->state = SSH_SESSION_FREE;   /* current */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    }
+  } while(!rc && (sshc->state != SSH_STOP));
+
+
+  if(rc == SSH_AGAIN) {
+    /* we would block, we need to wait for the socket to be ready (in the
+       right direction too)! */
+    *block = TRUE;
+  }
+
+  return result;
+}
+
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int myssh_perform_getsock(const struct connectdata *conn,
+                                 curl_socket_t *sock)
+{
+  int bitmap = GETSOCK_BLANK;
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(conn->waitfor & KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(conn->waitfor & KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int myssh_getsock(struct connectdata *conn,
+                         curl_socket_t *sock)
+{
+  /* if we know the direction we can use the generic *_getsock() function even
+     for the protocol_connect and doing states */
+  return myssh_perform_getsock(conn, sock);
+}
+
+static void myssh_block2waitfor(struct connectdata *conn, bool block)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  /* If it didn't block, or nothing was returned by ssh_get_poll_flags
+   * have the original set */
+  conn->waitfor = sshc->orig_waitfor;
+
+  if(block) {
+    int dir = ssh_get_poll_flags(sshc->ssh_session);
+    if(dir & SSH_READ_PENDING) {
+      /* translate the libssh define bits into our own bit defines */
+      conn->waitfor = KEEP_RECV;
+    }
+    else if(dir & SSH_WRITE_PENDING) {
+      conn->waitfor = KEEP_SEND;
+    }
+  }
+}
+
+/* called repeatedly until done from multi.c */
+static CURLcode myssh_multi_statemach(struct connectdata *conn,
+                                      bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  bool block;    /* we store the status and use that to provide a ssh_getsock()
+                    implementation */
+  CURLcode result = myssh_statemach_act(conn, &block);
+
+  *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+  myssh_block2waitfor(conn, block);
+
+  return result;
+}
+
+static CURLcode myssh_block_statemach(struct connectdata *conn,
+                                      bool disconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    timediff_t left = 1000;
+    struct curltime now = Curl_now();
+
+    result = myssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(!disconnect) {
+      if(Curl_pgrsUpdate(conn))
+        return CURLE_ABORTED_BY_CALLBACK;
+
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
+
+      left = Curl_timeleft(data, NULL, FALSE);
+      if(left < 0) {
+        failf(data, "Operation timed out");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
+    }
+
+    if(!result && block) {
+      curl_socket_t fd_read = conn->sock[FIRSTSOCKET];
+      /* wait for the socket to become ready */
+      (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD,
+                               CURL_SOCKET_BAD, left > 1000 ? 1000 : left);
+    }
+
+  }
+
+  return result;
+}
+
+/*
+ * SSH setup connection
+ */
+static CURLcode myssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode myssh_connect(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *ssh;
+  CURLcode result;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct Curl_easy *data = conn->data;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    myssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+
+  ssh = &conn->proto.sshc;
+
+  ssh->ssh_session = ssh_new();
+  if(ssh->ssh_session == NULL) {
+    failf(data, "Failure initialising ssh session");
+    return CURLE_FAILED_INIT;
+  }
+
+  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
+
+  if(conn->user) {
+    infof(data, "User: %s\n", conn->user);
+    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
+  }
+
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]);
+    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS,
+                    data->set.str[STRING_SSH_KNOWNHOSTS]);
+  }
+
+  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
+  if(conn->remote_port)
+    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT,
+                    &conn->remote_port);
+
+  if(data->set.ssh_compression) {
+    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION,
+                    "zlib,zlib@openssh.com,none");
+  }
+
+  ssh->privkey = NULL;
+  ssh->pubkey = NULL;
+
+  if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
+    int rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
+                                        &ssh->pubkey);
+    if(rc != SSH_OK) {
+      failf(data, "Could not load public key file");
+      /* ignore */
+    }
+  }
+
+  /* we do not verify here, we do it at the state machine,
+   * after connection */
+
+  state(conn, SSH_INIT);
+
+  result = myssh_multi_statemach(conn, done);
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result;
+
+  result = myssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+                     bool *connected, bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE;        /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SCP_TRANS_INIT);
+
+  result = myssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE;                /* default to false */
+
+  data->req.size = -1;          /* make sure this is unknown at this point */
+
+  sshc->actualcode = CURLE_OK;  /* reset error code */
+  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
+                                   variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = scp_perform(conn, &connected, done);
+  else
+    result = sftp_perform(conn, &connected, done);
+
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn,
+                               bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void) dead_connection;
+
+  if(ssh->ssh_session) {
+    /* only if there's a session still around to use! */
+
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = myssh_block_statemach(conn, TRUE);
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *protop = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine */
+    result = myssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(protop)
+    Curl_safefree(protop->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0;   /* clear all bits */
+  return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void) premature;             /* not used */
+
+  if(!status)
+    state(conn, SSH_SCP_DONE);
+
+  return myssh_done(conn, status);
+
+}
+
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+                        const void *mem, size_t len, CURLcode *err)
+{
+  int rc;
+  (void) sockindex; /* we only support SCP on the fixed known primary socket */
+  (void) err;
+
+  rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len);
+
+#if 0
+  /* The following code is misleading, mostly added as wishful thinking
+   * that libssh at some point will implement non-blocking ssh_scp_write/read.
+   * Currently rc can only be number of bytes read or SSH_ERROR. */
+  myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE);
+
+  if(rc == SSH_AGAIN) {
+    *err = CURLE_AGAIN;
+    return 0;
+  }
+  else
+#endif
+  if(rc != SSH_OK) {
+    *err = CURLE_SSH;
+    return -1;
+  }
+
+  return len;
+}
+
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+                        char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void) err;
+  (void) sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh returns int */
+  nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len);
+
+#if 0
+  /* The following code is misleading, mostly added as wishful thinking
+   * that libssh at some point will implement non-blocking ssh_scp_write/read.
+   * Currently rc can only be SSH_OK or SSH_ERROR. */
+
+  myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE);
+  if(nread == SSH_AGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+  }
+#endif
+
+  return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = myssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = myssh_multi_statemach(conn, dophase_done);
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void) dead_connection;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = myssh_block_statemach(conn, TRUE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+  return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+                               bool premature)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  if(!status) {
+    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+       errors that could happen due to open file handles during POSTQUOTE
+       operation */
+    if(!premature && conn->data->set.postquote && !conn->bits.retry)
+      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+    state(conn, SSH_SFTP_CLOSE);
+  }
+  return myssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;
+  (void)sockindex;
+
+  nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
+
+  myssh_block2waitfor(conn, FALSE);
+
+#if 0 /* not returned by libssh on write */
+  if(nwrite == SSH_AGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else
+#endif
+  if(nwrite < 0) {
+    *err = CURLE_SSH;
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex;
+
+  DEBUGASSERT(len < CURL_MAX_READ_SIZE);
+
+  switch(conn->proto.sshc.sftp_recv_state) {
+    case 0:
+      conn->proto.sshc.sftp_file_index =
+            sftp_async_read_begin(conn->proto.sshc.sftp_file,
+                                  (uint32_t)len);
+      if(conn->proto.sshc.sftp_file_index < 0) {
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+
+      /* FALLTHROUGH */
+    case 1:
+      conn->proto.sshc.sftp_recv_state = 1;
+
+      nread = sftp_async_read(conn->proto.sshc.sftp_file,
+                              mem, (uint32_t)len,
+                              conn->proto.sshc.sftp_file_index);
+
+      myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE);
+
+      if(nread == SSH_AGAIN) {
+        *err = CURLE_AGAIN;
+        return -1;
+      }
+      else if(nread < 0) {
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+
+      conn->proto.sshc.sftp_recv_state = 0;
+      return nread;
+
+    default:
+      /* we never reach here */
+      return -1;
+  }
+}
+
+static void sftp_quote(struct connectdata *conn)
+{
+  const char *cp;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *protop = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result;
+
+  /*
+   * Support some of the "FTP" commands
+   */
+  char *cmd = sshc->quote_item->data;
+  sshc->acceptfail = FALSE;
+
+  /* if a command starts with an asterisk, which a legal SFTP command never
+     can, the command will be allowed to fail without it causing any
+     aborts or cancels etc. It will cause libcurl to act as if the command
+     is successful, whatever the server reponds. */
+
+  if(cmd[0] == '*') {
+    cmd++;
+    sshc->acceptfail = TRUE;
+  }
+
+  if(strcasecompare("pwd", cmd)) {
+    /* output debug output if that is requested */
+    char *tmp = aprintf("257 \"%s\" is current directory.\n",
+                        protop->path);
+    if(!tmp) {
+      sshc->actualcode = CURLE_OUT_OF_MEMORY;
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      return;
+    }
+    if(data->set.verbose) {
+      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
+      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+    }
+    /* this sends an FTP-like "header" to the header callback so that the
+       current directory can be read very similar to how it is read when
+       using ordinary FTP. */
+    result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+    free(tmp);
+    if(result) {
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+    }
+    else
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+    return;
+  }
+
+  /*
+   * the arguments following the command must be separated from the
+   * command with a space so we can check for it unconditionally
+   */
+  cp = strchr(cmd, ' ');
+  if(cp == NULL) {
+    failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+    state(conn, SSH_SFTP_CLOSE);
+    sshc->nextstate = SSH_NO_STATE;
+    sshc->actualcode = CURLE_QUOTE_ERROR;
+    return;
+  }
+
+  /*
+   * also, every command takes at least one argument so we get that
+   * first argument right now
+   */
+  result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
+  if(result) {
+    if(result == CURLE_OUT_OF_MEMORY)
+      failf(data, "Out of memory");
+    else
+      failf(data, "Syntax error: Bad first parameter");
+    state(conn, SSH_SFTP_CLOSE);
+    sshc->nextstate = SSH_NO_STATE;
+    sshc->actualcode = result;
+    return;
+  }
+
+  /*
+   * SFTP is a binary protocol, so we don't send text commands
+   * to the server. Instead, we scan for commands used by
+   * OpenSSH's sftp program and call the appropriate libssh
+   * functions.
+   */
+  if(strncasecompare(cmd, "chgrp ", 6) ||
+     strncasecompare(cmd, "chmod ", 6) ||
+     strncasecompare(cmd, "chown ", 6)) {
+    /* attribute change */
+
+    /* sshc->quote_path1 contains the mode to set */
+    /* get the destination */
+    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+    if(result) {
+      if(result == CURLE_OUT_OF_MEMORY)
+        failf(data, "Out of memory");
+      else
+        failf(data, "Syntax error in chgrp/chmod/chown: "
+              "Bad second parameter");
+      Curl_safefree(sshc->quote_path1);
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+      return;
+    }
+    sshc->quote_attrs = NULL;
+    state(conn, SSH_SFTP_QUOTE_STAT);
+    return;
+  }
+  if(strncasecompare(cmd, "ln ", 3) ||
+     strncasecompare(cmd, "symlink ", 8)) {
+    /* symbolic linking */
+    /* sshc->quote_path1 is the source */
+    /* get the destination */
+    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+    if(result) {
+      if(result == CURLE_OUT_OF_MEMORY)
+        failf(data, "Out of memory");
+      else
+        failf(data, "Syntax error in ln/symlink: Bad second parameter");
+      Curl_safefree(sshc->quote_path1);
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+      return;
+    }
+    state(conn, SSH_SFTP_QUOTE_SYMLINK);
+    return;
+  }
+  else if(strncasecompare(cmd, "mkdir ", 6)) {
+    /* create dir */
+    state(conn, SSH_SFTP_QUOTE_MKDIR);
+    return;
+  }
+  else if(strncasecompare(cmd, "rename ", 7)) {
+    /* rename file */
+    /* first param is the source path */
+    /* second param is the dest. path */
+    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+    if(result) {
+      if(result == CURLE_OUT_OF_MEMORY)
+        failf(data, "Out of memory");
+      else
+        failf(data, "Syntax error in rename: Bad second parameter");
+      Curl_safefree(sshc->quote_path1);
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+      return;
+    }
+    state(conn, SSH_SFTP_QUOTE_RENAME);
+    return;
+  }
+  else if(strncasecompare(cmd, "rmdir ", 6)) {
+    /* delete dir */
+    state(conn, SSH_SFTP_QUOTE_RMDIR);
+    return;
+  }
+  else if(strncasecompare(cmd, "rm ", 3)) {
+    state(conn, SSH_SFTP_QUOTE_UNLINK);
+    return;
+  }
+#ifdef HAS_STATVFS_SUPPORT
+  else if(strncasecompare(cmd, "statvfs ", 8)) {
+    state(conn, SSH_SFTP_QUOTE_STATVFS);
+    return;
+  }
+#endif
+
+  failf(data, "Unknown SFTP command");
+  Curl_safefree(sshc->quote_path1);
+  Curl_safefree(sshc->quote_path2);
+  state(conn, SSH_SFTP_CLOSE);
+  sshc->nextstate = SSH_NO_STATE;
+  sshc->actualcode = CURLE_QUOTE_ERROR;
+}
+
+static void sftp_quote_stat(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  char *cmd = sshc->quote_item->data;
+  sshc->acceptfail = FALSE;
+
+  /* if a command starts with an asterisk, which a legal SFTP command never
+     can, the command will be allowed to fail without it causing any
+     aborts or cancels etc. It will cause libcurl to act as if the command
+     is successful, whatever the server reponds. */
+
+  if(cmd[0] == '*') {
+    cmd++;
+    sshc->acceptfail = TRUE;
+  }
+
+  /* We read the file attributes, store them in sshc->quote_attrs
+   * and modify them accordingly to command. Then we switch to
+   * QUOTE_SETSTAT state to write new ones.
+   */
+
+  if(sshc->quote_attrs)
+    sftp_attributes_free(sshc->quote_attrs);
+  sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2);
+  if(sshc->quote_attrs == NULL) {
+    Curl_safefree(sshc->quote_path1);
+    Curl_safefree(sshc->quote_path2);
+    failf(data, "Attempt to get SFTP stats failed: %d",
+          sftp_get_error(sshc->sftp_session));
+    state(conn, SSH_SFTP_CLOSE);
+    sshc->nextstate = SSH_NO_STATE;
+    sshc->actualcode = CURLE_QUOTE_ERROR;
+    return;
+  }
+
+  /* Now set the new attributes... */
+  if(strncasecompare(cmd, "chgrp", 5)) {
+    sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
+    if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+        !sshc->acceptfail) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: chgrp gid not a number");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
+  }
+  else if(strncasecompare(cmd, "chmod", 5)) {
+    mode_t perms;
+    perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8);
+    /* permissions are octal */
+    if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: chmod permissions not a number");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->permissions = perms;
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
+  }
+  else if(strncasecompare(cmd, "chown", 5)) {
+    sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
+    if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+        !sshc->acceptfail) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: chown uid not a number");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
+  }
+
+  /* Now send the completed structure... */
+  state(conn, SSH_SFTP_QUOTE_SETSTAT);
+  return;
+}
+
+CURLcode Curl_ssh_init(void)
+{
+  if(ssh_init()) {
+    DEBUGF(fprintf(stderr, "Error: libssh_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+  return CURLE_OK;
+}
+
+void Curl_ssh_cleanup(void)
+{
+  (void)ssh_finalize();
+}
+
+size_t Curl_ssh_version(char *buffer, size_t buflen)
+{
+  return msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION);
+}
+
+#endif                          /* USE_LIBSSH */
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
new file mode 100644
index 0000000000..2b25a514f4
--- /dev/null
+++ b/libs/libcurl/src/vssh/libssh2.c
@@ -0,0 +1,3346 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * 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.
+ *
+ ***************************************************************************/
+
+/* #define CURL_LIBSSH2_DEBUG */
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBSSH2
+
+#include <limits.h>
+
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "strdup.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+#include "curl_path.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+/* libssh2_sftp_statvfs and friends were added in 1.2.6 */
+#define HAS_STATVFS_SUPPORT 1
+#endif
+
+#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
+
+#define sftp_libssh2_realpath(s,p,t,m) \
+        libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
+                                (t), (m), LIBSSH2_SFTP_REALPATH)
+
+
+/* Local functions: */
+static const char *sftp_libssh2_strerror(int err);
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
+static LIBSSH2_FREE_FUNC(my_libssh2_free);
+
+static CURLcode ssh_connect(struct connectdata *conn, bool *done);
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode ssh_do(struct connectdata *conn, bool *done);
+
+static CURLcode scp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn,
+                          bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done);
+static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock);
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock);
+static CURLcode ssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                                /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  scp_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  scp_doing,                            /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  scp_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SCP,                        /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  sftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  sftp_doing,                           /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+static void
+kbd_callback(const char *name, int name_len, const char *instruction,
+             int instruction_len, int num_prompts,
+             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+             void **abstract)
+{
+  struct connectdata *conn = (struct connectdata *)*abstract;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  fprintf(stderr, "name=%s\n", name);
+  fprintf(stderr, "name_len=%d\n", name_len);
+  fprintf(stderr, "instruction=%s\n", instruction);
+  fprintf(stderr, "instruction_len=%d\n", instruction_len);
+  fprintf(stderr, "num_prompts=%d\n", num_prompts);
+#else
+  (void)name;
+  (void)name_len;
+  (void)instruction;
+  (void)instruction_len;
+#endif  /* CURL_LIBSSH2_DEBUG */
+  if(num_prompts == 1) {
+    responses[0].text = strdup(conn->passwd);
+    responses[0].length = curlx_uztoui(strlen(conn->passwd));
+  }
+  (void)prompts;
+  (void)abstract;
+} /* kbd_callback */
+
+static CURLcode sftp_libssh2_error_to_CURLE(int err)
+{
+  switch(err) {
+    case LIBSSH2_FX_OK:
+      return CURLE_OK;
+
+    case LIBSSH2_FX_NO_SUCH_FILE:
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+    case LIBSSH2_FX_WRITE_PROTECT:
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return CURLE_REMOTE_ACCESS_DENIED;
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return CURLE_REMOTE_DISK_FULL;
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return CURLE_REMOTE_FILE_EXISTS;
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return CURLE_QUOTE_ERROR;
+
+    default:
+      break;
+  }
+
+  return CURLE_SSH;
+}
+
+static CURLcode libssh2_session_error_to_CURLE(int err)
+{
+  switch(err) {
+    /* Ordered by order of appearance in libssh2.h */
+    case LIBSSH2_ERROR_NONE:
+      return CURLE_OK;
+
+    /* This is the error returned by libssh2_scp_recv2
+     * on unknown file */
+    case LIBSSH2_ERROR_SCP_PROTOCOL:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case LIBSSH2_ERROR_SOCKET_NONE:
+      return CURLE_COULDNT_CONNECT;
+
+    case LIBSSH2_ERROR_ALLOC:
+      return CURLE_OUT_OF_MEMORY;
+
+    case LIBSSH2_ERROR_SOCKET_SEND:
+      return CURLE_SEND_ERROR;
+
+    case LIBSSH2_ERROR_HOSTKEY_INIT:
+    case LIBSSH2_ERROR_HOSTKEY_SIGN:
+    case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
+    case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
+      return CURLE_PEER_FAILED_VERIFICATION;
+
+    case LIBSSH2_ERROR_PASSWORD_EXPIRED:
+      return CURLE_LOGIN_DENIED;
+
+    case LIBSSH2_ERROR_SOCKET_TIMEOUT:
+    case LIBSSH2_ERROR_TIMEOUT:
+      return CURLE_OPERATION_TIMEDOUT;
+
+    case LIBSSH2_ERROR_EAGAIN:
+      return CURLE_AGAIN;
+  }
+
+  return CURLE_SSH;
+}
+
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
+{
+  (void)abstract; /* arg not used */
+  return malloc(count);
+}
+
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
+{
+  (void)abstract; /* arg not used */
+  return realloc(ptr, count);
+}
+
+static LIBSSH2_FREE_FUNC(my_libssh2_free)
+{
+  (void)abstract; /* arg not used */
+  if(ptr) /* ssh2 agent sometimes call free with null ptr */
+    free(ptr);
+}
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_GSSAPI",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_QUOTE_STATVFS",
+    "SSH_SFTP_GETINFO",
+    "SSH_SFTP_FILETIME",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DOWNLOAD",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+  /* a precaution to make sure the lists are in sync */
+  DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "SFTP %p state change from %s to %s\n",
+          (void *)sshc, names[sshc->state], names[nowstate]);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+static int sshkeycallback(struct Curl_easy *easy,
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch match,
+                          void *clientp)
+{
+  (void)easy;
+  (void)knownkey;
+  (void)foundkey;
+  (void)clientp;
+
+  /* we only allow perfect matches, and we reject everything else */
+  return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
+}
+#endif
+
+/*
+ * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
+ * with 32bit size_t.
+ */
+#ifdef HAVE_LIBSSH2_SFTP_SEEK64
+#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
+#else
+#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
+#endif
+
+/*
+ * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
+ * architectures so we check of the necessary function is present.
+ */
+#ifndef HAVE_LIBSSH2_SCP_SEND64
+#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
+#else
+#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
+                                             (libssh2_uint64_t)d, 0, 0)
+#endif
+
+/*
+ * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
+ */
+#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
+#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
+#endif
+
+static CURLcode ssh_knownhost(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  struct Curl_easy *data = conn->data;
+
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    /* we're asked to verify the host against a file */
+    struct ssh_conn *sshc = &conn->proto.sshc;
+    int rc;
+    int keytype;
+    size_t keylen;
+    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
+                                                    &keylen, &keytype);
+    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
+    int keybit = 0;
+
+    if(remotekey) {
+      /*
+       * A subject to figure out is what host name we need to pass in here.
+       * What host name does OpenSSH store in its file if an IDN name is
+       * used?
+       */
+      struct libssh2_knownhost *host;
+      enum curl_khmatch keymatch;
+      curl_sshkeycallback func =
+        data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
+      struct curl_khkey knownkey;
+      struct curl_khkey *knownkeyp = NULL;
+      struct curl_khkey foundkey;
+
+      keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+        LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+
+#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);
+#else
+      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>");
+
+      /* 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 '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;
+
+      /* 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! */
+      rc = CURLKHSTAT_REJECT;
+
+    switch(rc) {
+    default: /* unknown return codes will equal reject */
+      /* FALLTHROUGH */
+    case CURLKHSTAT_REJECT:
+      state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
+    case CURLKHSTAT_DEFER:
+      /* DEFER means bail out but keep the SSH_HOSTKEY state */
+      result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      break;
+    case CURLKHSTAT_FINE:
+    case CURLKHSTAT_FINE_ADD_TO_FILE:
+      /* proceed */
+      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
+        /* the found host+key didn't match but has been told to be fine
+           anyway so we add it in memory */
+        int addrc = libssh2_knownhost_add(sshc->kh,
+                                          conn->host.name, NULL,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit, NULL);
+        if(addrc)
+          infof(data, "Warning adding the known host %s failed!\n",
+                conn->host.name);
+        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+          /* now we write the entire in-memory list of known hosts to the
+             known_hosts file */
+          int wrc =
+            libssh2_knownhost_writefile(sshc->kh,
+                                        data->set.str[STRING_SSH_KNOWNHOSTS],
+                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+          if(wrc) {
+            infof(data, "Warning, writing %s failed!\n",
+                  data->set.str[STRING_SSH_KNOWNHOSTS]);
+          }
+        }
+      }
+      break;
+    }
+  }
+#else /* HAVE_LIBSSH2_KNOWNHOST_API */
+  (void)conn;
+#endif
+  return result;
+}
+
+static CURLcode ssh_check_fingerprint(struct connectdata *conn)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  struct Curl_easy *data = conn->data;
+  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+  char md5buffer[33];
+
+  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
+      LIBSSH2_HOSTKEY_HASH_MD5);
+
+  if(fingerprint) {
+    /* The fingerprint points to static storage (!), don't free() it. */
+    int i;
+    for(i = 0; i < 16; i++)
+      msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
+    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
+  }
+
+  /* Before we authenticate we check the hostkey's MD5 fingerprint
+   * against a known fingerprint, if available.
+   */
+  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
+    if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
+      if(fingerprint)
+        failf(data,
+            "Denied establishing ssh session: mismatch md5 fingerprint. "
+            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
+      else
+        failf(data,
+            "Denied establishing ssh session: md5 fingerprint not available");
+      state(conn, SSH_SESSION_FREE);
+      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      return sshc->actualcode;
+    }
+    infof(data, "MD5 checksum match!\n");
+    /* as we already matched, we skip the check for known hosts */
+    return CURLE_OK;
+  }
+  return ssh_knownhost(conn);
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+
+static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *sftp_scp = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  char *new_readdir_line;
+  int rc = LIBSSH2_ERROR_NONE;
+  int err;
+  int seekerr = CURL_SEEKFUNC_OK;
+  *block = 0; /* we're not blocking by default */
+
+  do {
+
+    switch(sshc->state) {
+    case SSH_INIT:
+      sshc->secondCreateDirs = 0;
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_OK;
+
+      /* Set libssh2 to non-blocking, since everything internally is
+         non-blocking */
+      libssh2_session_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_S_STARTUP);
+      /* FALLTHROUGH */
+
+    case SSH_S_STARTUP:
+      rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc) {
+        char *err_msg = NULL;
+        (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
+        failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
+
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+
+      state(conn, SSH_HOSTKEY);
+
+      /* FALLTHROUGH */
+    case SSH_HOSTKEY:
+      /*
+       * Before we authenticate we should check the hostkey's fingerprint
+       * against our known hosts. How that is handled (reading from file,
+       * whatever) is up to us.
+       */
+      result = ssh_check_fingerprint(conn);
+      if(!result)
+        state(conn, SSH_AUTHLIST);
+      /* ssh_check_fingerprint sets state appropriately on error */
+      break;
+
+    case SSH_AUTHLIST:
+      /*
+       * Figure out authentication methods
+       * NB: As soon as we have provided a username to an openssh server we
+       * must never change it later. Thus, always specify the correct username
+       * here, even though the libssh2 docs kind of indicate that it should be
+       * possible to get a 'generic' list (not user-specific) of authentication
+       * methods, presumably with a blank username. That won't work in my
+       * experience.
+       * So always specify it here.
+       */
+      sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
+                                             conn->user,
+                                             curlx_uztoui(strlen(conn->user)));
+
+      if(!sshc->authlist) {
+        if(libssh2_userauth_authenticated(sshc->ssh_session)) {
+          sshc->authed = TRUE;
+          infof(data, "SSH user accepted with no authentication\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+        err = libssh2_session_last_errno(sshc->ssh_session);
+        if(err == LIBSSH2_ERROR_EAGAIN)
+          rc = LIBSSH2_ERROR_EAGAIN;
+        else {
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(err);
+        }
+        break;
+      }
+      infof(data, "SSH authentication methods available: %s\n",
+            sshc->authlist);
+
+      state(conn, SSH_AUTH_PKEY_INIT);
+      break;
+
+    case SSH_AUTH_PKEY_INIT:
+      /*
+       * Check the supported auth types in the order I feel is most secure
+       * with the requested type of authentication
+       */
+      sshc->authed = FALSE;
+
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
+         (strstr(sshc->authlist, "publickey") != NULL)) {
+        bool out_of_memory = FALSE;
+
+        sshc->rsa_pub = sshc->rsa = NULL;
+
+        if(data->set.str[STRING_SSH_PRIVATE_KEY])
+          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+        else {
+          /* To ponder about: should really the lib be messing about with the
+             HOME environment variable etc? */
+          char *home = curl_getenv("HOME");
+
+          /* If no private key file is specified, try some common paths. */
+          if(home) {
+            /* Try ~/.ssh first. */
+            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+            if(!sshc->rsa)
+              out_of_memory = TRUE;
+            else if(access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+              if(!sshc->rsa)
+                out_of_memory = TRUE;
+              else if(access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+              }
+            }
+            free(home);
+          }
+          if(!out_of_memory && !sshc->rsa) {
+            /* Nothing found; try the current dir. */
+            sshc->rsa = strdup("id_rsa");
+            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = strdup("id_dsa");
+              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+                /* Out of guesses. Set to the empty string to avoid
+                 * surprising info messages. */
+                sshc->rsa = strdup("");
+              }
+            }
+          }
+        }
+
+        /*
+         * Unless the user explicitly specifies a public key file, let
+         * libssh2 extract the public key from the private key file.
+         * This is done by simply passing sshc->rsa_pub = NULL.
+         */
+        if(data->set.str[STRING_SSH_PUBLIC_KEY]
+           /* treat empty string the same way as NULL */
+           && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
+          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+          if(!sshc->rsa_pub)
+            out_of_memory = TRUE;
+        }
+
+        if(out_of_memory || sshc->rsa == NULL) {
+          Curl_safefree(sshc->rsa);
+          Curl_safefree(sshc->rsa_pub);
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+
+        sshc->passphrase = data->set.ssl.key_passwd;
+        if(!sshc->passphrase)
+          sshc->passphrase = "";
+
+        if(sshc->rsa_pub)
+          infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
+
+        state(conn, SSH_AUTH_PKEY);
+      }
+      else {
+        state(conn, SSH_AUTH_PASS_INIT);
+      }
+      break;
+
+    case SSH_AUTH_PKEY:
+      /* The function below checks if the files exists, no need to stat() here.
+       */
+      rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
+                                                  conn->user,
+                                                  curlx_uztoui(
+                                                    strlen(conn->user)),
+                                                  sshc->rsa_pub,
+                                                  sshc->rsa, sshc->passphrase);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized SSH public key authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        char *err_msg = NULL;
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        infof(data, "SSH public key authentication failed: %s\n", err_msg);
+        state(conn, SSH_AUTH_PASS_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_PASS_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
+         (strstr(sshc->authlist, "password") != NULL)) {
+        state(conn, SSH_AUTH_PASS);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_PASS:
+      rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
+                                        curlx_uztoui(strlen(conn->user)),
+                                        conn->passwd,
+                                        curlx_uztoui(strlen(conn->passwd)),
+                                        NULL);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized password authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_HOST_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
+         (strstr(sshc->authlist, "hostbased") != NULL)) {
+        state(conn, SSH_AUTH_HOST);
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT_INIT);
+      }
+      break;
+
+    case SSH_AUTH_HOST:
+      state(conn, SSH_AUTH_AGENT_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_INIT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
+         && (strstr(sshc->authlist, "publickey") != NULL)) {
+
+        /* Connect to the ssh-agent */
+        /* The agent could be shared by a curl thread i believe
+           but nothing obvious as keys can be added/removed at any time */
+        if(!sshc->ssh_agent) {
+          sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
+          if(!sshc->ssh_agent) {
+            infof(data, "Could not create agent object\n");
+
+            state(conn, SSH_AUTH_KEY_INIT);
+            break;
+          }
+        }
+
+        rc = libssh2_agent_connect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN)
+          break;
+        if(rc < 0) {
+          infof(data, "Failure connecting to agent\n");
+          state(conn, SSH_AUTH_KEY_INIT);
+          rc = 0; /* clear rc and continue */
+        }
+        else {
+          state(conn, SSH_AUTH_AGENT_LIST);
+        }
+      }
+      else
+#endif /* HAVE_LIBSSH2_AGENT_API */
+        state(conn, SSH_AUTH_KEY_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_LIST:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      rc = libssh2_agent_list_identities(sshc->ssh_agent);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+      if(rc < 0) {
+        infof(data, "Failure requesting identities to agent\n");
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT);
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+      break;
+
+    case SSH_AUTH_AGENT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      /* as prev_identity evolves only after an identity user auth finished we
+         can safely request it again as long as EAGAIN is returned here or by
+         libssh2_agent_userauth */
+      rc = libssh2_agent_get_identity(sshc->ssh_agent,
+                                      &sshc->sshagent_identity,
+                                      sshc->sshagent_prev_identity);
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+
+      if(rc == 0) {
+        rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
+                                    sshc->sshagent_identity);
+
+        if(rc < 0) {
+          if(rc != LIBSSH2_ERROR_EAGAIN) {
+            /* tried and failed? go to next identity */
+            sshc->sshagent_prev_identity = sshc->sshagent_identity;
+          }
+          break;
+        }
+      }
+
+      if(rc < 0)
+        infof(data, "Failure requesting identities to agent\n");
+      else if(rc == 1)
+        infof(data, "No identity would match\n");
+
+      if(rc == LIBSSH2_ERROR_NONE) {
+        sshc->authed = TRUE;
+        infof(data, "Agent based authentication successful\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+#endif
+      break;
+
+    case SSH_AUTH_KEY_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
+         && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
+        state(conn, SSH_AUTH_KEY);
+      }
+      else {
+        state(conn, SSH_AUTH_DONE);
+      }
+      break;
+
+    case SSH_AUTH_KEY:
+      /* Authentication failed. Continue with keyboard-interactive now. */
+      rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
+                                                    conn->user,
+                                                    curlx_uztoui(
+                                                      strlen(conn->user)),
+                                                    &kbd_callback);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized keyboard interactive authentication\n");
+      }
+      state(conn, SSH_AUTH_DONE);
+      break;
+
+    case SSH_AUTH_DONE:
+      if(!sshc->authed) {
+        failf(data, "Authentication failure");
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_LOGIN_DENIED;
+        break;
+      }
+
+      /*
+       * At this point we have an authenticated ssh session.
+       */
+      infof(data, "Authentication complete\n");
+
+      Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
+
+      conn->sockfd = sock;
+      conn->writesockfd = CURL_SOCKET_BAD;
+
+      if(conn->handler->protocol == CURLPROTO_SFTP) {
+        state(conn, SSH_SFTP_INIT);
+        break;
+      }
+      infof(data, "SSH CONNECT phase done\n");
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_INIT:
+      /*
+       * Start the libssh2 sftp session
+       */
+      sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
+      if(!sshc->sftp_session) {
+        char *err_msg = NULL;
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        failf(data, "Failure initializing sftp session: %s", err_msg);
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+      state(conn, SSH_SFTP_REALPATH);
+      break;
+
+    case SSH_SFTP_REALPATH:
+    {
+      char tempHome[PATH_MAX];
+
+      /*
+       * Get the "home" directory
+       */
+      rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
+                                 tempHome, PATH_MAX-1);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc > 0) {
+        /* It seems that this string is not always NULL terminated */
+        tempHome[rc] = '\0';
+        sshc->homedir = strdup(tempHome);
+        if(!sshc->homedir) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+        conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+      }
+      else {
+        /* Return the error type */
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        if(err)
+          result = sftp_libssh2_error_to_CURLE(err);
+        else
+          /* in this case, the error wasn't in the SFTP level but for example
+             a time-out or similar */
+          result = CURLE_SSH;
+        sshc->actualcode = result;
+        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+                     err, (int)result));
+        state(conn, SSH_STOP);
+        break;
+      }
+    }
+    /* This is the last step in the SFTP connect phase. Do note that while
+       we get the homedir here, we get the "workingpath" in the DO action
+       since the homedir will remain the same between request but the
+       working path will not. */
+    DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+    state(conn, SSH_STOP);
+    break;
+
+    case SSH_SFTP_QUOTE_INIT:
+
+      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_GETINFO);
+      }
+      break;
+
+    case SSH_SFTP_POSTQUOTE_INIT:
+      if(data->set.postquote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.postquote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SFTP_QUOTE:
+      /* Send any quote commands */
+    {
+      const char *cp;
+
+      /*
+       * Support some of the "FTP" commands
+       *
+       * 'sshc->quote_item' is already verified to be non-NULL before it
+       * switched to this state.
+       */
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(strcasecompare("pwd", cmd)) {
+        /* output debug output if that is requested */
+        char *tmp = aprintf("257 \"%s\" is current directory.\n",
+                            sftp_scp->path);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
+          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+        }
+        /* this sends an FTP-like "header" to the header callback so that the
+           current directory can be read very similar to how it is read when
+           using ordinary FTP. */
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+        else
+          state(conn, SSH_SFTP_NEXT_QUOTE);
+        break;
+      }
+      {
+        /*
+         * the arguments following the command must be separated from the
+         * command with a space so we can check for it unconditionally
+         */
+        cp = strchr(cmd, ' ');
+        if(cp == NULL) {
+          failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+
+        /*
+         * also, every command takes at least one argument so we get that
+         * first argument right now
+         */
+        result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
+        if(result) {
+          if(result == CURLE_OUT_OF_MEMORY)
+            failf(data, "Out of memory");
+          else
+            failf(data, "Syntax error: Bad first parameter");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+          break;
+        }
+
+        /*
+         * SFTP is a binary protocol, so we don't send text commands
+         * to the server. Instead, we scan for commands used by
+         * OpenSSH's sftp program and call the appropriate libssh2
+         * functions.
+         */
+        if(strncasecompare(cmd, "chgrp ", 6) ||
+           strncasecompare(cmd, "chmod ", 6) ||
+           strncasecompare(cmd, "chown ", 6) ) {
+          /* attribute change */
+
+          /* sshc->quote_path1 contains the mode to set */
+          /* get the destination */
+          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in chgrp/chmod/chown: "
+                    "Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+          state(conn, SSH_SFTP_QUOTE_STAT);
+          break;
+        }
+        if(strncasecompare(cmd, "ln ", 3) ||
+           strncasecompare(cmd, "symlink ", 8)) {
+          /* symbolic linking */
+          /* sshc->quote_path1 is the source */
+          /* get the destination */
+          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data,
+                    "Syntax error in ln/symlink: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_SYMLINK);
+          break;
+        }
+        else if(strncasecompare(cmd, "mkdir ", 6)) {
+          /* create dir */
+          state(conn, SSH_SFTP_QUOTE_MKDIR);
+          break;
+        }
+        else if(strncasecompare(cmd, "rename ", 7)) {
+          /* rename file */
+          /* first param is the source path */
+          /* second param is the dest. path */
+          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in rename: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_RENAME);
+          break;
+        }
+        else if(strncasecompare(cmd, "rmdir ", 6)) {
+          /* delete dir */
+          state(conn, SSH_SFTP_QUOTE_RMDIR);
+          break;
+        }
+        else if(strncasecompare(cmd, "rm ", 3)) {
+          state(conn, SSH_SFTP_QUOTE_UNLINK);
+          break;
+        }
+#ifdef HAS_STATVFS_SUPPORT
+        else if(strncasecompare(cmd, "statvfs ", 8)) {
+          state(conn, SSH_SFTP_QUOTE_STATVFS);
+          break;
+        }
+#endif
+
+        failf(data, "Unknown SFTP command");
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+    }
+    break;
+
+    case SSH_SFTP_NEXT_QUOTE:
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      sshc->quote_item = sshc->quote_item->next;
+
+      if(sshc->quote_item) {
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        if(sshc->nextstate != SSH_NO_STATE) {
+          state(conn, sshc->nextstate);
+          sshc->nextstate = SSH_NO_STATE;
+        }
+        else {
+          state(conn, SSH_SFTP_GETINFO);
+        }
+      }
+      break;
+
+    case SSH_SFTP_QUOTE_STAT:
+    {
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(!strncasecompare(cmd, "chmod", 5)) {
+        /* Since chown and chgrp only set owner OR group but libssh2 wants to
+         * set them both at once, we need to obtain the current ownership
+         * first.  This takes an extra protocol round trip.
+         */
+        rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_STAT,
+                                  &sshc->quote_attrs);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Attempt to get SFTP stats failed: %s",
+                sftp_libssh2_strerror(err));
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now set the new attributes... */
+      if(strncasecompare(cmd, "chgrp", 5)) {
+        sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chgrp gid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(strncasecompare(cmd, "chmod", 5)) {
+        sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
+        /* permissions are octal */
+        if(sshc->quote_attrs.permissions == 0 &&
+           !ISDIGIT(sshc->quote_path1[0])) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chmod permissions not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(strncasecompare(cmd, "chown", 5)) {
+        sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chown uid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now send the completed structure... */
+      state(conn, SSH_SFTP_QUOTE_SETSTAT);
+      break;
+    }
+
+    case SSH_SFTP_QUOTE_SETSTAT:
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                curlx_uztoui(strlen(sshc->quote_path2)),
+                                LIBSSH2_SFTP_SETSTAT,
+                                &sshc->quote_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "Attempt to set SFTP stats failed: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_SYMLINK:
+      rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                   curlx_uztoui(strlen(sshc->quote_path1)),
+                                   sshc->quote_path2,
+                                   curlx_uztoui(strlen(sshc->quote_path2)),
+                                   LIBSSH2_SFTP_SYMLINK);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "symlink command failed: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_MKDIR:
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RENAME:
+      rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)),
+                                  sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_RENAME_OVERWRITE |
+                                  LIBSSH2_SFTP_RENAME_ATOMIC |
+                                  LIBSSH2_SFTP_RENAME_NATIVE);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RMDIR:
+      rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_UNLINK:
+      rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+#ifdef HAS_STATVFS_SUPPORT
+    case SSH_SFTP_QUOTE_STATVFS:
+    {
+      LIBSSH2_SFTP_STATVFS statvfs;
+      rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
+                                curlx_uztoui(strlen(sshc->quote_path1)),
+                                &statvfs);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      else if(rc == 0) {
+        char *tmp = aprintf("statvfs:\n"
+                            "f_bsize: %llu\n" "f_frsize: %llu\n"
+                            "f_blocks: %llu\n" "f_bfree: %llu\n"
+                            "f_bavail: %llu\n" "f_files: %llu\n"
+                            "f_ffree: %llu\n" "f_favail: %llu\n"
+                            "f_fsid: %llu\n" "f_flag: %llu\n"
+                            "f_namemax: %llu\n",
+                            statvfs.f_bsize, statvfs.f_frsize,
+                            statvfs.f_blocks, statvfs.f_bfree,
+                            statvfs.f_bavail, statvfs.f_files,
+                            statvfs.f_ffree, statvfs.f_favail,
+                            statvfs.f_fsid, statvfs.f_flag,
+                            statvfs.f_namemax);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+    }
+#endif
+    case SSH_SFTP_GETINFO:
+    {
+      if(data->set.get_filetime) {
+        state(conn, SSH_SFTP_FILETIME);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+    }
+
+    case SSH_SFTP_FILETIME:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        data->info.filetime = attrs.mtime;
+      }
+
+      state(conn, SSH_SFTP_TRANS_INIT);
+      break;
+    }
+
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_UPLOAD_INIT:
+    {
+      unsigned long flags;
+      /*
+       * NOTE!!!  libssh2 requires that the destination path is a full path
+       *          that includes the destination file and name OR ends in a "/"
+       *          If this is not done the destination file will be named the
+       *          same name as the last directory in the path.
+       */
+
+      if(data->state.resume_from != 0) {
+        LIBSSH2_SFTP_ATTRIBUTES attrs;
+        if(data->state.resume_from < 0) {
+          rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                    curlx_uztoui(strlen(sftp_scp->path)),
+                                    LIBSSH2_SFTP_STAT, &attrs);
+          if(rc == LIBSSH2_ERROR_EAGAIN) {
+            break;
+          }
+          if(rc) {
+            data->state.resume_from = 0;
+          }
+          else {
+            curl_off_t size = attrs.filesize;
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              return CURLE_BAD_DOWNLOAD_RESUME;
+            }
+            data->state.resume_from = attrs.filesize;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
+
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             flags, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+
+      if(!sshc->sftp_handle) {
+        rc = libssh2_session_last_errno(sshc->ssh_session);
+
+        if(LIBSSH2_ERROR_EAGAIN == rc)
+          break;
+
+        if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+          /* only when there was an SFTP protocol error can we extract
+             the sftp error! */
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+        else
+          err = -1; /* not an sftp error at all */
+
+        if(sshc->secondCreateDirs) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = err>= LIBSSH2_FX_OK?
+            sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+          failf(data, "Creating the dir/file failed: %s",
+                sftp_libssh2_strerror(err));
+          break;
+        }
+        if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
+            (err == LIBSSH2_FX_FAILURE) ||
+            (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
+           (data->set.ftp_create_missing_dirs &&
+            (strlen(sftp_scp->path) > 1))) {
+          /* try to create the path remotely */
+          rc = 0; /* clear rc and continue */
+          sshc->secondCreateDirs = 1;
+          state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+          break;
+        }
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = err>= LIBSSH2_FX_OK?
+          sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+        if(!sshc->actualcode) {
+          /* Sometimes, for some reason libssh2_sftp_last_error() returns
+             zero even though libssh2_sftp_open() failed previously! We need
+             to work around that! */
+          sshc->actualcode = CURLE_SSH;
+          err = -1;
+        }
+        failf(data, "Upload failed: %s (%d/%d)",
+              err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
+              err, rc);
+        break;
+      }
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        if(conn->seek_func) {
+          Curl_set_in_callback(data, true);
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+          Curl_set_in_callback(data, false);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed = 0;
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > data->set.buffer_size) ?
+              (size_t)data->set.buffer_size :
+              curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread;
+            Curl_set_in_callback(data, true);
+            actuallyread = data->state.fread_func(data->state.buffer, 1,
+                                                  readthisamountnow,
+                                                  data->state.in);
+            Curl_set_in_callback(data, false);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              return CURLE_FTP_COULDNT_USE_REST;
+            }
+          } while(passed < data->state.resume_from);
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 sftp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        /* since we don't really wait for anything at this point, we want the
+           state machine to move on as soon as possible so we set a very short
+           timeout here */
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+        state(conn, SSH_STOP);
+      }
+      break;
+    }
+
+    case SSH_SFTP_CREATE_DIRS_INIT:
+      if(strlen(sftp_scp->path) > 1) {
+        sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
+        state(conn, SSH_SFTP_CREATE_DIRS);
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS:
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
+        *sshc->slash_pos = 0;
+
+        infof(data, "Creating directory '%s'\n", sftp_scp->path);
+        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+        break;
+      }
+      state(conn, SSH_SFTP_UPLOAD_INIT);
+      break;
+
+    case SSH_SFTP_CREATE_DIRS_MKDIR:
+      /* 'mode' - parameter is preliminary - default to 0644 */
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
+                                 curlx_uztoui(strlen(sftp_scp->path)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      *sshc->slash_pos = '/';
+      ++sshc->slash_pos;
+      if(rc < 0) {
+        /*
+         * Abort if failure wasn't that the dir already exists or the
+         * permission was denied (creation might succeed further down the
+         * path) - retry on unspecific FAILURE also
+         */
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
+           (err != LIBSSH2_FX_FAILURE) &&
+           (err != LIBSSH2_FX_PERMISSION_DENIED)) {
+          result = sftp_libssh2_error_to_CURLE(err);
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = result?result:CURLE_SSH;
+          break;
+        }
+        rc = 0; /* clear rc and continue */
+      }
+      state(conn, SSH_SFTP_CREATE_DIRS);
+      break;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /*
+       * This is a directory that we are trying to get, so produce a directory
+       * listing
+       */
+      sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
+                                               sftp_scp->path,
+                                               curlx_uztoui(
+                                                 strlen(sftp_scp->path)),
+                                               0, 0, LIBSSH2_SFTP_OPENDIR);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        failf(data, "Could not open directory for reading: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
+      }
+      sshc->readdir_filename = malloc(PATH_MAX + 1);
+      if(!sshc->readdir_filename) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_longentry = malloc(PATH_MAX + 1);
+      if(!sshc->readdir_longentry) {
+        Curl_safefree(sshc->readdir_filename);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR:
+      rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+                                   sshc->readdir_filename,
+                                   PATH_MAX,
+                                   sshc->readdir_longentry,
+                                   PATH_MAX,
+                                   &sshc->readdir_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc > 0) {
+        sshc->readdir_len = (size_t) rc;
+        sshc->readdir_filename[sshc->readdir_len] = '\0';
+
+        if(data->set.ftp_list_only) {
+          char *tmpLine;
+
+          tmpLine = aprintf("%s\n", sshc->readdir_filename);
+          if(tmpLine == NULL) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     tmpLine, sshc->readdir_len + 1);
+          free(tmpLine);
+
+          if(result) {
+            state(conn, SSH_STOP);
+            break;
+          }
+          /* since this counts what we send to the client, we include the
+             newline in this counter */
+          data->req.bytecount += sshc->readdir_len + 1;
+
+          /* output debug output if that is requested */
+          if(data->set.verbose) {
+            Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
+                       sshc->readdir_len);
+          }
+        }
+        else {
+          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
+          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
+          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
+          if(!sshc->readdir_line) {
+            Curl_safefree(sshc->readdir_filename);
+            Curl_safefree(sshc->readdir_longentry);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+
+          memcpy(sshc->readdir_line, sshc->readdir_longentry,
+                 sshc->readdir_currLen);
+          if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
+             ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
+              LIBSSH2_SFTP_S_IFLNK)) {
+            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
+            if(sshc->readdir_linkPath == NULL) {
+              Curl_safefree(sshc->readdir_filename);
+              Curl_safefree(sshc->readdir_longentry);
+              state(conn, SSH_SFTP_CLOSE);
+              sshc->actualcode = CURLE_OUT_OF_MEMORY;
+              break;
+            }
+
+            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
+                      sshc->readdir_filename);
+            state(conn, SSH_SFTP_READDIR_LINK);
+            break;
+          }
+          state(conn, SSH_SFTP_READDIR_BOTTOM);
+          break;
+        }
+      }
+      else if(rc == 0) {
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_READDIR_DONE);
+        break;
+      }
+      else if(rc < 0) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        failf(data, "Could not open remote file for reading: %s :: %d",
+              sftp_libssh2_strerror(err),
+              libssh2_session_last_errno(sshc->ssh_session));
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        break;
+      }
+      break;
+
+    case SSH_SFTP_READDIR_LINK:
+      rc =
+        libssh2_sftp_symlink_ex(sshc->sftp_session,
+                                sshc->readdir_linkPath,
+                                curlx_uztoui(strlen(sshc->readdir_linkPath)),
+                                sshc->readdir_filename,
+                                PATH_MAX, LIBSSH2_SFTP_READLINK);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      sshc->readdir_len = (size_t) rc;
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* get room for the filename and extra output */
+      sshc->readdir_totalLen += 4 + sshc->readdir_len;
+      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
+                                          sshc->readdir_totalLen);
+      if(!new_readdir_line) {
+        sshc->readdir_line = NULL;
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_line = new_readdir_line;
+
+      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+                                         sshc->readdir_currLen,
+                                         sshc->readdir_totalLen -
+                                         sshc->readdir_currLen,
+                                         " -> %s",
+                                         sshc->readdir_filename);
+
+      state(conn, SSH_SFTP_READDIR_BOTTOM);
+      break;
+
+    case SSH_SFTP_READDIR_BOTTOM:
+      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+                                         sshc->readdir_currLen,
+                                         sshc->readdir_totalLen -
+                                         sshc->readdir_currLen, "\n");
+      result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                 sshc->readdir_line,
+                                 sshc->readdir_currLen);
+
+      if(!result) {
+
+        /* output debug output if that is requested */
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+                     sshc->readdir_currLen);
+        }
+        data->req.bytecount += sshc->readdir_currLen;
+      }
+      Curl_safefree(sshc->readdir_line);
+      if(result) {
+        state(conn, SSH_STOP);
+      }
+      else
+        state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR_DONE:
+      if(libssh2_sftp_closedir(sshc->sftp_handle) ==
+         LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      sshc->sftp_handle = NULL;
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_INIT:
+      /*
+       * Work on getting the specified file
+       */
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             LIBSSH2_FXF_READ, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        failf(data, "Could not open remote file for reading: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
+      }
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_STAT:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc ||
+         !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
+         (attrs.filesize == 0)) {
+        /*
+         * libssh2_sftp_open() didn't return an error, so maybe the server
+         * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
+         */
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+      }
+      else {
+        curl_off_t size = attrs.filesize;
+
+        if(size < 0) {
+          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        if(conn->data->state.use_range) {
+          curl_off_t from, to;
+          char *ptr;
+          char *ptr2;
+          CURLofft to_t;
+          CURLofft from_t;
+
+          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+          if(from_t == CURL_OFFT_FLOW)
+            return CURLE_RANGE_ERROR;
+          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+            ptr++;
+          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
+          if(to_t == CURL_OFFT_FLOW)
+            return CURLE_RANGE_ERROR;
+          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
+             || (to >= size)) {
+            to = size - 1;
+          }
+          if(from_t) {
+            /* from is relative to end of file */
+            from = size - to;
+            to = size - 1;
+          }
+          if(from > size) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          if(from > to) {
+            from = to;
+            size = 0;
+          }
+          else {
+            size = to - from + 1;
+          }
+
+          SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
+        }
+        data->req.size = size;
+        data->req.maxdownload = size;
+        Curl_pgrsSetDownloadSize(data, size);
+      }
+
+      /* We can resume if we can seek to the resume position */
+      if(data->state.resume_from) {
+        if(data->state.resume_from < 0) {
+          /* We're supposed to download the last abs(from) bytes */
+          if((curl_off_t)attrs.filesize < -data->state.resume_from) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          /* download from where? */
+          data->state.resume_from += attrs.filesize;
+        }
+        else {
+          if((curl_off_t)attrs.filesize < data->state.resume_from) {
+            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+        }
+        /* Does a completed file need to be seeked and started or closed ? */
+        /* Now store the number of bytes we are expected to download */
+        data->req.size = attrs.filesize - data->state.resume_from;
+        data->req.maxdownload = attrs.filesize - data->state.resume_from;
+        Curl_pgrsSetDownloadSize(data,
+                                 attrs.filesize - data->state.resume_from);
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+    }
+
+    /* Setup the actual download */
+    if(data->req.size == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      infof(data, "File already completely downloaded\n");
+      state(conn, SSH_STOP);
+      break;
+    }
+    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
+
+    /* not set by Curl_setup_transfer to preserve keepon bits */
+    conn->writesockfd = conn->sockfd;
+
+    /* we want to use the _receiving_ function even when the socket turns
+       out writableable as the underlying libssh2 recv function will deal
+       with both accordingly */
+    conn->cselect_bits = CURL_CSELECT_IN;
+
+    if(result) {
+      /* this should never occur; the close state should be entered
+         at the time the error occurs */
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->actualcode = result;
+    }
+    else {
+      state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SFTP_CLOSE:
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
+        }
+        sshc->sftp_handle = NULL;
+      }
+
+      Curl_safefree(sftp_scp->path);
+
+      DEBUGF(infof(data, "SFTP DONE done\n"));
+
+      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+         After nextstate is executed, the control should come back to
+         SSH_SFTP_CLOSE to pass the correct result back  */
+      if(sshc->nextstate != SSH_NO_STATE &&
+         sshc->nextstate != SSH_SFTP_CLOSE) {
+        state(conn, sshc->nextstate);
+        sshc->nextstate = SSH_SFTP_CLOSE;
+      }
+      else {
+        state(conn, SSH_STOP);
+        result = sshc->actualcode;
+      }
+      break;
+
+    case SSH_SFTP_SHUTDOWN:
+      /* during times we get here due to a broken transfer and then the
+         sftp_handle might not have been taken down so make sure that is done
+         before we proceed */
+
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session, &err_msg,
+                                           NULL, 0);
+          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
+        }
+        sshc->sftp_handle = NULL;
+      }
+      if(sshc->sftp_session) {
+        rc = libssh2_sftp_shutdown(sshc->sftp_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to stop libssh2 sftp subsystem\n");
+        }
+        sshc->sftp_session = NULL;
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      break;
+
+    case SSH_SCP_TRANS_INIT:
+      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.upload) {
+        if(data->state.infilesize < 0) {
+          failf(data, "SCP requires a known file size for upload");
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+          state(conn, SSH_SCP_CHANNEL_FREE);
+          break;
+        }
+        state(conn, SSH_SCP_UPLOAD_INIT);
+      }
+      else {
+        state(conn, SSH_SCP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SCP_UPLOAD_INIT:
+      /*
+       * libssh2 requires that the destination path is a full path that
+       * includes the destination file and name OR ends in a "/" .  If this is
+       * not done the destination file will be named the same name as the last
+       * directory in the path.
+       */
+      sshc->ssh_channel =
+        SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
+                 data->state.infilesize);
+      if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg = NULL;
+
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        /* Map generic errors to upload failed */
+        if(sshc->actualcode == CURLE_SSH ||
+           sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+        break;
+      }
+
+      /* upload data */
+      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 scp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SCP_DOWNLOAD_INIT:
+    {
+      curl_off_t bytecount;
+
+      /*
+       * We must check the remote file; if it is a directory no values will
+       * be set in sb
+       */
+
+      /*
+       * If support for >2GB files exists, use it.
+       */
+
+      /* get a fresh new channel from the ssh layer */
+#if LIBSSH2_VERSION_NUM < 0x010700
+      struct stat sb;
+      memset(&sb, 0, sizeof(struct stat));
+      sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
+                                           sftp_scp->path, &sb);
+#else
+      libssh2_struct_stat sb;
+      memset(&sb, 0, sizeof(libssh2_struct_stat));
+      sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
+                                            sftp_scp->path, &sb);
+#endif
+
+      if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg = NULL;
+
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        break;
+      }
+
+      /* download data */
+      bytecount = (curl_off_t)sb.st_size;
+      data->req.maxdownload =  (curl_off_t)sb.st_size;
+      Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->writesockfd = conn->sockfd;
+
+      /* we want to use the _receiving_ function even when the socket turns
+         out writableable as the underlying libssh2 recv function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_IN;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else
+        state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SCP_DONE:
+      if(data->set.upload)
+        state(conn, SSH_SCP_SEND_EOF);
+      else
+        state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_SEND_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_send_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to send libssh2 channel EOF: %d %s\n",
+                rc, err_msg);
+        }
+      }
+      state(conn, SSH_SCP_WAIT_EOF);
+      break;
+
+    case SSH_SCP_WAIT_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg);
+        }
+      }
+      state(conn, SSH_SCP_WAIT_CLOSE);
+      break;
+
+    case SSH_SCP_WAIT_CLOSE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_closed(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Channel failed to close: %d %s\n", rc, err_msg);
+        }
+      }
+      state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_CHANNEL_FREE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
+                rc, err_msg);
+        }
+        sshc->ssh_channel = NULL;
+      }
+      DEBUGF(infof(data, "SCP DONE phase complete\n"));
+#if 0 /* PREV */
+      state(conn, SSH_SESSION_DISCONNECT);
+#endif
+      state(conn, SSH_STOP);
+      result = sshc->actualcode;
+      break;
+
+    case SSH_SESSION_DISCONNECT:
+      /* during weird times when we've been prematurely aborted, the channel
+         is still alive when we reach this state and we MUST kill the channel
+         properly first */
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
+                rc, err_msg);
+        }
+        sshc->ssh_channel = NULL;
+      }
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to disconnect libssh2 session: %d %s\n",
+                rc, err_msg);
+        }
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_FREE);
+      break;
+
+    case SSH_SESSION_FREE:
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      if(sshc->kh) {
+        libssh2_knownhost_free(sshc->kh);
+        sshc->kh = NULL;
+      }
+#endif
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if(sshc->ssh_agent) {
+        rc = libssh2_agent_disconnect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to disconnect from libssh2 agent: %d %s\n",
+                rc, err_msg);
+        }
+        libssh2_agent_free(sshc->ssh_agent);
+        sshc->ssh_agent = NULL;
+
+        /* NB: there is no need to free identities, they are part of internal
+           agent stuff */
+        sshc->sshagent_identity = NULL;
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_free(sshc->ssh_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg);
+        }
+        sshc->ssh_session = NULL;
+      }
+
+      /* worst-case scenario cleanup */
+
+      DEBUGASSERT(sshc->ssh_session == NULL);
+      DEBUGASSERT(sshc->ssh_channel == NULL);
+      DEBUGASSERT(sshc->sftp_session == NULL);
+      DEBUGASSERT(sshc->sftp_handle == NULL);
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      DEBUGASSERT(sshc->kh == NULL);
+#endif
+#ifdef HAVE_LIBSSH2_AGENT_API
+      DEBUGASSERT(sshc->ssh_agent == NULL);
+#endif
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      Curl_safefree(sshc->homedir);
+
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+      Curl_safefree(sshc->readdir_line);
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* the code we are about to return */
+      result = sshc->actualcode;
+
+      memset(sshc, 0, sizeof(struct ssh_conn));
+
+      connclose(conn, "SSH session free");
+      sshc->state = SSH_SESSION_FREE; /* current */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+    }
+
+  } while(!rc && (sshc->state != SSH_STOP));
+
+  if(rc == LIBSSH2_ERROR_EAGAIN) {
+    /* we would block, we need to wait for the socket to be ready (in the
+       right direction too)! */
+    *block = TRUE;
+  }
+
+  return result;
+}
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock)
+{
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  int bitmap = GETSOCK_BLANK;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(conn->waitfor & KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(conn->waitfor & KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+#else
+  /* if we don't know the direction we can use the generic *_getsock()
+     function even for the protocol_connect and doing states */
+  return Curl_single_getsock(conn, sock);
+#endif
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int ssh_getsock(struct connectdata *conn,
+                       curl_socket_t *sock)
+{
+#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  (void)conn;
+  (void)sock;
+  /* if we don't know any direction we can just play along as we used to and
+     not provide any sensible info */
+  return GETSOCK_BLANK;
+#else
+  /* if we know the direction we can use the generic *_getsock() function even
+     for the protocol_connect and doing states */
+  return ssh_perform_getsock(conn, sock);
+#endif
+}
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+/*
+ * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
+ * function is used to figure out in what direction and stores this info so
+ * that the multi interface can take advantage of it. Make sure to call this
+ * function in all cases so that when it _doesn't_ return EAGAIN we can
+ * restore the default wait bits.
+ */
+static void ssh_block2waitfor(struct connectdata *conn, bool block)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  int dir = 0;
+  if(block) {
+    dir = libssh2_session_block_directions(sshc->ssh_session);
+    if(dir) {
+      /* translate the libssh2 define bits into our own bit defines */
+      conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
+        ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+    }
+  }
+  if(!dir)
+    /* It didn't block or libssh2 didn't reveal in which direction, put back
+       the original set */
+    conn->waitfor = sshc->orig_waitfor;
+}
+#else
+  /* no libssh2 directional support so we simply don't know */
+#define ssh_block2waitfor(x,y) Curl_nop_stmt
+#endif
+
+/* called repeatedly until done from multi.c */
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  bool block; /* we store the status and use that to provide a ssh_getsock()
+                 implementation */
+  do {
+    result = ssh_statemach_act(conn, &block);
+    *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+    /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
+       try again */
+  } while(!result && !*done && !block);
+  ssh_block2waitfor(conn, block);
+
+  return result;
+}
+
+static CURLcode ssh_block_statemach(struct connectdata *conn,
+                                    bool disconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    timediff_t left = 1000;
+    struct curltime now = Curl_now();
+
+    result = ssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(!disconnect) {
+      if(Curl_pgrsUpdate(conn))
+        return CURLE_ABORTED_BY_CALLBACK;
+
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
+
+      left = Curl_timeleft(data, NULL, FALSE);
+      if(left < 0) {
+        failf(data, "Operation timed out");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
+    }
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+    if(!result && block) {
+      int dir = libssh2_session_block_directions(sshc->ssh_session);
+      curl_socket_t sock = conn->sock[FIRSTSOCKET];
+      curl_socket_t fd_read = CURL_SOCKET_BAD;
+      curl_socket_t fd_write = CURL_SOCKET_BAD;
+      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
+        fd_read = sock;
+      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
+        fd_write = sock;
+      /* wait for the socket to become ready */
+      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
+                              left>1000?1000:left); /* ignore result */
+    }
+#endif
+
+  }
+
+  return result;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode ssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode ssh_connect(struct connectdata *conn, bool *done)
+{
+#ifdef CURL_LIBSSH2_DEBUG
+  curl_socket_t sock;
+#endif
+  struct ssh_conn *ssh;
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    ssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+  ssh = &conn->proto.sshc;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  if(conn->user) {
+    infof(data, "User: %s\n", conn->user);
+  }
+  if(conn->passwd) {
+    infof(data, "Password: %s\n", conn->passwd);
+  }
+  sock = conn->sock[FIRSTSOCKET];
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
+                                             my_libssh2_free,
+                                             my_libssh2_realloc, conn);
+  if(ssh->ssh_session == NULL) {
+    failf(data, "Failure initialising ssh session");
+    return CURLE_FAILED_INIT;
+  }
+
+  if(data->set.ssh_compression) {
+#if LIBSSH2_VERSION_NUM >= 0x010208
+    if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
+#endif
+      infof(data, "Failed to enable compression for ssh session\n");
+  }
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    int rc;
+    ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
+    if(!ssh->kh) {
+      libssh2_session_free(ssh->ssh_session);
+      return CURLE_FAILED_INIT;
+    }
+
+    /* read all known hosts from there */
+    rc = libssh2_knownhost_readfile(ssh->kh,
+                                    data->set.str[STRING_SSH_KNOWNHOSTS],
+                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+    if(rc < 0)
+      infof(data, "Failed to read known hosts from %s\n",
+            data->set.str[STRING_SSH_KNOWNHOSTS]);
+  }
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#ifdef CURL_LIBSSH2_DEBUG
+  libssh2_trace(ssh->ssh_session, ~0);
+  infof(data, "SSH socket: %d\n", (int)sock);
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  state(conn, SSH_INIT);
+
+  result = ssh_multi_statemach(conn, done);
+
+  return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SCP_TRANS_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn,
+                               bool *dophase_done)
+{
+  CURLcode result;
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/*
+ * The DO function is generic for both protocols. There was previously two
+ * separate ones but this way means less duplicated code.
+ */
+
+static CURLcode ssh_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE; /* default to false */
+
+  data->req.size = -1; /* make sure this is unknown at this point */
+
+  sshc->actualcode = CURLE_OK; /* reset error code */
+  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
+                                   variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = scp_perform(conn, &connected,  done);
+  else
+    result = sftp_perform(conn, &connected,  done);
+
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void) dead_connection;
+
+  if(ssh->ssh_session) {
+    /* only if there's a session still around to use! */
+
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = ssh_block_statemach(conn, TRUE);
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine */
+    result = ssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(sftp_scp)
+    Curl_safefree(sftp_scp->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0; /* clear all bits */
+  return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void)premature; /* not used */
+
+  if(!status)
+    state(conn, SSH_SCP_DONE);
+
+  return ssh_done(conn, status);
+
+}
+
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+                        const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_write() returns int! */
+  nwrite = (ssize_t)
+    libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+                        char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_read() returns int */
+  nread = (ssize_t)
+    libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+  }
+
+  return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void) dead_connection;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = ssh_block_statemach(conn, TRUE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+  return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+                               bool premature)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  if(!status) {
+    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+       errors that could happen due to open file handles during POSTQUOTE
+       operation */
+    if(!premature && conn->data->set.postquote && !conn->bits.retry)
+      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+    state(conn, SSH_SFTP_CLOSE);
+  }
+  return ssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
+                       but is changed to ssize_t in 0.15. These days we don't
+                       support libssh2 0.15*/
+  (void)sockindex;
+
+  nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex;
+
+  nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+
+  }
+  else if(nread < 0) {
+    *err = libssh2_session_error_to_CURLE((int)nread);
+  }
+  return nread;
+}
+
+static const char *sftp_libssh2_strerror(int err)
+{
+  switch(err) {
+    case LIBSSH2_FX_NO_SUCH_FILE:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+      return "Permission denied";
+
+    case LIBSSH2_FX_FAILURE:
+      return "Operation failed";
+
+    case LIBSSH2_FX_BAD_MESSAGE:
+      return "Bad message from SFTP server";
+
+    case LIBSSH2_FX_NO_CONNECTION:
+      return "Not connected to SFTP server";
+
+    case LIBSSH2_FX_CONNECTION_LOST:
+      return "Connection to SFTP server lost";
+
+    case LIBSSH2_FX_OP_UNSUPPORTED:
+      return "Operation not supported by SFTP server";
+
+    case LIBSSH2_FX_INVALID_HANDLE:
+      return "Invalid handle";
+
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return "File already exists";
+
+    case LIBSSH2_FX_WRITE_PROTECT:
+      return "File is write protected";
+
+    case LIBSSH2_FX_NO_MEDIA:
+      return "No media";
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+      return "Disk full";
+
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return "User quota exceeded";
+
+    case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
+      return "Unknown principle";
+
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return "File lock conflict";
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return "Directory not empty";
+
+    case LIBSSH2_FX_NOT_A_DIRECTORY:
+      return "Not a directory";
+
+    case LIBSSH2_FX_INVALID_FILENAME:
+      return "Invalid filename";
+
+    case LIBSSH2_FX_LINK_LOOP:
+      return "Link points to itself";
+  }
+  return "Unknown error in libssh2";
+}
+
+CURLcode Curl_ssh_init(void)
+{
+#ifdef HAVE_LIBSSH2_INIT
+  if(libssh2_init(0)) {
+    DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
+  return CURLE_OK;
+}
+
+void Curl_ssh_cleanup(void)
+{
+#ifdef HAVE_LIBSSH2_EXIT
+  (void)libssh2_exit();
+#endif
+}
+
+size_t Curl_ssh_version(char *buffer, size_t buflen)
+{
+  return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION);
+}
+
+#endif /* USE_LIBSSH2 */
diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c
index 7ca4f0eac5..9507888bdf 100644
--- a/libs/libcurl/src/vtls/mesalink.c
+++ b/libs/libcurl/src/vtls/mesalink.c
@@ -73,6 +73,17 @@ struct ssl_backend_data
 static Curl_recv mesalink_recv;
 static Curl_send mesalink_send;
 
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  return -1;
+}
+
 /*
  * This function loads all the client/CA certificates and CRLs. Setup the TLS
  * layer and do all necessary magic.
@@ -83,9 +94,6 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
   char *ciphers;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
-  const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile);
-  const char *const ssl_capath = SSL_CONN_CONFIG(CApath);
   struct in_addr addr4;
 #ifdef ENABLE_IPV6
   struct in6_addr addr6;
@@ -142,21 +150,25 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
   }
 
   SSL_CTX_set_verify(
-    BACKEND->ctx, verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
+    BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ?
+      SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
 
-  if(ssl_cafile || ssl_capath) {
-    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) {
-      if(verifypeer) {
+  if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) {
+    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile),
+                                                    SSL_CONN_CONFIG(CApath))) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data,
               "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
-              ssl_cafile ? ssl_cafile : "none",
-              ssl_capath ? ssl_capath : "none");
+              SSL_CONN_CONFIG(CAfile) ?
+              SSL_CONN_CONFIG(CAfile) : "none",
+              SSL_CONN_CONFIG(CApath) ?
+              SSL_CONN_CONFIG(CApath) : "none");
         return CURLE_SSL_CACERT_BADFILE;
       }
       infof(data,
-            "error setting certificate verify locations,"
-            " continuing anyway:\n");
+          "error setting certificate verify locations,"
+          " continuing anyway:\n");
     }
     else {
       infof(data, "successfully set certificate verify locations:\n");
@@ -164,8 +176,32 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
     infof(data,
           "  CAfile: %s\n"
           "  CApath: %s\n",
-          ssl_cafile ? ssl_cafile : "none",
-          ssl_capath ? ssl_capath : "none");
+          SSL_CONN_CONFIG(CAfile)?
+          SSL_CONN_CONFIG(CAfile): "none",
+          SSL_CONN_CONFIG(CApath)?
+          SSL_CONN_CONFIG(CApath): "none");
+  }
+
+  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+    int file_type = do_file_type(SSL_SET_OPTION(cert_type));
+
+    if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, SSL_SET_OPTION(cert),
+                                     file_type) != 1) {
+      failf(data, "unable to use client certificate (no key or wrong pass"
+            " phrase?)");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    file_type = do_file_type(SSL_SET_OPTION(key_type));
+    if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
+                                    file_type) != 1) {
+      failf(data, "unable to set private key");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    infof(data,
+          "client cert: %s\n",
+          SSL_CONN_CONFIG(clientcert)?
+          SSL_CONN_CONFIG(clientcert): "none");
   }
 
   ciphers = SSL_CONN_CONFIG(cipher_list);
diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c
index 482fd5e99a..435f3e93a1 100644
--- a/libs/libcurl/src/vtls/nss.c
+++ b/libs/libcurl/src/vtls/nss.c
@@ -1734,20 +1734,16 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
   CURLcode result;
   const long min = SSL_CONN_CONFIG(version);
   const long max = SSL_CONN_CONFIG(version_max);
-
-  /* map CURL_SSLVERSION_DEFAULT to NSS default */
-  if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) {
-    /* map CURL_SSLVERSION_DEFAULT to NSS default */
-    if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
-      return CURLE_SSL_CONNECT_ERROR;
-    /* ... but make sure we use at least TLSv1.0 according to libcurl API */
-    if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
-      sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
-  }
+  SSLVersionRange vrange;
 
   switch(min) {
   case CURL_SSLVERSION_TLSv1:
   case CURL_SSLVERSION_DEFAULT:
+    /* Bump our minimum TLS version if NSS has stricter requirements. */
+    if(SSL_VersionRangeGetDefault(ssl_variant_stream, &vrange) != SECSuccess)
+      return CURLE_SSL_CONNECT_ERROR;
+    if(sslver->min < vrange.min)
+      sslver->min = vrange.min;
     break;
   default:
     result = nss_sslver_from_curl(&sslver->min, min);
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index fb9f27123e..385f281793 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -25,11 +25,6 @@
  * but vtls.c should ever call or use these functions.
  */
 
-/*
- * The original SSLeay-using code for curl was written by Linas Vepstas and
- * Sampo Kellomaki 1998.
- */
-
 #include "curl_setup.h"
 
 #ifdef USE_OPENSSL
@@ -396,7 +391,11 @@ static const char *SSL_ERROR_to_str(int err)
  */
 static char *ossl_strerror(unsigned long error, char *buf, size_t size)
 {
+#ifdef OPENSSL_IS_BORINGSSL
+  ERR_error_string_n((uint32_t)error, buf, size);
+#else
   ERR_error_string_n(error, buf, size);
+#endif
   return buf;
 }
 
@@ -1534,8 +1533,13 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
   altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
 
   if(altnames) {
+#ifdef OPENSSL_IS_BORINGSSL
+    size_t numalts;
+    size_t i;
+#else
     int numalts;
     int i;
+#endif
     bool dnsmatched = FALSE;
     bool ipmatched = FALSE;
 
@@ -1565,11 +1569,10 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
              assumed that the data returned by ASN1_STRING_data() is null
              terminated or does not contain embedded nulls." But also that
              "The actual format of the data will depend on the actual string
-             type itself: for example for and IA5String the data will be ASCII"
+             type itself: for example for an IA5String the data will be ASCII"
 
-             Gisle researched the OpenSSL sources:
-             "I checked the 0.9.6 and 0.9.8 sources before my patch and
-             it always 0-terminates an IA5String."
+             It has been however verified that in 0.9.6 and 0.9.7, IA5String
+             is always zero-terminated.
           */
           if((altlen == strlen(altptr)) &&
              /* if this isn't true, there was an embedded zero in the name
@@ -1633,8 +1636,7 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
       /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
          is already UTF-8 encoded. We check for this case and copy the raw
          string manually to avoid the problem. This code can be made
-         conditional in the future when OpenSSL has been fixed. Work-around
-         brought by Alexis S. L. Carvalho. */
+         conditional in the future when OpenSSL has been fixed. */
       if(tmp) {
         if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
           j = ASN1_STRING_length(tmp);
@@ -2154,9 +2156,96 @@ get_ssl_version_txt(SSL *ssl)
 }
 #endif
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
+static CURLcode
+set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
+{
+  /* first, TLS min version... */
+  long curl_ssl_version_min = SSL_CONN_CONFIG(version);
+  long curl_ssl_version_max;
+
+  /* convert cURL min SSL version option to OpenSSL constant */
+  long ossl_ssl_version_min = 0;
+  long ossl_ssl_version_max = 0;
+  switch(curl_ssl_version_min) {
+    case CURL_SSLVERSION_TLSv1: /* TLS 1.x */
+    case CURL_SSLVERSION_TLSv1_0:
+      ossl_ssl_version_min = TLS1_VERSION;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      ossl_ssl_version_min = TLS1_1_VERSION;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      ossl_ssl_version_min = TLS1_2_VERSION;
+      break;
+#ifdef TLS1_3_VERSION
+    case CURL_SSLVERSION_TLSv1_3:
+      ossl_ssl_version_min = TLS1_3_VERSION;
+      break;
+#endif
+  }
+
+  /* CURL_SSLVERSION_DEFAULT means that no option was selected.
+    We don't want to pass 0 to SSL_CTX_set_min_proto_version as
+    it would enable all versions down to the lowest supported by
+    the library.
+    So we skip this, and stay with the OS default
+  */
+  if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) {
+    if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) {
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* ... then, TLS max version */
+  curl_ssl_version_max = SSL_CONN_CONFIG(version_max);
+
+  /* convert cURL max SSL version option to OpenSSL constant */
+  ossl_ssl_version_max = 0;
+  switch(curl_ssl_version_max) {
+    case CURL_SSLVERSION_MAX_TLSv1_0:
+      ossl_ssl_version_max = TLS1_VERSION;
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_1:
+      ossl_ssl_version_max = TLS1_1_VERSION;
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_2:
+      ossl_ssl_version_max = TLS1_2_VERSION;
+      break;
+#ifdef TLS1_3_VERSION
+    case CURL_SSLVERSION_MAX_TLSv1_3:
+      ossl_ssl_version_max = TLS1_3_VERSION;
+      break;
+#endif
+    case CURL_SSLVERSION_MAX_NONE:  /* none selected */
+    case CURL_SSLVERSION_MAX_DEFAULT:  /* max selected */
+    default:
+      /* SSL_CTX_set_max_proto_version states that:
+        setting the maximum to 0 will enable
+        protocol versions up to the highest version
+        supported by the library */
+      ossl_ssl_version_max = 0;
+      break;
+  }
+
+  if(!SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) {
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  return CURLE_OK;
+}
+#endif
+
+#ifdef OPENSSL_IS_BORINGSSL
+typedef uint32_t ctx_option_t;
+#else
+typedef long ctx_option_t;
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
 static CURLcode
-set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
-                        int sockindex)
+set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
+                              struct connectdata *conn, int sockindex)
 {
 #if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION)
   /* convoluted #if condition just to avoid compiler warnings on unused
@@ -2228,6 +2317,7 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
   }
   return CURLE_OK;
 }
+#endif
 
 /* The "new session" callback must return zero if the session can be removed
  * or non-zero if the session has been put into the session cache.
@@ -2294,7 +2384,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   X509_LOOKUP *lookup = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  long ctx_options = 0;
+  ctx_option_t ctx_options = 0;
+
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
   bool sni;
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
@@ -2457,48 +2548,66 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
 #endif
 
   switch(ssl_version) {
-  case CURL_SSLVERSION_SSLv3:
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_TLSv1;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
-#endif
+    /* "--sslv2" option means SSLv2 only, disable all others */
+    case CURL_SSLVERSION_SSLv2:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
+      SSL_CTX_set_min_proto_version(BACKEND->ctx, SSL2_VERSION);
+      SSL_CTX_set_max_proto_version(BACKEND->ctx, SSL2_VERSION);
+#else
+      ctx_options |= SSL_OP_NO_SSLv3;
+      ctx_options |= SSL_OP_NO_TLSv1;
+#  if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      ctx_options |= SSL_OP_NO_TLSv1_1;
+      ctx_options |= SSL_OP_NO_TLSv1_2;
+#    ifdef TLS1_3_VERSION
+      ctx_options |= SSL_OP_NO_TLSv1_3;
+#    endif
+#  endif
 #endif
-    break;
-
-  case CURL_SSLVERSION_DEFAULT:
-  case CURL_SSLVERSION_TLSv1:
-  case CURL_SSLVERSION_TLSv1_0:
-  case CURL_SSLVERSION_TLSv1_1:
-  case CURL_SSLVERSION_TLSv1_2:
-  case CURL_SSLVERSION_TLSv1_3:
-    /* asking for any TLS version as the minimum, means no SSL versions
-       allowed */
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_SSLv3;
-    result = set_ssl_version_min_max(&ctx_options, conn, sockindex);
-    if(result != CURLE_OK)
-       return result;
-    break;
+      break;
 
-  case CURL_SSLVERSION_SSLv2:
-    ctx_options |= SSL_OP_NO_SSLv3;
-    ctx_options |= SSL_OP_NO_TLSv1;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
+    /* "--sslv3" option means SSLv3 only, disable all others */
+    case CURL_SSLVERSION_SSLv3:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
+      SSL_CTX_set_min_proto_version(BACKEND->ctx, SSL3_VERSION);
+      SSL_CTX_set_max_proto_version(BACKEND->ctx, SSL3_VERSION);
+#else
+      ctx_options |= SSL_OP_NO_SSLv2;
+      ctx_options |= SSL_OP_NO_TLSv1;
+#  if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      ctx_options |= SSL_OP_NO_TLSv1_1;
+      ctx_options |= SSL_OP_NO_TLSv1_2;
+#    ifdef TLS1_3_VERSION
+      ctx_options |= SSL_OP_NO_TLSv1_3;
+#    endif
+#  endif
 #endif
+      break;
+
+    /* "--tlsv<x.y>" options mean TLS >= version <x.y> */
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */
+    case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */
+    case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */
+    case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */
+    case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */
+      /* asking for any TLS version as the minimum, means no SSL versions
+        allowed */
+      ctx_options |= SSL_OP_NO_SSLv2;
+      ctx_options |= SSL_OP_NO_SSLv3;
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
+      result = set_ssl_version_min_max(BACKEND->ctx, conn);
+#else
+      result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex);
 #endif
-    break;
+      if(result != CURLE_OK)
+        return result;
+      break;
 
-  default:
-    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
-    return CURLE_SSL_CONNECT_ERROR;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
   }
 
   SSL_CTX_set_options(BACKEND->ctx, ctx_options);
@@ -2654,11 +2763,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   }
 
   /* 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
+     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) {
@@ -3038,6 +3147,12 @@ static int X509V3_ext(struct Curl_easy *data,
   return 0; /* all is fine */
 }
 
+#ifdef OPENSSL_IS_BORINGSSL
+typedef size_t numcert_t;
+#else
+typedef int numcert_t;
+#endif
+
 static CURLcode get_cert_chain(struct connectdata *conn,
                                struct ssl_connect_data *connssl)
 
@@ -3046,7 +3161,7 @@ static CURLcode get_cert_chain(struct connectdata *conn,
   STACK_OF(X509) *sk;
   int i;
   struct Curl_easy *data = conn->data;
-  int numcerts;
+  numcert_t numcerts;
   BIO *mem;
 
   sk = SSL_get_peer_cert_chain(BACKEND->handle);
@@ -3056,14 +3171,14 @@ static CURLcode get_cert_chain(struct connectdata *conn,
 
   numcerts = sk_X509_num(sk);
 
-  result = Curl_ssl_init_certinfo(data, numcerts);
+  result = Curl_ssl_init_certinfo(data, (int)numcerts);
   if(result) {
     return result;
   }
 
   mem = BIO_new(BIO_s_mem());
 
-  for(i = 0; i < numcerts; i++) {
+  for(i = 0; i < (int)numcerts; i++) {
     ASN1_INTEGER *num;
     X509 *x = sk_X509_value(sk, i);
     EVP_PKEY *pubkey = NULL;
diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c
index 6a0e60fb6c..422819899e 100644
--- a/libs/libcurl/src/vtls/vtls.c
+++ b/libs/libcurl/src/vtls/vtls.c
@@ -515,14 +515,10 @@ 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)
-int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
-                     int numsocks)
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
 
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   if(connssl->connecting_state == ssl_connect_2_writing) {
     /* write mode */
     socks[0] = conn->sock[FIRSTSOCKET];
@@ -538,12 +534,10 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
 }
 #else
 int Curl_ssl_getsock(struct connectdata *conn,
-                     curl_socket_t *socks,
-                     int numsocks)
+                     curl_socket_t *socks)
 {
   (void)conn;
   (void)socks;
-  (void)numsocks;
   return GETSOCK_BLANK;
 }
 /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */
diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h
index 173d360de8..61d8416c29 100644
--- a/libs/libcurl/src/vtls/vtls.h
+++ b/libs/libcurl/src/vtls/vtls.h
@@ -143,8 +143,7 @@ bool Curl_ssl_config_matches(struct ssl_primary_config* data,
 bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
                                    struct ssl_primary_config *dest);
 void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc);
-int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
-                     int numsocks);
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
 
 int Curl_ssl_backend(void);
 
-- 
cgit v1.2.3