summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-05-22 16:37:08 +0000
committerng0 <ng0@n0.is>2019-05-22 16:37:08 +0000
commit76775eb29a045f4354ef7138deaf2e1721708dd4 (patch)
tree48e9517d65525dac2eeb54baac0e37bce9b58ca1 /lib
parenta341c3159eaeb4a6386fc3360f8d082e25b26ec3 (diff)
parent885ce31401b6789c959131754b1e5ae518964072 (diff)
downloadgnurl-76775eb29a045f4354ef7138deaf2e1721708dd4.tar.gz
gnurl-76775eb29a045f4354ef7138deaf2e1721708dd4.tar.bz2
gnurl-76775eb29a045f4354ef7138deaf2e1721708dd4.zip
Merge tag 'curl-7_65_0' of https://github.com/curl/curl
7.65.0
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.inc8
-rw-r--r--lib/altsvc.c12
-rw-r--r--lib/asyn-ares.c105
-rw-r--r--lib/base64.c9
-rw-r--r--lib/config-win32.h5
-rw-r--r--lib/conncache.c5
-rw-r--r--lib/conncache.h3
-rw-r--r--lib/connect.c34
-rw-r--r--lib/cookie.c50
-rw-r--r--lib/cookie.h1
-rw-r--r--lib/curl_config.h.cmake10
-rw-r--r--lib/curl_fnmatch.c9
-rw-r--r--lib/curl_get_line.c55
-rw-r--r--lib/curl_get_line.h29
-rw-r--r--lib/curl_md4.h4
-rw-r--r--lib/curl_md5.h10
-rw-r--r--lib/curl_memory.h4
-rw-r--r--lib/curl_ntlm_core.c6
-rw-r--r--lib/curl_ntlm_core.h4
-rw-r--r--lib/curl_ntlm_wb.c71
-rw-r--r--lib/curl_ntlm_wb.h11
-rw-r--r--lib/curl_path.c2
-rw-r--r--lib/curl_sasl.c33
-rw-r--r--lib/curl_setup.h4
-rw-r--r--lib/doh.c11
-rw-r--r--lib/doh.h10
-rw-r--r--lib/easy.c16
-rw-r--r--lib/fileinfo.c5
-rw-r--r--lib/formdata.c14
-rw-r--r--lib/formdata.h11
-rw-r--r--lib/ftp.c9
-rw-r--r--lib/ftplistparser.c5
-rw-r--r--lib/hostcheck.c6
-rw-r--r--lib/hostip.c46
-rw-r--r--lib/hostip.h7
-rw-r--r--lib/hostip6.c5
-rw-r--r--lib/http.c134
-rw-r--r--lib/http2.c12
-rw-r--r--lib/http_digest.c5
-rw-r--r--lib/http_digest.h12
-rw-r--r--lib/http_negotiate.c50
-rw-r--r--lib/http_negotiate.h6
-rw-r--r--lib/http_ntlm.c37
-rw-r--r--lib/http_ntlm.h10
-rw-r--r--lib/if2ip.c23
-rw-r--r--lib/if2ip.h4
-rw-r--r--lib/imap.c14
-rw-r--r--lib/inet_pton.c3
-rw-r--r--lib/ldap.c3
-rw-r--r--lib/md4.c113
-rw-r--r--lib/md5.c163
-rw-r--r--lib/memdebug.c7
-rw-r--r--lib/mime.c80
-rw-r--r--lib/mime.h20
-rw-r--r--lib/multi.c318
-rw-r--r--lib/multihandle.h48
-rw-r--r--lib/multiif.h17
-rw-r--r--lib/netrc.c5
-rw-r--r--lib/netrc.h9
-rw-r--r--lib/openldap.c5
-rw-r--r--lib/parsedate.c41
-rw-r--r--lib/pipeline.c404
-rw-r--r--lib/pipeline.h56
-rw-r--r--lib/pop3.c1
-rw-r--r--lib/progress.c114
-rw-r--r--lib/rtsp.c13
-rw-r--r--lib/security.c13
-rw-r--r--lib/sendf.c40
-rw-r--r--lib/setopt.c261
-rw-r--r--lib/smtp.c10
-rw-r--r--lib/socks.c22
-rw-r--r--lib/splay.c4
-rw-r--r--lib/ssh-libssh.c19
-rw-r--r--lib/ssh.c26
-rw-r--r--lib/tftp.c2
-rw-r--r--lib/timeval.c2
-rw-r--r--lib/transfer.c104
-rw-r--r--lib/url.c664
-rw-r--r--lib/url.h9
-rw-r--r--lib/urlapi-int.h7
-rw-r--r--lib/urlapi.c106
-rw-r--r--lib/urldata.h87
-rw-r--r--lib/vauth/cleartext.c40
-rw-r--r--lib/vauth/digest.c5
-rw-r--r--lib/vauth/krb5_gssapi.c6
-rw-r--r--lib/vauth/krb5_sspi.c6
-rw-r--r--lib/vauth/ntlm.c24
-rw-r--r--lib/vauth/ntlm_sspi.c8
-rw-r--r--lib/vauth/oauth2.c56
-rw-r--r--lib/vauth/spnego_gssapi.c9
-rw-r--r--lib/vauth/spnego_sspi.c7
-rw-r--r--lib/vauth/vauth.c42
-rw-r--r--lib/vauth/vauth.h20
-rw-r--r--lib/version.c10
-rw-r--r--lib/vtls/cyassl.c5
-rw-r--r--lib/vtls/gskit.c18
-rw-r--r--lib/vtls/gtls.c49
-rw-r--r--lib/vtls/mbedtls.c17
-rw-r--r--lib/vtls/mesalink.c2
-rw-r--r--lib/vtls/nss.c18
-rw-r--r--lib/vtls/openssl.c20
-rw-r--r--lib/vtls/polarssl.c9
-rw-r--r--lib/vtls/polarssl_threadlock.c59
-rw-r--r--lib/vtls/polarssl_threadlock.h9
-rw-r--r--lib/vtls/schannel.c20
-rw-r--r--lib/vtls/sectransp.c7
-rw-r--r--lib/vtls/vtls.c31
-rw-r--r--lib/wildcard.c6
-rw-r--r--lib/wildcard.h10
-rw-r--r--lib/x509asn1.c17
110 files changed, 1889 insertions, 2373 deletions
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 6c47bcda5..235b82b0e 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -52,10 +52,10 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
openldap.c curl_gethostname.c gopher.c idn_win32.c \
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
- curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
+ curl_multibyte.c hostcheck.c conncache.c dotdot.c \
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
- doh.c urlapi.c altsvc.c
+ doh.c urlapi.c curl_get_line.c altsvc.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
@@ -72,11 +72,11 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
- curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
+ curl_setup_once.h multihandle.h setup-vms.h dotdot.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 \
- altsvc.h
+ curl_get_line.h altsvc.h
LIB_RCFILES = libcurl.rc
diff --git a/lib/altsvc.c b/lib/altsvc.c
index 3bde72c2a..73cd5d734 100644
--- a/lib/altsvc.c
+++ b/lib/altsvc.c
@@ -29,7 +29,7 @@
#include <gnurl/curl.h>
#include "urldata.h"
#include "altsvc.h"
-#include "cookie.h" /* for Curl_get_line() */
+#include "curl_get_line.h"
#include "strcase.h"
#include "parsedate.h"
#include "sendf.h"
@@ -253,7 +253,6 @@ struct altsvcinfo *Curl_altsvc_init(void)
| CURLALTSVC_H2
#endif
#ifdef USE_HTTP3
- /* TODO: adjust when known */
| CURLALTSVC_H3
#endif
;
@@ -349,7 +348,7 @@ static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
len = p - protop;
if(!len || (len >= buflen))
- return CURLE_BAD_FUNCTION_ARGUMENT; /* TODO: improve error code */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
memcpy(alpnbuf, protop, len);
alpnbuf[len] = 0;
*ptr = p;
@@ -425,7 +424,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
/* "clear" is a magic keyword */
if(strcasecompare(alpnbuf, "clear")) {
- /* TODO: clear whatever it is it should clear */
return CURLE_OK;
}
@@ -478,7 +476,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
p++;
len = p - hostp;
if(!len || (len >= MAX_ALTSVC_HOSTLEN))
- return CURLE_BAD_FUNCTION_ARGUMENT; /* TODO: improve error code */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
memcpy(namebuf, hostp, len);
namebuf[len] = 0;
dsthost = namebuf;
@@ -504,8 +502,8 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
srcalpnid, dstalpnid,
srcport, dstport);
if(as) {
- /* TODO: the expires time also needs to take the Age: value (if any)
- into account. [See RFC 7838 section 3.1] */
+ /* The expires time also needs to take the Age: value (if any) into
+ account. [See RFC 7838 section 3.1] */
as->expires = maxage + time(NULL);
as->persist = persist;
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index 04a25b321..8561a4724 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -68,7 +68,7 @@
#include "progress.h"
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
- (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+ (defined(WIN32) || defined(__SYMBIAN32__))
# define CARES_STATICLIB
# endif
# include <ares.h>
@@ -89,8 +89,20 @@ struct ResolverResults {
int num_pending; /* number of ares_gethostbyname() requests */
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
int last_status;
+ struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
};
+/* How long we are willing to wait for additional parallel responses after
+ obtaining a "definitive" one.
+
+ This is intended to equal the c-ares default timeout. cURL always uses that
+ default value. Unfortunately, c-ares doesn't expose its default timeout in
+ its API, but it is officially documented as 5 seconds.
+
+ See query_completed_cb() for an explanation of how this is used.
+ */
+#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000
+
/*
* Curl_resolver_global_init() - the generic low-level asynchronous name
* resolve API. Called from curl_global_init() to initialize global resolver
@@ -319,9 +331,9 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
/* move through the descriptors and ask for processing on them */
for(i = 0; i < num; i++)
ares_process_fd((ares_channel)data->state.resolver,
- pfd[i].revents & (POLLRDNORM|POLLIN)?
+ (pfd[i].revents & (POLLRDNORM|POLLIN))?
pfd[i].fd:ARES_SOCKET_BAD,
- pfd[i].revents & (POLLWRNORM|POLLOUT)?
+ (pfd[i].revents & (POLLWRNORM|POLLOUT))?
pfd[i].fd:ARES_SOCKET_BAD);
}
return nfds;
@@ -347,6 +359,29 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
waitperform(conn, 0);
+ /* Now that we've checked for any last minute results above, see if there are
+ any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
+ expires. */
+ if(res
+ && res->num_pending
+ /* This is only set to non-zero if the timer was started. */
+ && (res->happy_eyeballs_dns_time.tv_sec
+ || res->happy_eyeballs_dns_time.tv_usec)
+ && (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time)
+ >= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
+ /* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
+ running. */
+ memset(
+ &res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time));
+
+ /* Cancel the raw c-ares request, which will fire query_completed_cb() with
+ ARES_ECANCELLED synchronously for all pending responses. This will
+ leave us with res->num_pending == 0, which is perfect for the next
+ block. */
+ ares_cancel((ares_channel)data->state.resolver);
+ DEBUGASSERT(res->num_pending == 0);
+ }
+
if(res && !res->num_pending) {
if(dns) {
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
@@ -455,9 +490,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
if(result)
/* close the connection, since we can't return failure here without
- cleaning up this connection properly.
- TODO: remove this action from here, it is not a name resolver decision.
- */
+ cleaning up this connection properly. */
connclose(conn, "c-ares resolve failed");
return result;
@@ -517,6 +550,66 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
/* A successful result overwrites any previous error */
if(res->last_status != ARES_SUCCESS)
res->last_status = status;
+
+ /* If there are responses still pending, we presume they must be the
+ complementary IPv4 or IPv6 lookups that we started in parallel in
+ Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a
+ "definitive" response from one of a set of parallel queries, we need to
+ think about how long we're willing to wait for more responses. */
+ if(res->num_pending
+ /* Only these c-ares status values count as "definitive" for these
+ purposes. For example, ARES_ENODATA is what we expect when there is
+ no IPv6 entry for a domain name, and that's not a reason to get more
+ aggressive in our timeouts for the other response. Other errors are
+ either a result of bad input (which should affect all parallel
+ requests), local or network conditions, non-definitive server
+ responses, or us cancelling the request. */
+ && (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) {
+ /* Right now, there can only be up to two parallel queries, so don't
+ bother handling any other cases. */
+ DEBUGASSERT(res->num_pending == 1);
+
+ /* It's possible that one of these parallel queries could succeed
+ quickly, but the other could always fail or timeout (when we're
+ talking to a pool of DNS servers that can only successfully resolve
+ IPv4 address, for example).
+
+ It's also possible that the other request could always just take
+ longer because it needs more time or only the second DNS server can
+ fulfill it successfully. But, to align with the philosophy of Happy
+ Eyeballs, we don't want to wait _too_ long or users will think
+ requests are slow when IPv6 lookups don't actually work (but IPv4 ones
+ do).
+
+ So, now that we have a usable answer (some IPv4 addresses, some IPv6
+ addresses, or "no such domain"), we start a timeout for the remaining
+ pending responses. Even though it is typical that this resolved
+ request came back quickly, that needn't be the case. It might be that
+ this completing request didn't get a result from the first DNS server
+ or even the first round of the whole DNS server pool. So it could
+ already be quite some time after we issued the DNS queries in the
+ first place. Without modifying c-ares, we can't know exactly where in
+ its retry cycle we are. We could guess based on how much time has
+ gone by, but it doesn't really matter. Happy Eyeballs tells us that,
+ given usable information in hand, we simply don't want to wait "too
+ much longer" after we get a result.
+
+ We simply wait an additional amount of time equal to the default
+ c-ares query timeout. That is enough time for a typical parallel
+ response to arrive without being "too long". Even on a network
+ where one of the two types of queries is failing or timing out
+ constantly, this will usually mean we wait a total of the default
+ c-ares timeout (5 seconds) plus the round trip time for the successful
+ request, which seems bearable. The downside is that c-ares might race
+ with us to issue one more retry just before we give up, but it seems
+ better to "waste" that request instead of trying to guess the perfect
+ timeout to prevent it. After all, we don't even know where in the
+ c-ares retry cycle each request is.
+ */
+ res->happy_eyeballs_dns_time = Curl_now();
+ Curl_expire(
+ conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
+ }
}
}
diff --git a/lib/base64.c b/lib/base64.c
index 431b64357..fb081a6bb 100644
--- a/lib/base64.c
+++ b/lib/base64.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
@@ -23,6 +23,11 @@
/* Base64 encoding/decoding */
#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_LIBSSH2) || \
+ defined(USE_LIBSSH) || !defined(CURL_DISABLE_LDAP) || \
+ !defined(CURL_DISABLE_DOH) || defined(USE_SSL)
+
#include "urldata.h" /* for the Curl_easy definition */
#include "warnless.h"
#include "curl_base64.h"
@@ -317,3 +322,5 @@ CURLcode Curl_base64url_encode(struct Curl_easy *data,
{
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
}
+
+#endif /* no users so disabled */
diff --git a/lib/config-win32.h b/lib/config-win32.h
index 76b00b9bb..24c35d339 100644
--- a/lib/config-win32.h
+++ b/lib/config-win32.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
@@ -185,6 +185,9 @@
/* Define if you have the ftruncate function. */
#define HAVE_FTRUNCATE 1
+/* Define to 1 if you have the `getpeername' function. */
+#define HAVE_GETPEERNAME 1
+
/* Define if you have the gethostbyaddr function. */
#define HAVE_GETHOSTBYADDR 1
diff --git a/lib/conncache.c b/lib/conncache.c
index 2c5d6b443..49fad83e5 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -434,6 +434,7 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
struct connectdata *conn_candidate = NULL;
conn->data = NULL; /* no owner anymore */
+ conn->lastused = Curl_now(); /* it was used up until now */
if(maxconnects > 0 &&
Curl_conncache_size(data) > maxconnects) {
infof(data, "Connection cache is full, closing the oldest one.\n");
@@ -479,7 +480,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
if(!CONN_INUSE(conn) && !conn->data) {
/* Set higher score for the age passed since the connection was used */
- score = Curl_timediff(now, conn->now);
+ score = Curl_timediff(now, conn->lastused);
if(score > highscore) {
highscore = score;
@@ -537,7 +538,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
if(!CONN_INUSE(conn) && !conn->data) {
/* Set higher score for the age passed since the connection was used */
- score = Curl_timediff(now, conn->now);
+ score = Curl_timediff(now, conn->lastused);
if(score > highscore) {
highscore = score;
diff --git a/lib/conncache.h b/lib/conncache.h
index 0df6d4715..35be9e0aa 100644
--- a/lib/conncache.h
+++ b/lib/conncache.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
@@ -40,7 +40,6 @@ struct conncache {
#define BUNDLE_NO_MULTIUSE -1
#define BUNDLE_UNKNOWN 0 /* initial value */
-#define BUNDLE_PIPELINING 1
#define BUNDLE_MULTIPLEX 2
struct connectbundle {
diff --git a/lib/connect.c b/lib/connect.c
index a53d79c21..002535b42 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -357,7 +357,7 @@ static CURLcode bindlocal(struct connectdata *conn,
conn->ip_version = CURL_IPRESOLVE_V6;
#endif
- rc = Curl_resolv(conn, dev, 0, &h);
+ rc = Curl_resolv(conn, dev, 0, FALSE, &h);
if(rc == CURLRESOLV_PENDING)
(void)Curl_resolver_wait_resolv(conn, &h);
conn->ip_version = ipver;
@@ -628,7 +628,6 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
long *port)
{
- unsigned short us_port;
struct sockaddr_in *si = NULL;
#ifdef ENABLE_IPV6
struct sockaddr_in6 *si6 = NULL;
@@ -642,7 +641,7 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
si = (struct sockaddr_in *)(void *) sa;
if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
addr, MAX_IPADR_LEN)) {
- us_port = ntohs(si->sin_port);
+ unsigned short us_port = ntohs(si->sin_port);
*port = us_port;
return TRUE;
}
@@ -652,7 +651,7 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
si6 = (struct sockaddr_in6 *)(void *) sa;
if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
addr, MAX_IPADR_LEN)) {
- us_port = ntohs(si6->sin6_port);
+ unsigned short us_port = ntohs(si6->sin6_port);
*port = us_port;
return TRUE;
}
@@ -679,17 +678,18 @@ UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
connection */
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
{
- curl_socklen_t len;
- struct Curl_sockaddr_storage ssrem;
- struct Curl_sockaddr_storage ssloc;
- struct Curl_easy *data = conn->data;
-
if(conn->socktype == SOCK_DGRAM)
/* there's no connection! */
return;
+#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+ struct Curl_easy *data = conn->data;
char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssrem;
+ struct Curl_sockaddr_storage ssloc;
+ curl_socklen_t len;
+#ifdef HAVE_GETPEERNAME
len = sizeof(struct Curl_sockaddr_storage);
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
int error = SOCKERRNO;
@@ -697,7 +697,8 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
error, Curl_strerror(error, buffer, sizeof(buffer)));
return;
}
-
+#endif
+#ifdef HAVE_GETSOCKNAME
len = sizeof(struct Curl_sockaddr_storage);
memset(&ssloc, 0, sizeof(ssloc));
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
@@ -706,7 +707,8 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
error, Curl_strerror(error, buffer, sizeof(buffer)));
return;
}
-
+#endif
+#ifdef HAVE_GETPEERNAME
if(!getaddressinfo((struct sockaddr*)&ssrem,
conn->primary_ip, &conn->primary_port)) {
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
@@ -714,15 +716,19 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
return;
}
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)) {
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
return;
}
-
+#endif
}
+#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
+ (void)sockfd; /* unused */
+#endif
/* persist connection info in session handle */
Curl_persistconninfo(conn);
@@ -1028,7 +1034,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
Curl_closesocket(conn, sockfd);
return CURLE_OK;
}
- infof(data, " Trying %s...\n", ipaddress);
+ infof(data, " Trying %s:%ld...\n", ipaddress, port);
#ifdef ENABLE_IPV6
is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
diff --git a/lib/cookie.c b/lib/cookie.c
index 44851a52f..05ce62193 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -93,6 +93,7 @@ Example set of cookies:
#include "share.h"
#include "strtoofft.h"
#include "strcase.h"
+#include "curl_get_line.h"
#include "curl_memrchr.h"
#include "inet_pton.h"
@@ -873,11 +874,13 @@ Curl_cookie_add(struct Curl_easy *data,
co->name = strdup(ptr);
if(!co->name)
badcookie = TRUE;
- /* For Netscape file format cookies we check prefix on the name */
- if(strncasecompare("__Secure-", co->name, 9))
- co->prefix |= COOKIE_PREFIX__SECURE;
- else if(strncasecompare("__Host-", co->name, 7))
- co->prefix |= COOKIE_PREFIX__HOST;
+ else {
+ /* For Netscape file format cookies we check prefix on the name */
+ if(strncasecompare("__Secure-", co->name, 9))
+ co->prefix |= COOKIE_PREFIX__SECURE;
+ else if(strncasecompare("__Host-", co->name, 7))
+ co->prefix |= COOKIE_PREFIX__HOST;
+ }
break;
case 6:
co->value = strdup(ptr);
@@ -1085,33 +1088,6 @@ Curl_cookie_add(struct Curl_easy *data,
return co;
}
-/*
- * get_line() makes sure to only return complete whole lines that fit in 'len'
- * bytes and end with a newline.
- */
-char *Curl_get_line(char *buf, int len, FILE *input)
-{
- bool partial = FALSE;
- while(1) {
- char *b = fgets(buf, len, input);
- if(b) {
- size_t rlen = strlen(b);
- if(rlen && (b[rlen-1] == '\n')) {
- if(partial) {
- partial = FALSE;
- continue;
- }
- return b;
- }
- /* read a partial, discard the next piece that ends with newline */
- partial = TRUE;
- }
- else
- break;
- }
- return NULL;
-}
-
/*****************************************************************************
*
@@ -1533,10 +1509,6 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
struct Cookie *co;
FILE *out;
bool use_stdout = FALSE;
- char *format_ptr;
- unsigned int i;
- unsigned int j;
- struct Cookie **array;
if(!c)
/* no cookie engine alive */
@@ -1563,6 +1535,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
out);
if(c->numcookies) {
+ unsigned int i;
+ unsigned int j;
+ struct Cookie **array;
+
array = malloc(sizeof(struct Cookie *) * c->numcookies);
if(!array) {
if(!use_stdout)
@@ -1582,7 +1558,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
for(i = 0; i < j; i++) {
- format_ptr = get_netscape_format(array[i]);
+ char *format_ptr = get_netscape_format(array[i]);
if(format_ptr == NULL) {
fprintf(out, "#\n# Fatal libcurl error\n");
free(array);
diff --git a/lib/cookie.h b/lib/cookie.h
index 6e4108bb1..6e314f9fa 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -101,7 +101,6 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
void Curl_cookie_freelist(struct Cookie *cookies);
void Curl_cookie_clearall(struct CookieInfo *cookies);
void Curl_cookie_clearsess(struct CookieInfo *cookies);
-char *Curl_get_line(char *buf, int len, FILE *input);
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
#define Curl_cookie_list(x) NULL
diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index 5308eb579..9ac64f651 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -235,6 +235,12 @@
/* Define to 1 if you have the `getprotobyname' function. */
#cmakedefine HAVE_GETPROTOBYNAME 1
+/* Define to 1 if you have the `getpeername' function. */
+#cmakedefine HAVE_GETPEERNAME 1
+
+/* Define to 1 if you have the `getsockname' function. */
+#cmakedefine HAVE_GETSOCKNAME 1
+
/* Define to 1 if you have the `getpwuid' function. */
#cmakedefine HAVE_GETPWUID 1
@@ -930,8 +936,8 @@
/* if PolarSSL is enabled */
#cmakedefine USE_POLARSSL 1
-/* if DarwinSSL is enabled */
-#cmakedefine USE_DARWINSSL 1
+/* if Secure Transport is enabled */
+#cmakedefine USE_SECTRANSP 1
/* if mbedTLS is enabled */
#cmakedefine USE_MBEDTLS 1
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index 3b7fc5026..027680083 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -32,15 +32,6 @@
#ifndef HAVE_FNMATCH
-/*
- * TODO:
- *
- * Make this function match POSIX. Test 1307 includes a set of test patterns
- * that returns different results with a POSIX fnmatch() than with this
- * implementation and this is considered a bug where POSIX is the guiding
- * light.
- */
-
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
diff --git a/lib/curl_get_line.c b/lib/curl_get_line.c
new file mode 100644
index 000000000..c4194851a
--- /dev/null
+++ b/lib/curl_get_line.c
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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"
+
+#include "curl_get_line.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * get_line() makes sure to only return complete whole lines that fit in 'len'
+ * bytes and end with a newline.
+ */
+char *Curl_get_line(char *buf, int len, FILE *input)
+{
+ bool partial = FALSE;
+ while(1) {
+ char *b = fgets(buf, len, input);
+ if(b) {
+ size_t rlen = strlen(b);
+ if(rlen && (b[rlen-1] == '\n')) {
+ if(partial) {
+ partial = FALSE;
+ continue;
+ }
+ return b;
+ }
+ /* read a partial, discard the next piece that ends with newline */
+ partial = TRUE;
+ }
+ else
+ break;
+ }
+ return NULL;
+}
diff --git a/lib/curl_get_line.h b/lib/curl_get_line.h
new file mode 100644
index 000000000..532ab080a
--- /dev/null
+++ b/lib/curl_get_line.h
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_GET_LINE_H
+#define HEADER_CURL_GET_LINE_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.
+ *
+ ***************************************************************************/
+
+/* get_line() makes sure to only return complete whole lines that fit in 'len'
+ * bytes and end with a newline. */
+char *Curl_get_line(char *buf, int len, FILE *input);
+
+#endif /* HEADER_CURL_GET_LINE_H */
diff --git a/lib/curl_md4.h b/lib/curl_md4.h
index e0690416d..392203f9e 100644
--- a/lib/curl_md4.h
+++ b/lib/curl_md4.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, 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
@@ -25,11 +25,13 @@
#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))
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 /* HEADER_CURL_MD4_H */
diff --git a/lib/curl_md5.h b/lib/curl_md5.h
index 5f70c9634..aaf25f61b 100644
--- a/lib/curl_md5.h
+++ b/lib/curl_md5.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2010, 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
@@ -53,10 +53,10 @@ void Curl_md5it(unsigned char *output,
const unsigned char *input);
MD5_context * Curl_MD5_init(const MD5_params *md5params);
-int Curl_MD5_update(MD5_context *context,
- const unsigned char *data,
- unsigned int len);
-int Curl_MD5_final(MD5_context *context, unsigned char *result);
+CURLcode Curl_MD5_update(MD5_context *context,
+ const unsigned char *data,
+ unsigned int len);
+CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result);
#endif
diff --git a/lib/curl_memory.h b/lib/curl_memory.h
index 6d024a743..db93014c3 100644
--- a/lib/curl_memory.h
+++ b/lib/curl_memory.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
@@ -39,7 +39,7 @@
*
* File lib/strdup.c is an exception, given that it provides a strdup
* clone implementation while using malloc. Extra care needed inside
- * this one. TODO: revisit this paragraph and related code.
+ * this one.
*
* The need for curl_memory.h inclusion is due to libcurl's feature
* of allowing library user to provide memory replacement functions,
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index e7060eb29..b6df38f71 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -57,6 +57,8 @@
# 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>
@@ -568,10 +570,14 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
{
/* 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);
diff --git a/lib/curl_ntlm_core.h b/lib/curl_ntlm_core.h
index 07ef5deae..3b4b8053c 100644
--- a/lib/curl_ntlm_core.h
+++ b/lib/curl_ntlm_core.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, 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
@@ -43,9 +43,7 @@
/* Define USE_NTRESPONSES in order to make the type-3 message include
* the NT response message. */
-#if !defined(USE_OPENSSL) || !defined(OPENSSL_NO_MD4)
#define USE_NTRESPONSES
-#endif
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index 18ee75dd9..80266e2a4 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -53,6 +53,8 @@
#include "url.h"
#include "strerror.h"
#include "strdup.h"
+#include "strcase.h"
+
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -74,7 +76,7 @@
# define sclose_nolog(x) close((x))
#endif
-void Curl_ntlm_wb_cleanup(struct connectdata *conn)
+void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
{
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
sclose(conn->ntlm_auth_hlpr_socket);
@@ -333,6 +335,48 @@ done:
return CURLE_REMOTE_ACCESS_DENIED;
}
+CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
+ bool proxy,
+ const char *header)
+{
+ curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
+
+ if(!checkprefix("NTLM", header))
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ header += strlen("NTLM");
+ while(*header && ISSPACE(*header))
+ header++;
+
+ if(*header) {
+ conn->challenge_header = strdup(header);
+ if(!conn->challenge_header)
+ return CURLE_OUT_OF_MEMORY;
+
+ *state = NTLMSTATE_TYPE2; /* We got a type-2 message */
+ }
+ else {
+ if(*state == NTLMSTATE_LAST) {
+ infof(conn->data, "NTLM auth restarted\n");
+ Curl_http_auth_cleanup_ntlm_wb(conn);
+ }
+ else if(*state == NTLMSTATE_TYPE3) {
+ infof(conn->data, "NTLM handshake rejected\n");
+ Curl_http_auth_cleanup_ntlm_wb(conn);
+ *state = NTLMSTATE_NONE;
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+ else if(*state >= NTLMSTATE_TYPE1) {
+ infof(conn->data, "NTLM handshake failure (internal error)\n");
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+
+ *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
+ }
+
+ return CURLE_OK;
+}
+
/*
* This is for creating ntlm header output by delegating challenge/response
* to Samba's winbind daemon helper ntlm_auth.
@@ -345,8 +389,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
char **allocuserpwd;
/* point to the name and password for this */
const char *userp;
- /* point to the correct struct with this */
- struct ntlmdata *ntlm;
+ curlntlm *state;
struct auth *authp;
CURLcode res = CURLE_OK;
@@ -358,13 +401,13 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
if(proxy) {
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->http_proxy.user;
- ntlm = &conn->proxyntlm;
+ state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
}
else {
allocuserpwd = &conn->allocptr.userpwd;
userp = conn->user;
- ntlm = &conn->ntlm;
+ state = &conn->http_ntlm_state;
authp = &conn->data->state.authhost;
}
authp->done = FALSE;
@@ -373,7 +416,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
if(!userp)
userp = "";
- switch(ntlm->state) {
+ switch(*state) {
case NTLMSTATE_TYPE1:
default:
/* Use Samba's 'winbind' daemon to support NTLM authentication,
@@ -392,7 +435,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
res = ntlm_wb_init(conn, userp);
if(res)
return res;
- res = ntlm_wb_response(conn, "YR\n", ntlm->state);
+ res = ntlm_wb_response(conn, "YR\n", *state);
if(res)
return res;
@@ -406,11 +449,12 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
conn->response_header = NULL;
break;
+
case NTLMSTATE_TYPE2:
input = aprintf("TT %s\n", conn->challenge_header);
if(!input)
return CURLE_OUT_OF_MEMORY;
- res = ntlm_wb_response(conn, input, ntlm->state);
+ res = ntlm_wb_response(conn, input, *state);
free(input);
input = NULL;
if(res)
@@ -421,17 +465,20 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
proxy ? "Proxy-" : "",
conn->response_header);
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
- ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
+ *state = NTLMSTATE_TYPE3; /* we sent a type-3 */
authp->done = TRUE;
- Curl_ntlm_wb_cleanup(conn);
+ Curl_http_auth_cleanup_ntlm_wb(conn);
if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY;
break;
+
case NTLMSTATE_TYPE3:
/* connection is already authenticated,
* don't send a header in future requests */
- free(*allocuserpwd);
- *allocuserpwd = NULL;
+ *state = NTLMSTATE_LAST;
+ /* FALLTHROUGH */
+ case NTLMSTATE_LAST:
+ Curl_safefree(*allocuserpwd);
authp->done = TRUE;
break;
}
diff --git a/lib/curl_ntlm_wb.h b/lib/curl_ntlm_wb.h
index aba3d469c..3cf841cf2 100644
--- a/lib/curl_ntlm_wb.h
+++ b/lib/curl_ntlm_wb.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, 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
@@ -27,11 +27,14 @@
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
defined(NTLM_WB_ENABLED)
-/* this is for creating ntlm header output by delegating challenge/response
- to Samba's winbind daemon helper ntlm_auth */
+/* this is for ntlm header input */
+CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy,
+ const char *header);
+
+/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
-void Curl_ntlm_wb_cleanup(struct connectdata *conn);
+void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn);
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
diff --git a/lib/curl_path.c b/lib/curl_path.c
index 74406ace4..3e1fe2a7c 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -22,7 +22,7 @@
#include "curl_setup.h"
-#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
+#if defined(USE_SSH)
#include <gnurl/curl.h>
#include "curl_memory.h"
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 437a9f66a..e8a940211 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -31,6 +31,9 @@
#include "curl_setup.h"
+#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_POP3)
+
#include <gnurl/curl.h>
#include "urldata.h"
@@ -83,14 +86,14 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
#if defined(USE_KERBEROS5)
/* Cleanup the gssapi structure */
if(authused == SASL_MECH_GSSAPI) {
- Curl_auth_gssapi_cleanup(&conn->krb5);
+ Curl_auth_cleanup_gssapi(&conn->krb5);
}
#endif
#if defined(USE_NTLM)
/* Cleanup the NTLM structure */
if(authused == SASL_MECH_NTLM) {
- Curl_auth_ntlm_cleanup(&conn->ntlm);
+ Curl_auth_cleanup_ntlm(&conn->ntlm);
}
#endif
@@ -290,7 +293,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
#if defined(USE_KERBEROS5)
if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
Curl_auth_user_contains_domain(conn->user)) {
- sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
+ sasl->mutual_auth = FALSE;
mech = SASL_MECH_STRING_GSSAPI;
state1 = SASL_GSSAPI;
state2 = SASL_GSSAPI_TOKEN;
@@ -357,10 +360,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
sasl->authused = SASL_MECH_XOAUTH2;
if(force_ir || data->set.sasl_ir)
- result = Curl_auth_create_oauth_bearer_message(data, conn->user,
- NULL, 0,
- conn->oauth_bearer,
- &resp, &len);
+ result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
+ conn->oauth_bearer,
+ &resp, &len);
}
else if(enabledmechs & SASL_MECH_PLAIN) {
mech = SASL_MECH_STRING_PLAIN;
@@ -368,8 +370,8 @@ 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, conn->user, conn->passwd,
- &resp, &len);
+ result = Curl_auth_create_plain_message(data, NULL, conn->user,
+ conn->passwd, &resp, &len);
}
else if(enabledmechs & SASL_MECH_LOGIN) {
mech = SASL_MECH_STRING_LOGIN;
@@ -451,9 +453,8 @@ 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, conn->user, conn->passwd,
- &resp,
- &len);
+ result = Curl_auth_create_plain_message(data, NULL, conn->user,
+ conn->passwd, &resp, &len);
break;
case SASL_LOGIN:
result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
@@ -562,10 +563,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
newstate = SASL_OAUTH2_RESP;
}
else
- result = Curl_auth_create_oauth_bearer_message(data, conn->user,
- NULL, 0,
- conn->oauth_bearer,
- &resp, &len);
+ result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
+ conn->oauth_bearer,
+ &resp, &len);
break;
case SASL_OAUTH2_RESP:
@@ -626,3 +626,4 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
return result;
}
+#endif /* protocols are enabled that use SASL */
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 26c3646e8..35f69d141 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -686,6 +686,10 @@ int netware_init(void);
#error "No longer supported. Set CURLOPT_CAINFO at runtime instead."
#endif
+#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH)
+#define USE_SSH
+#endif
+
/*
* Provide a mechanism to silence picky compilers, such as gcc 4.6+.
* Parameters should of course normally not be unused, but for example when
diff --git a/lib/doh.c b/lib/doh.c
index b5327c4ae..6d1f3303b 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -22,6 +22,8 @@
#include "curl_setup.h"
+#ifndef CURL_DISABLE_DOH
+
#include "urldata.h"
#include "curl_addrinfo.h"
#include "doh.h"
@@ -582,7 +584,6 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
unsigned short qdcount;
unsigned short ancount;
unsigned short type = 0;
- unsigned short class;
unsigned short rdlength;
unsigned short nscount;
unsigned short arcount;
@@ -610,6 +611,7 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
ancount = get16bit(doh, 6);
while(ancount) {
+ unsigned short class;
unsigned int ttl;
rc = skipqname(doh, dohlen, &index);
@@ -894,8 +896,6 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
DOHcode rc;
DOHcode rc2;
struct dohentry de;
- struct Curl_dns_entry *dns;
- struct Curl_addrinfo *ai;
/* remove DOH handles from multi handle and close them */
curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy);
Curl_close(data->req.doh.probe[0].easy);
@@ -925,6 +925,9 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
data->req.doh.host);
}
if(!rc || !rc2) {
+ struct Curl_dns_entry *dns;
+ struct Curl_addrinfo *ai;
+
infof(data, "DOH Host name: %s\n", data->req.doh.host);
showdoh(data, &de);
@@ -960,3 +963,5 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
return CURLE_OK;
}
+
+#endif /* CURL_DISABLE_DOH */
diff --git a/lib/doh.h b/lib/doh.h
index 83c79bc5d..34bfa6f2b 100644
--- a/lib/doh.h
+++ b/lib/doh.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 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
@@ -25,6 +25,8 @@
#include "urldata.h"
#include "curl_addrinfo.h"
+#ifndef CURL_DISABLE_DOH
+
/*
* Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
* and returns a 'Curl_addrinfo *' with the address information.
@@ -102,4 +104,10 @@ DOHcode doh_decode(unsigned char *doh,
struct dohentry *d);
void de_cleanup(struct dohentry *d);
#endif
+
+#else /* if DOH is disabled */
+#define Curl_doh(a,b,c,d) NULL
+#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
+#endif
+
#endif /* HEADER_CURL_DOH_H */
diff --git a/lib/easy.c b/lib/easy.c
index 9e902623b..0cbe8c8da 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -265,7 +265,6 @@ void curl_global_cleanup(void)
if(--initialized)
return;
- Curl_global_host_cache_dtor();
Curl_ssl_cleanup();
Curl_resolver_global_cleanup();
@@ -428,8 +427,8 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
mask. Convert from libcurl bitmask to the poll one. */
m->socket.events = socketcb2poll(what);
infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
- what&CURL_POLL_IN?"IN":"",
- what&CURL_POLL_OUT?"OUT":"");
+ (what&CURL_POLL_IN)?"IN":"",
+ (what&CURL_POLL_OUT)?"OUT":"");
}
break;
}
@@ -452,8 +451,8 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
m->socket.revents = 0;
ev->list = m;
infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
- what&CURL_POLL_IN?"IN":"",
- what&CURL_POLL_OUT?"OUT":"");
+ (what&CURL_POLL_IN)?"IN":"",
+ (what&CURL_POLL_OUT)?"OUT":"");
}
else
return CURLE_OUT_OF_MEMORY;
@@ -560,7 +559,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
return CURLE_RECV_ERROR;
if(mcode)
- return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
+ return CURLE_URL_MALFORMAT;
/* we don't really care about the "msgs_in_queue" value returned in the
second argument */
@@ -962,7 +961,10 @@ void curl_easy_reset(struct Curl_easy *data)
/* zero out authentication data: */
memset(&data->state.authhost, 0, sizeof(struct auth));
memset(&data->state.authproxy, 0, sizeof(struct auth));
- Curl_digest_cleanup(data);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+ Curl_http_auth_cleanup_digest(data);
+#endif
}
/*
diff --git a/lib/fileinfo.c b/lib/fileinfo.c
index 4e72e1eba..2630c9e46 100644
--- a/lib/fileinfo.c
+++ b/lib/fileinfo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 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
@@ -21,7 +21,7 @@
***************************************************************************/
#include "curl_setup.h"
-
+#ifndef CURL_DISABLE_FTP
#include "strdup.h"
#include "fileinfo.h"
#include "curl_memory.h"
@@ -41,3 +41,4 @@ void Curl_fileinfo_cleanup(struct fileinfo *finfo)
Curl_safefree(finfo->info.b_data);
free(finfo);
}
+#endif
diff --git a/lib/formdata.c b/lib/formdata.c
index 5a6cdd644..ae453b1c6 100644
--- a/lib/formdata.c
+++ b/lib/formdata.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
@@ -24,14 +24,14 @@
#include <gnurl/curl.h>
-#ifndef CURL_DISABLE_HTTP
+#include "formdata.h"
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
#endif
#include "urldata.h" /* for struct Curl_easy */
-#include "formdata.h"
#include "mime.h"
#include "non-ascii.h"
#include "vtls/vtls.h"
@@ -568,7 +568,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype) {
- char *f = form->flags & HTTPPOST_BUFFER?
+ char *f = (form->flags & HTTPPOST_BUFFER)?
form->showfilename : form->value;
char const *type;
type = Curl_mime_contenttype(f);
@@ -920,7 +920,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
return result;
}
-#else /* CURL_DISABLE_HTTP */
+#else
+/* if disabled */
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
struct curl_httppost **last_post,
...)
@@ -945,5 +946,4 @@ void curl_formfree(struct curl_httppost *form)
/* does nothing HTTP is disabled */
}
-
-#endif /* !defined(CURL_DISABLE_HTTP) */
+#endif /* if disabled */
diff --git a/lib/formdata.h b/lib/formdata.h
index 1246c2bc8..cb20805f5 100644
--- a/lib/formdata.h
+++ b/lib/formdata.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
@@ -22,6 +22,10 @@
*
***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_MIME
+
/* used by FormAdd for temporary storage */
typedef struct FormInfo {
char *name;
@@ -47,5 +51,10 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
curl_mimepart *,
struct curl_httppost *post,
curl_read_callback fread_func);
+#else
+/* disabled */
+#define Curl_getformdata(a,b,c,d) CURLE_NOT_BUILT_IN
+#endif
+
#endif /* HEADER_CURL_FORMDATA_H */
diff --git a/lib/ftp.c b/lib/ftp.c
index 132813666..6d017ad18 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -572,7 +572,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
#if defined(HAVE_GSSAPI)
/* handle the security-oriented responses 6xx ***/
- /* FIXME: some errorchecking perhaps... ***/
switch(code) {
case 631:
code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
@@ -1080,7 +1079,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
}
/* resolv ip/host to ip */
- rc = Curl_resolv(conn, host, 0, &h);
+ rc = Curl_resolv(conn, host, 0, FALSE, &h);
if(rc == CURLRESOLV_PENDING)
(void)Curl_resolver_wait_resolv(conn, &h);
if(h) {
@@ -1934,7 +1933,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
*/
const char * const host_name = conn->bits.socksproxy ?
conn->socks_proxy.host.name : conn->http_proxy.host.name;
- rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
+ rc = Curl_resolv(conn, host_name, (int)conn->port, FALSE, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING, ignores the return code but 'addr' will be NULL in
case of failure */
@@ -1950,7 +1949,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
else {
/* normal, direct, ftp connection */
- rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
+ rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING */
(void)Curl_resolver_wait_resolv(conn, &addr);
@@ -3490,7 +3489,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
if(Curl_connect_ongoing(conn)) {
/* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
- aren't used so we blank their arguments. TODO: make this nicer */
+ aren't used so we blank their arguments. */
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0);
return result;
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index c13b0fe70..5893bc51f 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -914,10 +914,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
case PL_WINNT_DIRORSIZE:
switch(parser->state.NT.sub.dirorsize) {
case PL_WINNT_DIRORSIZE_PRESPACE:
- if(c == ' ') {
-
- }
- else {
+ if(c != ' ') {
parser->item_offset = finfo->b_used - 1;
parser->item_length = 1;
parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT;
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index 6fcd0a901..115d24b2e 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -127,16 +127,14 @@ static int hostmatch(char *hostname, char *pattern)
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
{
- char *matchp;
- char *hostp;
int res = 0;
if(!match_pattern || !*match_pattern ||
!hostname || !*hostname) /* sanity check */
;
else {
- matchp = strdup(match_pattern);
+ char *matchp = strdup(match_pattern);
if(matchp) {
- hostp = strdup(hostname);
+ char *hostp = strdup(hostname);
if(hostp) {
if(hostmatch(hostp, matchp) == CURL_HOST_MATCH)
res = 1;
diff --git a/lib/hostip.c b/lib/hostip.c
index 7909141c1..cf33ed8f4 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -114,43 +114,9 @@
* CURLRES_* defines based on the config*.h and curl_setup.h defines.
*/
-/* These two symbols are for the global DNS cache */
-static struct curl_hash hostname_cache;
-static int host_cache_initialized;
-
static void freednsentry(void *freethis);
/*
- * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
- * Global DNS cache is general badness. Do not use. This will be removed in
- * a future version. Use the share interface instead!
- *
- * Returns a struct curl_hash pointer on success, NULL on failure.
- */
-struct curl_hash *Curl_global_host_cache_init(void)
-{
- int rc = 0;
- if(!host_cache_initialized) {
- rc = Curl_hash_init(&hostname_cache, 7, Curl_hash_str,
- Curl_str_key_compare, freednsentry);
- if(!rc)
- host_cache_initialized = 1;
- }
- return rc?NULL:&hostname_cache;
-}
-
-/*
- * Destroy and cleanup the global DNS cache
- */
-void Curl_global_host_cache_dtor(void)
-{
- if(host_cache_initialized) {
- Curl_hash_destroy(&hostname_cache);
- host_cache_initialized = 0;
- }
-}
-
-/*
* Return # of addresses in a Curl_addrinfo struct
*/
int Curl_num_addresses(const Curl_addrinfo *addr)
@@ -368,9 +334,9 @@ Curl_fetch_addr(struct connectdata *conn,
return dns;
}
+#ifndef CURL_DISABLE_SHUFFLE_DNS
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
Curl_addrinfo **addr);
-
/*
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
* struct by re-linking its linked list.
@@ -435,6 +401,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
}
return result;
}
+#endif
/*
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
@@ -456,12 +423,14 @@ Curl_cache_addr(struct Curl_easy *data,
struct Curl_dns_entry *dns;
struct Curl_dns_entry *dns2;
+#ifndef CURL_DISABLE_SHUFFLE_DNS
/* shuffle addresses if requested */
if(data->set.dns_shuffle_addresses) {
CURLcode result = Curl_shuffle_addr(data, &addr);
if(result)
return NULL;
}
+#endif
/* Create a new cache entry */
dns = calloc(1, sizeof(struct Curl_dns_entry));
@@ -516,6 +485,7 @@ Curl_cache_addr(struct Curl_easy *data,
int Curl_resolv(struct connectdata *conn,
const char *hostname,
int port,
+ bool allowDOH,
struct Curl_dns_entry **entry)
{
struct Curl_dns_entry *dns = NULL;
@@ -561,7 +531,7 @@ int Curl_resolv(struct connectdata *conn,
return CURLRESOLV_ERROR;
}
- if(data->set.doh) {
+ if(allowDOH && data->set.doh) {
addr = Curl_doh(conn, hostname, port, &respwait);
}
else {
@@ -687,7 +657,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
if(!timeout)
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
- return Curl_resolv(conn, hostname, port, entry);
+ return Curl_resolv(conn, hostname, port, TRUE, entry);
if(timeout < 1000) {
/* The alarm() function only provides integer second resolution, so if
@@ -749,7 +719,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
/* Perform the actual name resolution. This might be interrupted by an
* alarm if it takes too long.
*/
- rc = Curl_resolv(conn, hostname, port, entry);
+ rc = Curl_resolv(conn, hostname, port, TRUE, entry);
#ifdef USE_ALARM_TIMEOUT
clean_up:
diff --git a/lib/hostip.h b/lib/hostip.h
index cd43882af..9dc0d5a17 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -83,8 +83,11 @@ struct Curl_dns_entry {
#define CURLRESOLV_ERROR -1
#define CURLRESOLV_RESOLVED 0
#define CURLRESOLV_PENDING 1
-int Curl_resolv(struct connectdata *conn, const char *hostname,
- int port, struct Curl_dns_entry **dnsentry);
+int Curl_resolv(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ bool allowDOH,
+ 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);
diff --git a/lib/hostip6.c b/lib/hostip6.c
index fb2f35ce3..5511f1aab 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -102,14 +102,15 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
printf("dump_addrinfo:\n");
for(; ai; ai = ai->ai_next) {
char buf[INET6_ADDRSTRLEN];
- char buffer[STRERROR_LEN];
printf(" fam %2d, CNAME %s, ",
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
if(Curl_printable_address(ai, buf, sizeof(buf)))
printf("%s\n", buf);
- else
+ else {
+ char buffer[STRERROR_LEN];
printf("failed; %s\n",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
+ }
}
}
#else
diff --git a/lib/http.c b/lib/http.c
index 5a70c4d23..92c06a144 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -73,7 +73,6 @@
#include "http_proxy.h"
#include "warnless.h"
#include "non-ascii.h"
-#include "pipeline.h"
#include "http2.h"
#include "connect.h"
#include "strdup.h"
@@ -93,7 +92,9 @@ static int http_getsock_do(struct connectdata *conn,
int numsocks);
static int http_should_fail(struct connectdata *conn);
+#ifndef CURL_DISABLE_PROXY
static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
+#endif
#ifdef USE_SSL
static CURLcode https_connecting(struct connectdata *conn, bool *done);
@@ -177,7 +178,7 @@ static CURLcode http_setup_conn(struct connectdata *conn)
return CURLE_OK;
}
-
+#ifndef CURL_DISABLE_PROXY
/*
* checkProxyHeaders() checks the linked list of custom proxy headers
* if proxy headers are not available, then it will lookup into http header
@@ -204,6 +205,10 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
return NULL;
}
+#else
+/* disabled */
+#define Curl_checkProxyheaders(x,y) NULL
+#endif
/*
* Strip off leading and trailing whitespace from the value in the
@@ -258,6 +263,7 @@ char *Curl_copy_header_value(const char *header)
return value;
}
+#ifndef CURL_DISABLE_HTTP_AUTH
/*
* http_output_basic() sets up an Authorization: header (or the proxy version)
* for HTTP Basic authentication.
@@ -339,6 +345,8 @@ static CURLcode http_output_bearer(struct connectdata *conn)
return result;
}
+#endif
+
/* pickoneauth() selects the most favourable authentication method from the
* ones available and the ones we want.
*
@@ -458,8 +466,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
(data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
(data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
if(((expectsend - bytessent) < 2000) ||
- (conn->ntlm.state != NTLMSTATE_NONE) ||
- (conn->proxyntlm.state != NTLMSTATE_NONE)) {
+ (conn->http_ntlm_state != NTLMSTATE_NONE) ||
+ (conn->proxy_ntlm_state != NTLMSTATE_NONE)) {
/* The NTLM-negotiation has started *OR* there is just a little (<2K)
data left to send, keep on sending. */
@@ -486,8 +494,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
(data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
if(((expectsend - bytessent) < 2000) ||
- (conn->negotiate.state != GSS_AUTHNONE) ||
- (conn->proxyneg.state != GSS_AUTHNONE)) {
+ (conn->http_negotiate_state != GSS_AUTHNONE) ||
+ (conn->proxy_negotiate_state != GSS_AUTHNONE)) {
/* The NEGOTIATE-negotiation has started *OR*
there is just a little (<2K) data left to send, keep on sending. */
@@ -612,6 +620,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
return result;
}
+#ifndef CURL_DISABLE_HTTP_AUTH
/*
* Output the correct authentication header depending on the auth type
* and whether or not it is to a proxy.
@@ -800,6 +809,22 @@ Curl_http_output_auth(struct connectdata *conn,
return result;
}
+#else
+/* when disabled */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+ const char *request,
+ const char *path,
+ bool proxytunnel)
+{
+ (void)conn;
+ (void)request;
+ (void)path;
+ (void)proxytunnel;
+ return CURLE_OK;
+}
+#endif
+
/*
* Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
* headers. They are dealt with both in the transfer.c main loop and in the
@@ -815,8 +840,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
struct Curl_easy *data = conn->data;
#ifdef USE_SPNEGO
- struct negotiatedata *negdata = proxy?
- &conn->proxyneg:&conn->negotiate;
+ curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
+ &conn->http_negotiate_state;
#endif
unsigned long *availp;
struct auth *authp;
@@ -863,7 +888,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
return CURLE_OUT_OF_MEMORY;
data->state.authproblem = FALSE;
/* we received a GSS auth token and we dealt with it fine */
- negdata->state = GSS_AUTHRECV;
+ *negstate = GSS_AUTHRECV;
}
else
data->state.authproblem = TRUE;
@@ -894,19 +919,10 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
*availp |= CURLAUTH_NTLM_WB;
authp->avail |= CURLAUTH_NTLM_WB;
- /* Get the challenge-message which will be passed to
- * ntlm_auth for generating the type 3 message later */
- while(*auth && ISSPACE(*auth))
- auth++;
- if(checkprefix("NTLM", auth)) {
- auth += strlen("NTLM");
- while(*auth && ISSPACE(*auth))
- auth++;
- if(*auth) {
- conn->challenge_header = strdup(auth);
- if(!conn->challenge_header)
- return CURLE_OUT_OF_MEMORY;
- }
+ result = Curl_input_ntlm_wb(conn, proxy, auth);
+ if(result) {
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
}
}
#endif
@@ -1280,7 +1296,6 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
This needs FIXing.
*/
return CURLE_SEND_ERROR;
- Curl_pipeline_leave_write(conn);
}
}
Curl_add_buffer_free(&in);
@@ -1457,12 +1472,14 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
/* nothing else to do except wait right now - we're not done here. */
return CURLE_OK;
+#ifndef CURL_DISABLE_PROXY
if(conn->data->set.haproxyprotocol) {
/* add HAProxy PROXY protocol header */
result = add_haproxy_protocol_header(conn);
if(result)
return result;
}
+#endif
if(conn->given->protocol & CURLPROTO_HTTPS) {
/* perform SSL initialization */
@@ -1489,6 +1506,7 @@ static int http_getsock_do(struct connectdata *conn,
return GETSOCK_WRITESOCK(0);
}
+#ifndef CURL_DISABLE_PROXY
static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
{
char proxy_header[128];
@@ -1529,6 +1547,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
return result;
}
+#endif
#ifdef USE_SSL
static CURLcode https_connecting(struct connectdata *conn, bool *done)
@@ -1689,8 +1708,6 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
const char *endofline_native = NULL;
const char *endofline_network = NULL;
- /* TODO: Maybe split Curl_add_custom_headers to make it reusable here */
-
if(
#ifdef CURL_DO_LINEEND_CONV
(handle->set.prefer_ascii) ||
@@ -1863,6 +1880,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
return CURLE_OK;
}
+#ifndef CURL_DISABLE_PARSEDATE
CURLcode Curl_add_timecondition(struct Curl_easy *data,
Curl_send_buffer *req_buffer)
{
@@ -1921,6 +1939,16 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
return result;
}
+#else
+/* disabled */
+CURLcode Curl_add_timecondition(struct Curl_easy *data,
+ Curl_send_buffer *req_buffer)
+{
+ (void)data;
+ (void)req_buffer;
+ return CURLE_OK;
+}
+#endif
/*
* Curl_http() gets called from the generic multi_do() function when a HTTP
@@ -1972,6 +2000,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
#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;
@@ -2149,6 +2184,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
http->sendit = NULL;
}
+#ifndef CURL_DISABLE_MIME
if(http->sendit) {
const char *cthdr = Curl_checkheaders(conn, "Content-Type");
@@ -2173,6 +2209,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
http->postsize = Curl_mime_size(http->sendit);
}
+#endif
ptr = Curl_checkheaders(conn, "Transfer-Encoding");
if(ptr) {
@@ -2741,6 +2778,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
+#ifndef CURL_DISABLE_MIME
/* Output mime-generated headers. */
{
struct curl_slist *hdr;
@@ -2751,6 +2789,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
}
+#endif
/* For really small posts we don't use Expect: headers at all, and for
the somewhat bigger ones we allow the app to disable it. Just make
@@ -3372,9 +3411,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
#if defined(USE_NTLM)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
- (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
+ (conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
((data->req.httpcode == 407) &&
- (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
+ (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
@@ -3382,19 +3421,19 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
#if defined(USE_SPNEGO)
if(conn->bits.close &&
(((data->req.httpcode == 401) &&
- (conn->negotiate.state == GSS_AUTHRECV)) ||
+ (conn->http_negotiate_state == GSS_AUTHRECV)) ||
((data->req.httpcode == 407) &&
- (conn->proxyneg.state == GSS_AUTHRECV)))) {
+ (conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
data->state.authproblem = TRUE;
}
- if((conn->negotiate.state == GSS_AUTHDONE) &&
+ if((conn->http_negotiate_state == GSS_AUTHDONE) &&
(data->req.httpcode != 401)) {
- conn->negotiate.state = GSS_AUTHSUCC;
+ conn->http_negotiate_state = GSS_AUTHSUCC;
}
- if((conn->proxyneg.state == GSS_AUTHDONE) &&
+ if((conn->proxy_negotiate_state == GSS_AUTHDONE) &&
(data->req.httpcode != 407)) {
- conn->proxyneg.state = GSS_AUTHSUCC;
+ conn->proxy_negotiate_state = GSS_AUTHSUCC;
}
#endif
/*
@@ -3632,6 +3671,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(conn->httpversion != 20)
infof(data, "Lying server, not serving HTTP/2\n");
}
+ if(conn->httpversion < 20) {
+ conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
+ infof(data, "Mark bundle as not supporting multiuse\n");
+ }
}
else if(!nc) {
/* this is the real world, not a Nirvana
@@ -3669,7 +3712,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
}
else {
- /* TODO: do we care about the other cases here? */
nc = 0;
}
}
@@ -3722,16 +3764,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
else if(conn->httpversion >= 11 &&
!conn->bits.close) {
- /* If HTTP version is >= 1.1 and connection is persistent
- server supports pipelining. */
+ /* If HTTP version is >= 1.1 and connection is persistent */
DEBUGF(infof(data,
- "HTTP 1.1 or later with persistent connection, "
- "pipelining supported\n"));
- /* Activate pipelining if needed */
- if(conn->bundle) {
- if(!Curl_pipeline_site_blacklisted(data, conn))
- conn->bundle->multiuse = BUNDLE_PIPELINING;
- }
+ "HTTP 1.1 or later with persistent connection\n"));
}
switch(k->httpcode) {
@@ -3816,19 +3851,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
data->info.contenttype = contenttype;
}
}
- else if(checkprefix("Server:", k->p)) {
- if(conn->httpversion < 20) {
- /* only do this for non-h2 servers */
- char *server_name = Curl_copy_header_value(k->p);
-
- /* Turn off pipelining if the server version is blacklisted */
- if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
- if(Curl_pipeline_server_blacklisted(data, server_name))
- conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
- }
- free(server_name);
- }
- }
else if((conn->httpversion == 10) &&
conn->bits.httpproxy &&
Curl_compareheader(k->p,
diff --git a/lib/http2.c b/lib/http2.c
index ef74704ac..221afec28 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -111,8 +111,6 @@ static int http2_perform_getsock(const struct connectdata *conn,
int bitmap = GETSOCK_BLANK;
(void)numsocks;
- /* TODO We should check underlying socket state if it is SSL socket
- because of renegotiation. */
sock[0] = conn->sock[FIRSTSOCKET];
/* in a HTTP/2 connection we can basically always get a frame so we should
@@ -620,7 +618,7 @@ static int push_promise(struct Curl_easy *data,
/*
* multi_connchanged() is called to tell that there is a connection in
- * this multi handle that has changed state (pipelining become possible, the
+ * this multi handle that has changed state (multiplexing become possible, the
* number of allowed streams changed or similar), and a subsequent use of this
* multi handle should move CONNECT_PEND handles back to CONNECT to have them
* retry.
@@ -970,7 +968,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
char *h;
if(!strcmp(":authority", (const char *)name)) {
- /* psuedo headers are lower case */
+ /* pseudo headers are lower case */
int rc = 0;
char *check = aprintf("%s:%d", conn->host.name, conn->remote_port);
if(!check)
@@ -1847,9 +1845,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
const void *mem, size_t len, CURLcode *err)
{
/*
- * BIG TODO: Currently, we send request in this function, but this
- * function is also used to send request body. It would be nice to
- * add dedicated function for request.
+ * Currently, we send request in this function, but this function is also
+ * used to send request body. It would be nice to add dedicated function for
+ * request.
*/
int rv;
struct http_conn *httpc = &conn->proto.httpc;
diff --git a/lib/http_digest.c b/lib/http_digest.c
index e2d865b0a..9616c30ed 100644
--- a/lib/http_digest.c
+++ b/lib/http_digest.c
@@ -5,7 +5,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
@@ -28,6 +28,7 @@
#include "strcase.h"
#include "vauth/vauth.h"
#include "http_digest.h"
+
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -171,7 +172,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
return CURLE_OK;
}
-void Curl_digest_cleanup(struct Curl_easy *data)
+void Curl_http_auth_cleanup_digest(struct Curl_easy *data)
{
Curl_auth_digest_cleanup(&data->state.digest);
Curl_auth_digest_cleanup(&data->state.proxydigest);
diff --git a/lib/http_digest.h b/lib/http_digest.h
index fd225c7c1..73410ae88 100644
--- a/lib/http_digest.h
+++ b/lib/http_digest.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, 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
@@ -23,6 +23,8 @@
***************************************************************************/
#include "curl_setup.h"
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+
/* this is for digest header input */
CURLcode Curl_input_digest(struct connectdata *conn,
bool proxy, const char *header);
@@ -33,10 +35,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
const unsigned char *request,
const unsigned char *uripath);
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-void Curl_digest_cleanup(struct Curl_easy *data);
-#else
-#define Curl_digest_cleanup(x) Curl_nop_stmt
-#endif
+void Curl_http_auth_cleanup_digest(struct Curl_easy *data);
+
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_CRYPTO_AUTH */
#endif /* HEADER_CURL_HTTP_DIGEST_H */
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 9415236fb..c8f406444 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -49,6 +49,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
/* Point to the correct struct with this */
struct negotiatedata *neg_ctx;
+ curlnegotiate state;
if(proxy) {
userp = conn->http_proxy.user;
@@ -57,6 +58,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
host = conn->http_proxy.host.name;
neg_ctx = &conn->proxyneg;
+ state = conn->proxy_negotiate_state;
}
else {
userp = conn->user;
@@ -65,6 +67,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
data->set.str[STRING_SERVICE_NAME] : "HTTP";
host = conn->host.name;
neg_ctx = &conn->negotiate;
+ state = conn->http_negotiate_state;
}
/* Not set means empty */
@@ -82,14 +85,14 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
len = strlen(header);
neg_ctx->havenegdata = len != 0;
if(!len) {
- if(neg_ctx->state == GSS_AUTHSUCC) {
+ if(state == GSS_AUTHSUCC) {
infof(conn->data, "Negotiate auth restarted\n");
- Curl_cleanup_negotiate(conn);
+ Curl_http_auth_cleanup_negotiate(conn);
}
- else if(neg_ctx->state != GSS_AUTHNONE) {
+ else if(state != GSS_AUTHNONE) {
/* The server rejected our authentication and hasn't supplied any more
negotiation mechanisms */
- Curl_cleanup_negotiate(conn);
+ Curl_http_auth_cleanup_negotiate(conn);
return CURLE_LOGIN_DENIED;
}
}
@@ -104,7 +107,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
host, header, neg_ctx);
if(result)
- Curl_auth_spnego_cleanup(neg_ctx);
+ Curl_http_auth_cleanup_negotiate(conn);
return result;
}
@@ -115,6 +118,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
&conn->negotiate;
struct auth *authp = proxy ? &conn->data->state.authproxy :
&conn->data->state.authhost;
+ curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
+ &conn->http_negotiate_state;
char *base64 = NULL;
size_t len = 0;
char *userp;
@@ -122,28 +127,34 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
authp->done = FALSE;
- if(neg_ctx->state == GSS_AUTHRECV) {
+ if(*state == GSS_AUTHRECV) {
if(neg_ctx->havenegdata) {
neg_ctx->havemultiplerequests = TRUE;
}
}
- else if(neg_ctx->state == GSS_AUTHSUCC) {
+ else if(*state == GSS_AUTHSUCC) {
if(!neg_ctx->havenoauthpersist) {
neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests;
}
}
if(neg_ctx->noauthpersist ||
- (neg_ctx->state != GSS_AUTHDONE && neg_ctx->state != GSS_AUTHSUCC)) {
+ (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) {
- if(neg_ctx->noauthpersist && neg_ctx->state == GSS_AUTHSUCC) {
+ if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) {
infof(conn->data, "Curl_output_negotiate, "
"no persistent authentication: cleanup existing context");
- Curl_auth_spnego_cleanup(neg_ctx);
+ Curl_http_auth_cleanup_negotiate(conn);
}
if(!neg_ctx->context) {
result = Curl_input_negotiate(conn, proxy, "Negotiate");
- if(result)
+ if(result == CURLE_LOGIN_DENIED) {
+ /* 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;
+ return CURLE_OK;
+ }
+ else if(result)
return result;
}
@@ -170,23 +181,23 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
return CURLE_OUT_OF_MEMORY;
}
- neg_ctx->state = GSS_AUTHSENT;
+ *state = GSS_AUTHSENT;
#ifdef HAVE_GSSAPI
if(neg_ctx->status == GSS_S_COMPLETE ||
neg_ctx->status == GSS_S_CONTINUE_NEEDED) {
- neg_ctx->state = GSS_AUTHDONE;
+ *state = GSS_AUTHDONE;
}
#else
#ifdef USE_WINDOWS_SSPI
if(neg_ctx->status == SEC_E_OK ||
neg_ctx->status == SEC_I_CONTINUE_NEEDED) {
- neg_ctx->state = GSS_AUTHDONE;
+ *state = GSS_AUTHDONE;
}
#endif
#endif
}
- if(neg_ctx->state == GSS_AUTHDONE || neg_ctx->state == GSS_AUTHSUCC) {
+ if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) {
/* connection is already authenticated,
* don't send a header in future requests */
authp->done = TRUE;
@@ -197,10 +208,13 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
return CURLE_OK;
}
-void Curl_cleanup_negotiate(struct connectdata *conn)
+void Curl_http_auth_cleanup_negotiate(struct connectdata *conn)
{
- Curl_auth_spnego_cleanup(&conn->negotiate);
- Curl_auth_spnego_cleanup(&conn->proxyneg);
+ conn->http_negotiate_state = GSS_AUTHNONE;
+ conn->proxy_negotiate_state = GSS_AUTHNONE;
+
+ Curl_auth_cleanup_spnego(&conn->negotiate);
+ Curl_auth_cleanup_spnego(&conn->proxyneg);
}
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h
index d4a7f09e0..4f0ac1686 100644
--- a/lib/http_negotiate.h
+++ b/lib/http_negotiate.h
@@ -22,7 +22,7 @@
*
***************************************************************************/
-#ifdef USE_SPNEGO
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
/* this is for Negotiate header input */
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
@@ -31,8 +31,8 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
/* this is for creating Negotiate header output */
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
-void Curl_cleanup_negotiate(struct connectdata *conn);
+void Curl_http_auth_cleanup_negotiate(struct connectdata *conn);
-#endif /* USE_SPNEGO */
+#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index aaf8a3deb..e4a4fe05d 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -5,7 +5,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
@@ -68,9 +68,11 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
{
/* point to the correct struct with this */
struct ntlmdata *ntlm;
+ curlntlm *state;
CURLcode result = CURLE_OK;
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
+ state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
if(checkprefix("NTLM", header)) {
header += strlen("NTLM");
@@ -83,25 +85,25 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
if(result)
return result;
- ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
+ *state = NTLMSTATE_TYPE2; /* We got a type-2 message */
}
else {
- if(ntlm->state == NTLMSTATE_LAST) {
+ if(*state == NTLMSTATE_LAST) {
infof(conn->data, "NTLM auth restarted\n");
- Curl_http_ntlm_cleanup(conn);
+ Curl_http_auth_cleanup_ntlm(conn);
}
- else if(ntlm->state == NTLMSTATE_TYPE3) {
+ else if(*state == NTLMSTATE_TYPE3) {
infof(conn->data, "NTLM handshake rejected\n");
- Curl_http_ntlm_cleanup(conn);
- ntlm->state = NTLMSTATE_NONE;
+ Curl_http_auth_cleanup_ntlm(conn);
+ *state = NTLMSTATE_NONE;
return CURLE_REMOTE_ACCESS_DENIED;
}
- else if(ntlm->state >= NTLMSTATE_TYPE1) {
+ else if(*state >= NTLMSTATE_TYPE1) {
infof(conn->data, "NTLM handshake failure (internal error)\n");
return CURLE_REMOTE_ACCESS_DENIED;
}
- ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
+ *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
}
}
@@ -129,6 +131,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
/* point to the correct struct with this */
struct ntlmdata *ntlm;
+ curlntlm *state;
struct auth *authp;
DEBUGASSERT(conn);
@@ -147,6 +150,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
hostname = conn->http_proxy.host.name;
ntlm = &conn->proxyntlm;
+ state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
}
else {
@@ -157,6 +161,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
conn->data->set.str[STRING_SERVICE_NAME] : "HTTP";
hostname = conn->host.name;
ntlm = &conn->ntlm;
+ state = &conn->http_ntlm_state;
authp = &conn->data->state.authhost;
}
authp->done = FALSE;
@@ -180,7 +185,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
#endif
#endif
- switch(ntlm->state) {
+ switch(*state) {
case NTLMSTATE_TYPE1:
default: /* for the weird cases we (re)start here */
/* Create a type-1 message */
@@ -222,7 +227,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
- ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
+ *state = NTLMSTATE_TYPE3; /* we send a type-3 */
authp->done = TRUE;
}
break;
@@ -230,7 +235,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
case NTLMSTATE_TYPE3:
/* connection is already authenticated,
* don't send a header in future requests */
- ntlm->state = NTLMSTATE_LAST;
+ *state = NTLMSTATE_LAST;
/* FALLTHROUGH */
case NTLMSTATE_LAST:
Curl_safefree(*allocuserpwd);
@@ -241,13 +246,13 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
return CURLE_OK;
}
-void Curl_http_ntlm_cleanup(struct connectdata *conn)
+void Curl_http_auth_cleanup_ntlm(struct connectdata *conn)
{
- Curl_auth_ntlm_cleanup(&conn->ntlm);
- Curl_auth_ntlm_cleanup(&conn->proxyntlm);
+ Curl_auth_cleanup_ntlm(&conn->ntlm);
+ Curl_auth_cleanup_ntlm(&conn->proxyntlm);
#if defined(NTLM_WB_ENABLED)
- Curl_ntlm_wb_cleanup(conn);
+ Curl_http_auth_cleanup_ntlm_wb(conn);
#endif
}
diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h
index d186bbe37..003714dbd 100644
--- a/lib/http_ntlm.h
+++ b/lib/http_ntlm.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_NTLM_H
-#define HEADER_CURL_NTLM_H
+#ifndef HEADER_CURL_HTTP_NTLM_H
+#define HEADER_CURL_HTTP_NTLM_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, 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
@@ -33,8 +33,8 @@ CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
-void Curl_http_ntlm_cleanup(struct connectdata *conn);
+void Curl_http_auth_cleanup_ntlm(struct connectdata *conn);
#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
-#endif /* HEADER_CURL_NTLM_H */
+#endif /* HEADER_CURL_HTTP_NTLM_H */
diff --git a/lib/if2ip.c b/lib/if2ip.c
index acbcff71e..d003de678 100644
--- a/lib/if2ip.c
+++ b/lib/if2ip.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
@@ -97,7 +97,7 @@ unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
#if defined(HAVE_GETIFADDRS)
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
- unsigned int remote_scope_id, const char *interf,
+ unsigned int local_scope_id, const char *interf,
char *buf, int buf_size)
{
struct ifaddrs *iface, *head;
@@ -109,7 +109,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
#if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \
!defined(ENABLE_IPV6)
- (void) remote_scope_id;
+ (void) local_scope_id;
#endif
if(getifaddrs(&head) >= 0) {
@@ -123,7 +123,9 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
char ipstr[64];
#ifdef ENABLE_IPV6
if(af == AF_INET6) {
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
unsigned int scopeid = 0;
+#endif
unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
if(ifscope != remote_scope) {
@@ -143,15 +145,16 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
->sin6_scope_id;
/* If given, scope id should match. */
- if(remote_scope_id && scopeid != remote_scope_id) {
+ if(local_scope_id && scopeid != local_scope_id) {
if(res == IF2IP_NOT_FOUND)
res = IF2IP_AF_NOT_SUPPORTED;
continue;
}
-#endif
+
if(scopeid)
- msnprintf(scope, sizeof(scope), "%%%u", scopeid);
+ msnprintf(scope, sizeof(scope), "%%%u", scopeid);
+#endif
}
else
#endif
@@ -179,7 +182,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
#elif defined(HAVE_IOCTL_SIOCGIFADDR)
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
- unsigned int remote_scope_id, const char *interf,
+ unsigned int local_scope_id, const char *interf,
char *buf, int buf_size)
{
struct ifreq req;
@@ -189,7 +192,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
size_t len;
(void)remote_scope;
- (void)remote_scope_id;
+ (void)local_scope_id;
if(!interf || (af != AF_INET))
return IF2IP_NOT_FOUND;
@@ -225,12 +228,12 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
#else
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
- unsigned int remote_scope_id, const char *interf,
+ unsigned int local_scope_id, const char *interf,
char *buf, int buf_size)
{
(void) af;
(void) remote_scope;
- (void) remote_scope_id;
+ (void) local_scope_id;
(void) interf;
(void) buf;
(void) buf_size;
diff --git a/lib/if2ip.h b/lib/if2ip.h
index a11b1c222..f193d4257 100644
--- a/lib/if2ip.h
+++ b/lib/if2ip.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
@@ -39,7 +39,7 @@ typedef enum {
} if2ip_result_t;
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
- unsigned int remote_scope_id, const char *interf,
+ unsigned int local_scope_id, const char *interf,
char *buf, int buf_size);
#ifdef __INTERIX
diff --git a/lib/imap.c b/lib/imap.c
index df069647f..b5236ebe4 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -28,6 +28,7 @@
* RFC4959 IMAP Extension for SASL Initial Client Response
* RFC5092 IMAP URL Scheme
* RFC6749 OAuth 2.0 Authorization Framework
+ * RFC8314 Use of TLS for Email Submission and Access
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
*
***************************************************************************/
@@ -1042,7 +1043,7 @@ static CURLcode imap_state_listsearch_resp(struct connectdata *conn,
line[len] = '\0';
}
else if(imapcode != IMAP_RESP_OK)
- result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+ result = CURLE_QUOTE_ERROR;
else
/* End of DO phase */
state(conn, IMAP_STOP);
@@ -1114,7 +1115,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
if(imapcode != '*') {
Curl_pgrsSetDownloadSize(data, -1);
state(conn, IMAP_STOP);
- return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
+ return CURLE_REMOTE_FILE_NOT_FOUND;
}
/* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse
@@ -1491,12 +1492,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
state(conn, IMAP_APPEND_FINAL);
}
- /* Run the state-machine
-
- TODO: when the multi interface is used, this _really_ should be using
- the imap_multi_statemach function but we have no general support for
- non-blocking DONE operations!
- */
+ /* Run the state-machine */
if(!result)
result = imap_block_statemach(conn, FALSE);
}
@@ -1794,7 +1790,7 @@ static char *imap_atom(const char *str, bool escape_only)
return NULL;
/* Look for "atom-specials", counting the backslash and quote characters as
- these will need escapping */
+ these will need escaping */
p1 = str;
while(*p1) {
if(*p1 == '\\')
diff --git a/lib/inet_pton.c b/lib/inet_pton.c
index fef9610d1..0d65ae0ec 100644
--- a/lib/inet_pton.c
+++ b/lib/inet_pton.c
@@ -153,7 +153,7 @@ inet_pton6(const char *src, unsigned char *dst)
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
- const char *xdigits, *curtok;
+ const char *curtok;
int ch, saw_xdigit;
size_t val;
@@ -168,6 +168,7 @@ inet_pton6(const char *src, unsigned char *dst)
saw_xdigit = 0;
val = 0;
while((ch = *src++) != '\0') {
+ const char *xdigits;
const char *pch;
pch = strchr((xdigits = xdigits_l), ch);
diff --git a/lib/ldap.c b/lib/ldap.c
index 734a4ae24..66ec35236 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -1069,8 +1069,6 @@ static int _ldap_url_parse(const struct connectdata *conn,
static void _ldap_free_urldesc(LDAPURLDesc *ludp)
{
- size_t i;
-
if(!ludp)
return;
@@ -1078,6 +1076,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp)
free(ludp->lud_filter);
if(ludp->lud_attrs) {
+ size_t i;
for(i = 0; i < ludp->lud_attrs_dups; i++)
free(ludp->lud_attrs[i]);
free(ludp->lud_attrs);
diff --git a/lib/md4.c b/lib/md4.c
index 4691904be..e7c77bc36 100644
--- a/lib/md4.c
+++ b/lib/md4.c
@@ -38,9 +38,11 @@
#include "curl_setup.h"
-/* The NSS, OS/400 and sometimes mbed TLS crypto libraries do not provide the
- * MD4 hash algorithm, so we have a local implementation of it */
+/* 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"
@@ -113,7 +115,6 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD4_u32plus a, b, c, d;
- MD4_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
@@ -123,6 +124,8 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
d = ctx->d;
do {
+ MD4_u32plus saved_a, saved_b, saved_c, saved_d;
+
saved_a = a;
saved_b = b;
saved_c = c;
@@ -130,59 +133,59 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 3)
- STEP(F, d, a, b, c, SET(1), 7)
- STEP(F, c, d, a, b, SET(2), 11)
- STEP(F, b, c, d, a, SET(3), 19)
- STEP(F, a, b, c, d, SET(4), 3)
- STEP(F, d, a, b, c, SET(5), 7)
- STEP(F, c, d, a, b, SET(6), 11)
- STEP(F, b, c, d, a, SET(7), 19)
- STEP(F, a, b, c, d, SET(8), 3)
- STEP(F, d, a, b, c, SET(9), 7)
- STEP(F, c, d, a, b, SET(10), 11)
- STEP(F, b, c, d, a, SET(11), 19)
- STEP(F, a, b, c, d, SET(12), 3)
- STEP(F, d, a, b, c, SET(13), 7)
- STEP(F, c, d, a, b, SET(14), 11)
- STEP(F, b, c, d, a, SET(15), 19)
+ STEP(F, d, a, b, c, SET(1), 7)
+ STEP(F, c, d, a, b, SET(2), 11)
+ STEP(F, b, c, d, a, SET(3), 19)
+ STEP(F, a, b, c, d, SET(4), 3)
+ STEP(F, d, a, b, c, SET(5), 7)
+ STEP(F, c, d, a, b, SET(6), 11)
+ STEP(F, b, c, d, a, SET(7), 19)
+ STEP(F, a, b, c, d, SET(8), 3)
+ STEP(F, d, a, b, c, SET(9), 7)
+ STEP(F, c, d, a, b, SET(10), 11)
+ STEP(F, b, c, d, a, SET(11), 19)
+ STEP(F, a, b, c, d, SET(12), 3)
+ STEP(F, d, a, b, c, SET(13), 7)
+ STEP(F, c, d, a, b, SET(14), 11)
+ STEP(F, b, c, d, a, SET(15), 19)
/* Round 2 */
- STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
- STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
- STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
- STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
- STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
- STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
- STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
- STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
- STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
- STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
- STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
- STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
- STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
- STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
- STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
- STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
/* Round 3 */
- STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
- STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
- STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
- STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
- STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
- STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
- STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
- STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
- STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
- STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
- STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
- STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
- STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
- STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
- STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
- STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
-
- a += saved_a;
+ STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
+ STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
+ STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
+ STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
+
+ a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
@@ -212,7 +215,7 @@ static void MD4_Init(MD4_CTX *ctx)
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
{
MD4_u32plus saved_lo;
- unsigned long used, available;
+ unsigned long used;
saved_lo = ctx->lo;
ctx->lo = (saved_lo + size) & 0x1fffffff;
@@ -223,7 +226,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
used = saved_lo & 0x3f;
if(used) {
- available = 64 - used;
+ unsigned long available = 64 - used;
if(size < available) {
memcpy(&ctx->buffer[used], data, size);
@@ -304,5 +307,7 @@ void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
MD4_Update(&ctx, input, curlx_uztoui(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)) */
diff --git a/lib/md5.c b/lib/md5.c
index f88688b34..8811f4429 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -39,19 +39,19 @@
typedef struct md5_ctx MD5_CTX;
-static void MD5_Init(MD5_CTX * ctx)
+static void MD5_Init(MD5_CTX *ctx)
{
md5_init(ctx);
}
-static void MD5_Update(MD5_CTX * ctx,
+static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
md5_update(ctx, inputLen, input);
}
-static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
md5_digest(ctx, 16, digest);
}
@@ -65,19 +65,19 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
typedef gcry_md_hd_t MD5_CTX;
-static void MD5_Init(MD5_CTX * ctx)
+static void MD5_Init(MD5_CTX *ctx)
{
gcry_md_open(ctx, GCRY_MD_MD5, 0);
}
-static void MD5_Update(MD5_CTX * ctx,
+static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
gcry_md_write(*ctx, input, inputLen);
}
-static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
memcpy(digest, gcry_md_read(*ctx, 0), 16);
gcry_md_close(*ctx);
@@ -124,7 +124,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
CC_MD5_Final(digest, ctx);
}
-#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
+#elif defined(WIN32) && !defined(CURL_WINDOWS_APP)
#include <wincrypt.h>
#include "curl_memory.h"
@@ -275,7 +275,6 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
- MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
@@ -285,6 +284,8 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
d = ctx->d;
do {
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
saved_a = a;
saved_b = b;
saved_c = c;
@@ -292,77 +293,77 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
- STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
- STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
- STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
- STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
- STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
- STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
- STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
- STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
- STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
- STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
- STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
- STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
- STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
- STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
- STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
- STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
- STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
- STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
- STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
- STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
- STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
- STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
- STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
- STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
- STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
- STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
- STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
- STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
- STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
- STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
- STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
- STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
- STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
- STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
- STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
- STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
- STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
- STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
- STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
- STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
- STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
- STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
- STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
- STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
- STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
- STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
- STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
- STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
- STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
- STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
- STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
- STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
- STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
- STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
- STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
- STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
- STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
- STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
- STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
- STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
- STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
- STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
- STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
-
- a += saved_a;
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
@@ -392,7 +393,7 @@ static void MD5_Init(MD5_CTX *ctx)
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
- unsigned long used, available;
+ unsigned long used;
saved_lo = ctx->lo;
ctx->lo = (saved_lo + size) & 0x1fffffff;
@@ -403,7 +404,7 @@ static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
used = saved_lo & 0x3f;
if(used) {
- available = 64 - used;
+ unsigned long available = 64 - used;
if(size < available) {
memcpy(&ctx->buffer[used], data, size);
@@ -545,23 +546,23 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
return ctxt;
}
-int Curl_MD5_update(MD5_context *context,
- const unsigned char *data,
- unsigned int len)
+CURLcode Curl_MD5_update(MD5_context *context,
+ const unsigned char *data,
+ unsigned int len)
{
(*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
- return 0;
+ return CURLE_OK;
}
-int Curl_MD5_final(MD5_context *context, unsigned char *result)
+CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result)
{
(*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
free(context->md5_hashctx);
free(context);
- return 0;
+ return CURLE_OK;
}
#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/lib/memdebug.c b/lib/memdebug.c
index 639a9bb45..c3635772b 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -114,8 +114,8 @@ void curl_dbg_memdebug(const char *logname)
curl_dbg_logfile = stderr;
#ifdef MEMDEBUG_LOG_SYNC
/* Flush the log file after every line so the log isn't lost in a crash */
- if(logfile)
- setbuf(logfile, (char *)NULL);
+ if(curl_dbg_logfile)
+ setbuf(curl_dbg_logfile, (char *)NULL);
#endif
}
}
@@ -306,9 +306,8 @@ void *curl_dbg_realloc(void *ptr, size_t wantedsize,
void curl_dbg_free(void *ptr, int line, const char *source)
{
- struct memdebug *mem;
-
if(ptr) {
+ struct memdebug *mem;
#ifdef __INTEL_COMPILER
# pragma warning(push)
diff --git a/lib/mime.c b/lib/mime.c
index 4f6789398..eb77cbddd 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -29,8 +29,8 @@
#include "urldata.h"
#include "sendf.h"
-#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
- !defined(CURL_DISABLE_IMAP)
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
+ !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
@@ -821,8 +821,10 @@ static size_t readback_part(curl_mimepart *part,
struct curl_slist *hdr = (struct curl_slist *) part->state.ptr;
switch(part->state.state) {
case MIMESTATE_BEGIN:
- mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
- MIMESTATE_CURLHEADERS, part->curlheaders);
+ mimesetstate(&part->state,
+ (part->flags & MIME_BODY_ONLY)?
+ MIMESTATE_BODY: MIMESTATE_CURLHEADERS,
+ part->curlheaders);
break;
case MIMESTATE_USERHEADERS:
if(!hdr) {
@@ -1899,72 +1901,4 @@ CURLcode curl_mime_headers(curl_mimepart *part,
return CURLE_NOT_BUILT_IN;
}
-void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
-{
- (void) part;
- (void) easy;
-}
-
-void Curl_mime_cleanpart(curl_mimepart *part)
-{
- (void) part;
-}
-
-CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src)
-{
- (void) dst;
- (void) src;
- return CURLE_OK; /* Nothing to duplicate: always succeed. */
-}
-
-CURLcode Curl_mime_set_subparts(curl_mimepart *part,
- curl_mime *subparts, int take_ownership)
-{
- (void) part;
- (void) subparts;
- (void) take_ownership;
- return CURLE_NOT_BUILT_IN;
-}
-
-CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
- const char *contenttype,
- const char *disposition,
- enum mimestrategy strategy)
-{
- (void) part;
- (void) contenttype;
- (void) disposition;
- (void) strategy;
- return CURLE_NOT_BUILT_IN;
-}
-
-curl_off_t Curl_mime_size(curl_mimepart *part)
-{
- (void) part;
- return (curl_off_t) -1;
-}
-
-size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
-{
- (void) buffer;
- (void) size;
- (void) nitems;
- (void) instream;
- return 0;
-}
-
-CURLcode Curl_mime_rewind(curl_mimepart *part)
-{
- (void) part;
- return CURLE_NOT_BUILT_IN;
-}
-
-/* VARARGS2 */
-CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
-{
- (void) slp;
- (void) fmt;
- return CURLE_NOT_BUILT_IN;
-}
-
-#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
+#endif /* if disabled */
diff --git a/lib/mime.h b/lib/mime.h
index 0721c8ca4..4c9a5fb71 100644
--- a/lib/mime.h
+++ b/lib/mime.h
@@ -22,6 +22,8 @@
*
***************************************************************************/
+#include "curl_setup.h"
+
#define MIME_RAND_BOUNDARY_CHARS 16 /* Nb. of random boundary chars. */
#define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */
#define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */
@@ -69,7 +71,7 @@ enum mimestrategy {
typedef struct {
const char * name; /* Encoding name. */
size_t (*encodefunc)(char *buffer, size_t size, bool ateof,
- curl_mimepart *part); /* Encoded read. */
+ curl_mimepart *part); /* Encoded read. */
curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */
} mime_encoder;
@@ -125,6 +127,8 @@ struct curl_mimepart_s {
mime_encoder_state encstate; /* Data encoder state. */
};
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
+ !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
/* Prototypes. */
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
@@ -143,4 +147,18 @@ CURLcode Curl_mime_rewind(curl_mimepart *part);
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
const char *Curl_mime_contenttype(const char *filename);
+#else
+/* if disabled */
+#define Curl_mime_initpart(x,y)
+#define Curl_mime_cleanpart(x)
+#define Curl_mime_duppart(x,y) CURLE_OK /* Nothing to duplicate. Succeed */
+#define Curl_mime_set_subparts(a,b,c) CURLE_NOT_BUILT_IN
+#define Curl_mime_prepare_headers(a,b,c,d) CURLE_NOT_BUILT_IN
+#define Curl_mime_size(x) (curl_off_t) -1
+#define Curl_mime_read NULL
+#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define Curl_mime_add_header(x,y,...) CURLE_NOT_BUILT_IN
+#endif
+
+
#endif /* HEADER_CURL_MIME_H */
diff --git a/lib/multi.c b/lib/multi.c
index a3422c2ad..fa6e8f31a 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -41,7 +41,6 @@
#include "speedcheck.h"
#include "conncache.h"
#include "multihandle.h"
-#include "pipeline.h"
#include "sigpipe.h"
#include "vtls/vtls.h"
#include "connect.h"
@@ -92,12 +91,10 @@ static const char * const statename[]={
"WAITPROXYCONNECT",
"SENDPROTOCONNECT",
"PROTOCONNECT",
- "WAITDO",
"DO",
"DOING",
"DO_MORE",
"DO_DONE",
- "WAITPERFORM",
"PERFORM",
"TOOFAST",
"DONE",
@@ -136,12 +133,10 @@ static void mstate(struct Curl_easy *data, CURLMstate state
NULL, /* WAITPROXYCONNECT */
NULL, /* SENDPROTOCONNECT */
NULL, /* PROTOCONNECT */
- NULL, /* WAITDO */
Curl_connect_free, /* DO */
NULL, /* DOING */
NULL, /* DO_MORE */
NULL, /* DO_DONE */
- NULL, /* WAITPERFORM */
NULL, /* PERFORM */
NULL, /* TOOFAST */
NULL, /* DONE */
@@ -349,9 +344,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
Curl_llist_init(&multi->msglist, multi_freeamsg);
Curl_llist_init(&multi->pending, multi_freeamsg);
- multi->max_pipeline_length = 5;
- multi->pipelining = CURLPIPE_MULTIPLEX;
-
/* -1 means it not set by user, use the default value */
multi->maxconnects = -1;
return multi;
@@ -408,19 +400,9 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
/* set the easy handle */
multistate(data, CURLM_STATE_INIT);
- if((data->set.global_dns_cache) &&
- (data->dns.hostcachetype != HCACHE_GLOBAL)) {
- /* global dns cache was requested but still isn't */
- struct curl_hash *global = Curl_global_host_cache_init();
- if(global) {
- /* only do this if the global cache init works */
- data->dns.hostcache = global;
- data->dns.hostcachetype = HCACHE_GLOBAL;
- }
- }
/* for multi interface connections, we share DNS cache automatically if the
easy handle's one is currently not set. */
- else if(!data->dns.hostcache ||
+ if(!data->dns.hostcache ||
(data->dns.hostcachetype == HCACHE_NONE)) {
data->dns.hostcache = &multi->hostcache;
data->dns.hostcachetype = HCACHE_MULTI;
@@ -440,12 +422,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->psl = &multi->psl;
#endif
- /* This adds the new entry at the 'end' of the doubly-linked circular
- list of Curl_easy structs to try and maintain a FIFO queue so
- the pipelined requests are in order. */
-
- /* We add this new entry last in the list. */
-
+ /* We add the new entry last in the list. */
data->next = NULL; /* end of the line */
if(multi->easyp) {
struct Curl_easy *last = multi->easylp;
@@ -497,8 +474,6 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->set.server_response_timeout;
data->state.conn_cache->closure_handle->set.no_signal =
data->set.no_signal;
- data->state.conn_cache->closure_handle->set.verbose =
- data->set.verbose;
update_timer(multi);
return CURLM_OK;
@@ -538,8 +513,6 @@ static CURLcode multi_done(struct Curl_easy *data,
/* Stop the resolver and free its own resources (but not dns_entry yet). */
Curl_resolver_kill(conn);
- Curl_getoff_all_pipelines(data, conn);
-
/* Cleanup possible redirect junk */
Curl_safefree(data->req.newurl);
Curl_safefree(data->req.location);
@@ -573,12 +546,12 @@ static CURLcode multi_done(struct Curl_easy *data,
process_pending_handles(data->multi); /* connection / multiplex */
- if(conn->send_pipe.size || conn->recv_pipe.size) {
- /* Stop if pipeline is not empty . */
- detach_connnection(data);
- DEBUGF(infof(data, "Connection still in use %zu/%zu, "
+ detach_connnection(data);
+ if(CONN_INUSE(conn)) {
+ /* Stop if still used. */
+ DEBUGF(infof(data, "Connection still in use %zu, "
"no more multi_done now!\n",
- conn->send_pipe.size, conn->recv_pipe.size));
+ conn->easyq.size));
return CURLE_OK;
}
@@ -615,12 +588,12 @@ static CURLcode multi_done(struct Curl_easy *data,
if((data->set.reuse_forbid
#if defined(USE_NTLM)
- && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
- conn->proxyntlm.state == NTLMSTATE_TYPE2)
+ && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
+ conn->proxy_ntlm_state == NTLMSTATE_TYPE2)
#endif
#if defined(USE_SPNEGO)
- && !(conn->negotiate.state == GSS_AUTHRECV ||
- conn->proxyneg.state == GSS_AUTHRECV)
+ && !(conn->http_negotiate_state == GSS_AUTHRECV ||
+ conn->proxy_negotiate_state == GSS_AUTHRECV)
#endif
) || conn->bits.close
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
@@ -652,7 +625,6 @@ static CURLcode multi_done(struct Curl_easy *data,
data->state.lastconnect = NULL;
}
- detach_connnection(data);
Curl_free_request_state(data);
return result;
}
@@ -698,9 +670,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
/* Set connection owner so that the DONE function closes it. We can
safely do this here since connection is killed. */
data->conn->data = easy;
- /* If the handle is in a pipeline and has started sending off its
- request but not received its response yet, we need to close
- connection. */
streamclose(data->conn, "Removed with partial response");
easy_owns_conn = TRUE;
}
@@ -723,9 +692,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
nothing really useful to do with it anyway! */
(void)multi_done(data, data->result, premature);
}
- else
- /* Clear connection pipelines, if multi_done above was not called */
- Curl_getoff_all_pipelines(data, data->conn);
}
if(data->connect_queue.ptr)
@@ -803,16 +769,19 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
return CURLM_OK;
}
-/* Return TRUE if the application asked for a certain set of pipelining */
-bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
+/* Return TRUE if the application asked for multiplexing */
+bool Curl_multiplex_wanted(const struct Curl_multi *multi)
{
- return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
+ return (multi && (multi->multiplexing));
}
/* This is the only function that should clear data->conn. This will
occasionally be called with the pointer already cleared. */
static void detach_connnection(struct Curl_easy *data)
{
+ struct connectdata *conn = data->conn;
+ if(conn)
+ Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
data->conn = NULL;
}
@@ -821,7 +790,10 @@ void Curl_attach_connnection(struct Curl_easy *data,
struct connectdata *conn)
{
DEBUGASSERT(!data->conn);
+ DEBUGASSERT(conn);
data->conn = conn;
+ Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data,
+ &data->conn_queue);
}
static int waitconnect_getsock(struct connectdata *conn,
@@ -935,7 +907,6 @@ static int multi_getsock(struct Curl_easy *data,
to waiting for the same as the *PERFORM
states */
case CURLM_STATE_PERFORM:
- case CURLM_STATE_WAITPERFORM:
return Curl_single_getsock(data->conn, socks, numsocks);
}
@@ -1203,7 +1174,7 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
* do_complete is called when the DO actions are complete.
*
* We init chunking and trailer bits to their default values here immediately
- * before receiving any header data for the current request in the pipeline.
+ * before receiving any header data for the current request.
*/
static void do_complete(struct connectdata *conn)
{
@@ -1216,6 +1187,9 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
CURLcode result = CURLE_OK;
struct connectdata *conn = data->conn;
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->handler);
+
if(conn->handler->do_it) {
/* generic protocol-specific function pointer set in curl_connect() */
result = conn->handler->do_it(conn, done);
@@ -1232,8 +1206,6 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
* second stage DO state which (wrongly) was introduced to support FTP's
* second connection.
*
- * TODO: A future libcurl should be able to work away this state.
- *
* 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
* DOING state there's more work to do!
*/
@@ -1266,7 +1238,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
bool done = FALSE;
CURLMcode rc;
CURLcode result = CURLE_OK;
- struct SingleRequest *k;
timediff_t timeout_ms;
timediff_t recv_timeout_ms;
timediff_t send_timeout_ms;
@@ -1293,7 +1264,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(multi_ischanged(multi, TRUE)) {
DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
- process_pending_handles(multi); /* pipelined/multiplexed */
+ process_pending_handles(multi); /* multiplexed */
}
if(data->conn && data->mstate > CURLM_STATE_CONNECT &&
@@ -1308,7 +1279,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* we need to wait for the connect state as only then is the start time
stored, but we must not check already completed handles */
timeout_ms = Curl_timeleft(data, &now,
- (data->mstate <= CURLM_STATE_WAITDO)?
+ (data->mstate <= CURLM_STATE_DO)?
TRUE:FALSE);
if(timeout_ms < 0) {
@@ -1322,7 +1293,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
" milliseconds",
Curl_timediff(now, data->progress.t_startsingle));
else {
- k = &data->req;
+ struct SingleRequest *k = &data->req;
if(k->size != -1) {
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
" milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
@@ -1390,33 +1361,31 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = CURLE_OK;
break;
}
+ else if(data->state.previouslypending) {
+ /* this transfer comes from the pending queue so try move another */
+ infof(data, "Transfer was pending, now try another\n");
+ process_pending_handles(data->multi);
+ }
if(!result) {
- /* Add this handle to the send or pend pipeline */
- result = Curl_add_handle_to_pipeline(data, data->conn);
- if(result)
- stream_error = TRUE;
+ if(async)
+ /* We're now waiting for an asynchronous name lookup */
+ multistate(data, CURLM_STATE_WAITRESOLVE);
else {
- if(async)
- /* We're now waiting for an asynchronous name lookup */
- multistate(data, CURLM_STATE_WAITRESOLVE);
- else {
- /* after the connect has been sent off, go WAITCONNECT unless the
- protocol connect is already done and we can go directly to
- WAITDO or DO! */
- rc = CURLM_CALL_MULTI_PERFORM;
+ /* after the connect has been sent off, go WAITCONNECT unless the
+ protocol connect is already done and we can go directly to
+ WAITDO or DO! */
+ rc = CURLM_CALL_MULTI_PERFORM;
- if(protocol_connect)
- multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
- CURLM_STATE_WAITDO:CURLM_STATE_DO);
- else {
+ if(protocol_connect)
+ multistate(data, CURLM_STATE_DO);
+ else {
#ifndef CURL_DISABLE_HTTP
- if(Curl_connect_ongoing(data->conn))
- multistate(data, CURLM_STATE_WAITPROXYCONNECT);
- else
+ if(Curl_connect_ongoing(data->conn))
+ multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+ else
#endif
- multistate(data, CURLM_STATE_WAITCONNECT);
- }
+ multistate(data, CURLM_STATE_WAITCONNECT);
}
}
}
@@ -1429,6 +1398,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct connectdata *conn = data->conn;
const char *hostname;
+ DEBUGASSERT(conn);
if(conn->bits.httpproxy)
hostname = conn->http_proxy.host.name;
else if(conn->bits.conn_to_host)
@@ -1467,13 +1437,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(result)
/* if Curl_once_resolved() returns failure, the connection struct
is already freed and gone */
- detach_connnection(data); /* no more connection */
+ data->conn = NULL; /* no more connection */
else {
/* call again please so that we get the next socket setup */
rc = CURLM_CALL_MULTI_PERFORM;
if(protocol_connect)
- multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
- CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ multistate(data, CURLM_STATE_DO);
else {
#ifndef CURL_DISABLE_HTTP
if(Curl_connect_ongoing(data->conn))
@@ -1496,6 +1465,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
#ifndef CURL_DISABLE_HTTP
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);
if(data->conn->bits.proxy_connect_closed) {
@@ -1521,6 +1491,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case CURLM_STATE_WAITCONNECT:
/* awaiting a completion of an asynch TCP connect */
+ DEBUGASSERT(data->conn);
result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected);
if(connected && !result) {
#ifndef CURL_DISABLE_HTTP
@@ -1552,8 +1523,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, CURLM_STATE_PROTOCONNECT);
else if(!result) {
/* protocol connect has completed, go WAITDO or DO */
- multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
- CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ multistate(data, CURLM_STATE_DO);
rc = CURLM_CALL_MULTI_PERFORM;
}
else if(result) {
@@ -1569,8 +1539,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = Curl_protocol_connecting(data->conn, &protocol_connect);
if(!result && protocol_connect) {
/* after the connect has completed, go WAITDO or DO */
- multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
- CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ multistate(data, CURLM_STATE_DO);
rc = CURLM_CALL_MULTI_PERFORM;
}
else if(result) {
@@ -1581,15 +1550,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
break;
- case CURLM_STATE_WAITDO:
- /* Wait for our turn to DO when we're pipelining requests */
- if(Curl_pipeline_checkget_write(data, data->conn)) {
- /* Grabbed the channel */
- multistate(data, CURLM_STATE_DO);
- rc = CURLM_CALL_MULTI_PERFORM;
- }
- break;
-
case CURLM_STATE_DO:
if(data->set.connect_only) {
/* keep connection open for application to use the socket */
@@ -1606,6 +1566,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(!result) {
if(!dophase_done) {
+#ifndef CURL_DISABLE_FTP
/* some steps needed for wildcard matching */
if(data->state.wildcardmatch) {
struct WildcardData *wc = &data->wildcard;
@@ -1617,6 +1578,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
}
}
+#endif
/* DO was not completed in one function call, we must continue
DOING... */
multistate(data, CURLM_STATE_DOING);
@@ -1696,6 +1658,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);
if(!result) {
@@ -1719,10 +1682,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/*
* When we are connected, DO MORE and then go DO_DONE
*/
+ DEBUGASSERT(data->conn);
result = multi_do_more(data->conn, &control);
- /* No need to remove this handle from the send pipeline here since that
- is done in multi_done() */
if(!result) {
if(control) {
/* if positive, advance to DO_DONE
@@ -1745,38 +1707,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
case CURLM_STATE_DO_DONE:
- /* Move ourselves from the send to recv pipeline */
- Curl_move_handle_from_send_to_recv_pipe(data, data->conn);
-
- if(data->conn->bits.multiplex || data->conn->send_pipe.size)
+ DEBUGASSERT(data->conn);
+ if(data->conn->bits.multiplex)
/* Check if we can move pending requests to send pipe */
- process_pending_handles(multi); /* pipelined/multiplexed */
+ process_pending_handles(multi); /* multiplexed */
/* Only perform the transfer if there's a good socket to work with.
Having both BAD is a signal to skip immediately to DONE */
if((data->conn->sockfd != CURL_SOCKET_BAD) ||
(data->conn->writesockfd != CURL_SOCKET_BAD))
- multistate(data, CURLM_STATE_WAITPERFORM);
+ multistate(data, CURLM_STATE_PERFORM);
else {
+#ifndef CURL_DISABLE_FTP
if(data->state.wildcardmatch &&
((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
- data->wildcard.state = CURLWC_DONE;
+ data->wildcard.state = CURLWC_DONE;
}
+#endif
multistate(data, CURLM_STATE_DONE);
}
rc = CURLM_CALL_MULTI_PERFORM;
break;
- case CURLM_STATE_WAITPERFORM:
- /* Wait for our turn to PERFORM */
- if(Curl_pipeline_checkget_read(data, data->conn)) {
- /* Grabbed the channel */
- multistate(data, CURLM_STATE_PERFORM);
- rc = CURLM_CALL_MULTI_PERFORM;
- }
- break;
-
case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
+ DEBUGASSERT(data->conn);
/* if both rates are within spec, resume transfer */
if(Curl_pgrsUpdate(data->conn))
result = CURLE_ABORTED_BY_CALLBACK;
@@ -1850,18 +1804,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* read/write data if it is ready to do so */
result = Curl_readwrite(data->conn, data, &done, &comeback);
- k = &data->req;
-
- if(!(k->keepon & KEEP_RECV)) {
- /* We're done receiving */
- Curl_pipeline_leave_read(data->conn);
- }
-
- if(!(k->keepon & KEEP_SEND)) {
- /* We're done sending */
- Curl_pipeline_leave_write(data->conn);
- }
-
if(done || (result == CURLE_RECV_ERROR)) {
/* If CURLE_RECV_ERROR happens early enough, we assume it was a race
* condition and the server closed the re-used connection exactly when
@@ -1881,23 +1823,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
}
else if((CURLE_HTTP2_STREAM == result) &&
- Curl_h2_http_1_1_error(data->conn)) {
+ Curl_h2_http_1_1_error(data->conn)) {
CURLcode ret = Curl_retry_request(data->conn, &newurl);
- infof(data, "Forcing HTTP/1.1 for NTLM");
- data->set.httpversion = CURL_HTTP_VERSION_1_1;
-
- if(!ret)
- retry = (newurl)?TRUE:FALSE;
- else
- result = ret;
-
- if(retry) {
- /* if we are to retry, set the result to OK and consider the
- request as done */
+ if(!ret) {
+ infof(data, "Downgrades to HTTP/1.1!\n");
+ data->set.httpversion = CURL_HTTP_VERSION_1_1;
+ /* clear the error message bit too as we ignore the one we got */
+ data->state.errorbuf = FALSE;
+ if(!newurl)
+ /* typically for HTTP_1_1_REQUIRED error on first flight */
+ newurl = strdup(data->change.url);
+ /* if we are to retry, set the result to OK and consider the request
+ as done */
+ retry = TRUE;
result = CURLE_OK;
done = TRUE;
}
+ else
+ result = ret;
}
if(result) {
@@ -1922,13 +1866,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* call this even if the readwrite function returned error */
Curl_posttransfer(data);
- /* we're no longer receiving */
- Curl_removeHandleFromPipeline(data, &data->conn->recv_pipe);
-
- /* expire the new receiving pipeline head */
- if(data->conn->recv_pipe.head)
- Curl_expire(data->conn->recv_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
-
/* When we follow redirects or is set to retry the connection, we must
to go back to the CONNECT state */
if(data->req.newurl || retry) {
@@ -1942,13 +1879,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
else
follow = FOLLOW_RETRY;
- result = multi_done(data, CURLE_OK, FALSE);
+ (void)multi_done(data, CURLE_OK, FALSE);
+ /* multi_done() might return CURLE_GOT_NOTHING */
+ result = Curl_follow(data, newurl, follow);
if(!result) {
- result = Curl_follow(data, newurl, follow);
- if(!result) {
- multistate(data, CURLM_STATE_CONNECT);
- rc = CURLM_CALL_MULTI_PERFORM;
- }
+ multistate(data, CURLM_STATE_CONNECT);
+ rc = CURLM_CALL_MULTI_PERFORM;
}
free(newurl);
}
@@ -1987,12 +1923,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(data->conn) {
CURLcode res;
- /* Remove ourselves from the receive pipeline, if we are there. */
- Curl_removeHandleFromPipeline(data, &data->conn->recv_pipe);
-
- if(data->conn->bits.multiplex || data->conn->send_pipe.size)
+ if(data->conn->bits.multiplex)
/* Check if we can move pending requests to connection */
- process_pending_handles(multi); /* pipelined/multiplexing */
+ process_pending_handles(multi); /* multiplexing */
/* post-transfer command */
res = multi_done(data, result, FALSE);
@@ -2002,7 +1935,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
result = res;
/*
- * If there are other handles on the pipeline, multi_done won't set
+ * If there are other handles on the connection, multi_done won't set
* conn to NULL. In such a case, curl_multi_remove_handle() can
* access free'd data, if the connection is free'd and the handle
* removed before we perform the processing in CURLM_STATE_COMPLETED
@@ -2011,6 +1944,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
detach_connnection(data);
}
+#ifndef CURL_DISABLE_FTP
if(data->state.wildcardmatch) {
if(data->wildcard.state != CURLWC_DONE) {
/* if a wildcard is set and we are not ending -> lets start again
@@ -2019,7 +1953,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
}
}
-
+#endif
/* after we have DONE what we're supposed to do, go COMPLETED, and
it doesn't matter what the multi_done() returned! */
multistate(data, CURLM_STATE_COMPLETED);
@@ -2051,12 +1985,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
process_pending_handles(multi); /* connection */
if(data->conn) {
- /* if this has a connection, unsubscribe from the pipelines */
- Curl_pipeline_leave_write(data->conn);
- Curl_pipeline_leave_read(data->conn);
- Curl_removeHandleFromPipeline(data, &data->conn->send_pipe);
- Curl_removeHandleFromPipeline(data, &data->conn->recv_pipe);
-
if(stream_error) {
/* Don't attempt to send data over a connection that timed out */
bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
@@ -2217,12 +2145,6 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_hash_destroy(&multi->hostcache);
Curl_psl_destroy(&multi->psl);
-
- /* Free the blacklists by setting them to NULL */
- (void)Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
- (void)Curl_pipeline_set_server_blacklist(NULL,
- &multi->pipelining_server_bl);
-
free(multi);
return CURLM_OK;
@@ -2575,19 +2497,6 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* bad bad bad bad bad bad bad */
return CURLM_INTERNAL_ERROR;
- /* If the pipeline is enabled, take the handle which is in the head of
- the pipeline. If we should write into the socket, take the
- send_pipe head. If we should read from the socket, take the
- recv_pipe head. */
- if(data->conn) {
- if((ev_bitmask & CURL_POLL_OUT) &&
- data->conn->send_pipe.head)
- data = data->conn->send_pipe.head->ptr;
- else if((ev_bitmask & CURL_POLL_IN) &&
- data->conn->recv_pipe.head)
- data = data->conn->recv_pipe.head->ptr;
- }
-
if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
/* set socket event bitmask if they're not locked */
data->conn->cselect_bits = ev_bitmask;
@@ -2694,7 +2603,7 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
multi->push_userp = va_arg(param, void *);
break;
case CURLMOPT_PIPELINING:
- multi->pipelining = va_arg(param, long) & CURLPIPE_MULTIPLEX;
+ multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX;
break;
case CURLMOPT_TIMERFUNCTION:
multi->timer_cb = va_arg(param, curl_multi_timer_callback);
@@ -2708,25 +2617,19 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
case CURLMOPT_MAX_HOST_CONNECTIONS:
multi->max_host_connections = va_arg(param, long);
break;
+ case CURLMOPT_MAX_TOTAL_CONNECTIONS:
+ multi->max_total_connections = va_arg(param, long);
+ break;
+ /* options formerly used for pipelining */
case CURLMOPT_MAX_PIPELINE_LENGTH:
- multi->max_pipeline_length = va_arg(param, long);
break;
case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
- multi->content_length_penalty_size = va_arg(param, long);
break;
case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
- multi->chunk_length_penalty_size = va_arg(param, long);
break;
case CURLMOPT_PIPELINING_SITE_BL:
- res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
- &multi->pipelining_site_bl);
break;
case CURLMOPT_PIPELINING_SERVER_BL:
- res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
- &multi->pipelining_server_bl);
- break;
- case CURLMOPT_MAX_TOTAL_CONNECTIONS:
- multi->max_total_connections = va_arg(param, long);
break;
default:
res = CURLM_UNKNOWN_OPTION;
@@ -3079,24 +2982,20 @@ size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
return multi ? multi->max_total_connections : 0;
}
-curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
-{
- return multi ? multi->content_length_penalty_size : 0;
-}
-
-curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
-{
- return multi ? multi->chunk_length_penalty_size : 0;
-}
+/*
+ * When information about a connection has appeared, call this!
+ */
-struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
+void Curl_multiuse_state(struct connectdata *conn,
+ int bundlestate) /* use BUNDLE_* defines */
{
- return &multi->pipelining_site_bl;
-}
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->bundle);
+ DEBUGASSERT(conn->data);
+ DEBUGASSERT(conn->data->multi);
-struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
-{
- return &multi->pipelining_server_bl;
+ conn->bundle->multiuse = bundlestate;
+ process_pending_handles(conn->data->multi);
}
static void process_pending_handles(struct Curl_multi *multi)
@@ -3114,6 +3013,9 @@ static void process_pending_handles(struct Curl_multi *multi)
/* Make sure that the handle will be processed soonish. */
Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+ /* mark this as having been in the pending queue */
+ data->state.previouslypending = TRUE;
}
}
@@ -3157,8 +3059,8 @@ void Curl_multi_dump(struct Curl_multi *multi)
continue;
}
fprintf(stderr, "[%s %s] ",
- entry->action&CURL_POLL_IN?"RECVING":"",
- entry->action&CURL_POLL_OUT?"SENDING":"");
+ (entry->action&CURL_POLL_IN)?"RECVING":"",
+ (entry->action&CURL_POLL_OUT)?"SENDING":"");
}
if(data->numsocks)
fprintf(stderr, "\n");
diff --git a/lib/multihandle.h b/lib/multihandle.h
index ea2bf352d..279379ae0 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.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
@@ -46,18 +46,16 @@ typedef enum {
CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
phase */
- CURLM_STATE_WAITDO, /* 8 - wait for our turn to send the request */
- CURLM_STATE_DO, /* 9 - start send off the request (part 1) */
- CURLM_STATE_DOING, /* 10 - sending off the request (part 1) */
- CURLM_STATE_DO_MORE, /* 11 - send off the request (part 2) */
- CURLM_STATE_DO_DONE, /* 12 - done sending off request */
- CURLM_STATE_WAITPERFORM, /* 13 - wait for our turn to read the response */
- CURLM_STATE_PERFORM, /* 14 - transfer data */
- CURLM_STATE_TOOFAST, /* 15 - wait because limit-rate exceeded */
- CURLM_STATE_DONE, /* 16 - post data transfer operation */
- CURLM_STATE_COMPLETED, /* 17 - operation complete */
- CURLM_STATE_MSGSENT, /* 18 - the operation complete message is sent */
- CURLM_STATE_LAST /* 19 - not a true state, never use this */
+ CURLM_STATE_DO, /* 8 - start send off the request (part 1) */
+ CURLM_STATE_DOING, /* 9 - sending off the request (part 1) */
+ CURLM_STATE_DO_MORE, /* 10 - send off the request (part 2) */
+ CURLM_STATE_DO_DONE, /* 11 - done sending off request */
+ CURLM_STATE_PERFORM, /* 12 - transfer data */
+ CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */
+ CURLM_STATE_DONE, /* 14 - post data transfer operation */
+ CURLM_STATE_COMPLETED, /* 15 - operation complete */
+ CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */
+ CURLM_STATE_LAST /* 17 - not a true state, never use this */
} CURLMstate;
/* we support N sockets per easy handle. Set the corresponding bit to what
@@ -66,7 +64,7 @@ typedef enum {
#define GETSOCK_READABLE (0x00ff)
#define GETSOCK_WRITABLE (0xff00)
-#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
+#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
/* This is the struct known as CURLM on the outside */
struct Curl_multi {
@@ -112,8 +110,8 @@ struct Curl_multi {
same actual socket) */
struct curl_hash sockhash;
- /* pipelining wanted bits (CURLPIPE*) */
- long pipelining;
+ /* multiplexing wanted */
+ bool multiplexing;
bool recheckstate; /* see Curl_multi_connchanged */
@@ -129,24 +127,6 @@ struct Curl_multi {
long max_total_connections; /* if >0, a fixed limit of the maximum number
of connections in total */
- long max_pipeline_length; /* if >0, maximum number of requests in a
- pipeline */
-
- long content_length_penalty_size; /* a connection with a
- content-length bigger than
- this is not considered
- for pipelining */
-
- long chunk_length_penalty_size; /* a connection with a chunk length
- bigger than this is not
- considered for pipelining */
-
- struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted
- from pipelining */
-
- struct curl_llist pipelining_server_bl; /* List of server types that are
- blacklisted from pipelining */
-
/* timer callback and user data pointer for the *socket() API */
curl_multi_timer_callback timer_cb;
void *timer_userp;
diff --git a/lib/multiif.h b/lib/multiif.h
index ed35ef427..e8a5e7062 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -30,10 +30,10 @@ void Curl_updatesocket(struct Curl_easy *data);
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
void Curl_expire_clear(struct Curl_easy *data);
void Curl_expire_done(struct Curl_easy *data, expire_id id);
-bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
void Curl_detach_connnection(struct Curl_easy *data);
void Curl_attach_connnection(struct Curl_easy *data,
struct connectdata *conn);
+bool Curl_multiplex_wanted(const struct Curl_multi *multi);
void Curl_set_in_callback(struct Curl_easy *data, bool value);
bool Curl_is_in_callback(struct Curl_easy *easy);
@@ -64,22 +64,11 @@ void Curl_multi_dump(struct Curl_multi *multi);
/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
-/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
-curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
-
-/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */
-curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi);
-
-/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */
-struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi);
-
-/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */
-struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
-
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
-void Curl_multi_connchanged(struct Curl_multi *multi);
+void Curl_multiuse_state(struct connectdata *conn,
+ int bundlestate); /* use BUNDLE_* defines */
/*
* Curl_multi_closed()
diff --git a/lib/netrc.c b/lib/netrc.c
index 2c5ed33bb..e32e062d6 100644
--- a/lib/netrc.c
+++ b/lib/netrc.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
@@ -21,6 +21,7 @@
***************************************************************************/
#include "curl_setup.h"
+#ifndef CURL_DISABLE_NETRC
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -240,3 +241,5 @@ int Curl_parsenetrc(const char *host,
return retcode;
}
+
+#endif
diff --git a/lib/netrc.h b/lib/netrc.h
index fe3dc357e..7f56c4b4d 100644
--- a/lib/netrc.h
+++ b/lib/netrc.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2011, 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
@@ -22,6 +22,9 @@
*
***************************************************************************/
+#include "curl_setup.h"
+#ifndef CURL_DISABLE_NETRC
+
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
int Curl_parsenetrc(const char *host,
char **loginp,
@@ -34,5 +37,9 @@ int Curl_parsenetrc(const char *host,
* section in the netrc.
* If (*loginp)[0] != 0, search for password within machine and login.
*/
+#else
+/* disabled */
+#define Curl_parsenetrc(a,b,c,d,e,f) 1
+#endif
#endif /* HEADER_CURL_NETRC_H */
diff --git a/lib/openldap.c b/lib/openldap.c
index 935632a60..cf95f1afa 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -196,9 +196,6 @@ static CURLcode ldap_setup_connection(struct connectdata *conn)
li->proto = proto;
conn->proto.generic = li;
connkeep(conn, "OpenLDAP default");
- /* TODO:
- * - provide option to choose SASL Binds instead of Simple
- */
return CURLE_OK;
}
@@ -510,8 +507,6 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
lr->nument++;
rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
if(rc < 0) {
- /* TODO: verify that this is really how this return code should be
- handled */
*err = CURLE_RECV_ERROR;
return -1;
}
diff --git a/lib/parsedate.c b/lib/parsedate.c
index a97310e55..d069642ce 100644
--- a/lib/parsedate.c
+++ b/lib/parsedate.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
@@ -82,20 +82,6 @@
#include "warnless.h"
#include "parsedate.h"
-const char * const Curl_wkday[] =
-{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
-static const char * const weekday[] =
-{ "Monday", "Tuesday", "Wednesday", "Thursday",
- "Friday", "Saturday", "Sunday" };
-const char * const Curl_month[]=
-{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-struct tzinfo {
- char name[5];
- int offset; /* +/- in minutes */
-};
-
/*
* parsedate()
*
@@ -114,6 +100,22 @@ static int parsedate(const char *date, time_t *output);
#define PARSEDATE_LATER 1
#define PARSEDATE_SOONER 2
+#ifndef CURL_DISABLE_PARSEDATE
+
+const char * const Curl_wkday[] =
+{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
+static const char * const weekday[] =
+{ "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday", "Sunday" };
+const char * const Curl_month[]=
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+struct tzinfo {
+ char name[5];
+ int offset; /* +/- in minutes */
+};
+
/* Here's a bunch of frequently used time zone names. These were supported
by the old getdate parser. */
#define tDAYZONE -60 /* offset for daylight savings time */
@@ -555,6 +557,15 @@ static int parsedate(const char *date, time_t *output)
return PARSEDATE_OK;
}
+#else
+/* disabled */
+static int parsedate(const char *date, time_t *output)
+{
+ (void)date;
+ *output = 0;
+ return PARSEDATE_OK; /* a lie */
+}
+#endif
time_t curl_getdate(const char *p, const time_t *now)
{
diff --git a/lib/pipeline.c b/lib/pipeline.c
deleted file mode 100644
index 0adc1cd48..000000000
--- a/lib/pipeline.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2013 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#include <gnurl/curl.h>
-
-#include "urldata.h"
-#include "url.h"
-#include "progress.h"
-#include "multiif.h"
-#include "pipeline.h"
-#include "sendf.h"
-#include "strcase.h"
-
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-struct site_blacklist_entry {
- struct curl_llist_element list;
- unsigned short port;
- char hostname[1];
-};
-
-static void site_blacklist_llist_dtor(void *user, void *element)
-{
- struct site_blacklist_entry *entry = element;
- (void)user;
- free(entry);
-}
-
-static void server_blacklist_llist_dtor(void *user, void *element)
-{
- (void)user;
- free(element);
-}
-
-bool Curl_pipeline_penalized(struct Curl_easy *data,
- struct connectdata *conn)
-{
- if(data) {
- bool penalized = FALSE;
- curl_off_t penalty_size =
- Curl_multi_content_length_penalty_size(data->multi);
- curl_off_t chunk_penalty_size =
- Curl_multi_chunk_length_penalty_size(data->multi);
- curl_off_t recv_size = -2; /* Make it easy to spot in the log */
-
- /* Find the head of the recv pipe, if any */
- if(conn->recv_pipe.head) {
- struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr;
-
- recv_size = recv_handle->req.size;
-
- if(penalty_size > 0 && recv_size > penalty_size)
- penalized = TRUE;
- }
-
- if(chunk_penalty_size > 0 &&
- (curl_off_t)conn->chunk.datasize > chunk_penalty_size)
- penalized = TRUE;
-
- infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
- CURL_FORMAT_CURL_OFF_T "/%" CURL_FORMAT_CURL_OFF_T
- "), penalized: %s\n",
- conn->connection_id, (void *)conn, recv_size,
- conn->chunk.datasize, penalized?"TRUE":"FALSE");
- return penalized;
- }
- return FALSE;
-}
-
-static CURLcode addHandleToPipeline(struct Curl_easy *data,
- struct curl_llist *pipeline)
-{
- Curl_llist_insert_next(pipeline, pipeline->tail, data,
- &data->pipeline_queue);
- return CURLE_OK;
-}
-
-
-CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
- struct connectdata *conn)
-{
- struct curl_llist_element *sendhead = conn->send_pipe.head;
- struct curl_llist *pipeline;
- CURLcode result;
-
- pipeline = &conn->send_pipe;
-
- result = addHandleToPipeline(handle, pipeline);
- if((conn->bundle->multiuse == BUNDLE_PIPELINING) &&
- (pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head)) {
- /* this is a new one as head, expire it */
- Curl_pipeline_leave_write(conn); /* not in use yet */
- Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
- }
-
-#if 0 /* enable for pipeline debugging */
- print_pipeline(conn);
-#endif
-
- return result;
-}
-
-/* Move this transfer from the sending list to the receiving list.
-
- Pay special attention to the new sending list "leader" as it needs to get
- checked to update what sockets it acts on.
-
-*/
-void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
- struct connectdata *conn)
-{
- struct curl_llist_element *curr;
-
- curr = conn->send_pipe.head;
- while(curr) {
- if(curr->ptr == handle) {
- Curl_llist_move(&conn->send_pipe, curr,
- &conn->recv_pipe, conn->recv_pipe.tail);
-
- if(conn->send_pipe.head) {
- /* Since there's a new easy handle at the start of the send pipeline,
- set its timeout value to 1ms to make it trigger instantly */
- Curl_pipeline_leave_write(conn); /* not used now */
-#ifdef DEBUGBUILD
- infof(conn->data, "%p is at send pipe head B!\n",
- (void *)conn->send_pipe.head->ptr);
-#endif
- Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
- }
-
- /* The receiver's list is not really interesting here since either this
- handle is now first in the list and we'll deal with it soon, or
- another handle is already first and thus is already taken care of */
-
- break; /* we're done! */
- }
- curr = curr->next;
- }
-}
-
-bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
- struct connectdata *conn)
-{
- if(handle->multi) {
- struct curl_llist *blacklist =
- Curl_multi_pipelining_site_bl(handle->multi);
-
- if(blacklist) {
- struct curl_llist_element *curr;
-
- curr = blacklist->head;
- while(curr) {
- struct site_blacklist_entry *site;
-
- site = curr->ptr;
- if(strcasecompare(site->hostname, conn->host.name) &&
- site->port == conn->remote_port) {
- infof(handle, "Site %s:%d is pipeline blacklisted\n",
- conn->host.name, conn->remote_port);
- return TRUE;
- }
- curr = curr->next;
- }
- }
- }
- return FALSE;
-}
-
-CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
- struct curl_llist *list)
-{
- /* Free the old list */
- if(list->size)
- Curl_llist_destroy(list, NULL);
-
- if(sites) {
- Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor);
-
- /* Parse the URLs and populate the list */
- while(*sites) {
- char *port;
- struct site_blacklist_entry *entry;
-
- entry = malloc(sizeof(struct site_blacklist_entry) + strlen(*sites));
- if(!entry) {
- Curl_llist_destroy(list, NULL);
- return CURLM_OUT_OF_MEMORY;
- }
- strcpy(entry->hostname, *sites);
-
- port = strchr(entry->hostname, ':');
- if(port) {
- *port = '\0';
- port++;
- entry->port = (unsigned short)strtol(port, NULL, 10);
- }
- else {
- /* Default port number for HTTP */
- entry->port = 80;
- }
-
- Curl_llist_insert_next(list, list->tail, entry, &entry->list);
- sites++;
- }
- }
-
- return CURLM_OK;
-}
-
-struct blacklist_node {
- struct curl_llist_element list;
- char server_name[1];
-};
-
-bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
- char *server_name)
-{
- if(handle->multi && server_name) {
- struct curl_llist *list =
- Curl_multi_pipelining_server_bl(handle->multi);
-
- struct curl_llist_element *e = list->head;
- while(e) {
- struct blacklist_node *bl = (struct blacklist_node *)e;
- if(strncasecompare(bl->server_name, server_name,
- strlen(bl->server_name))) {
- infof(handle, "Server %s is blacklisted\n", server_name);
- return TRUE;
- }
- e = e->next;
- }
-
- DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
- }
- return FALSE;
-}
-
-CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
- struct curl_llist *list)
-{
- /* Free the old list */
- if(list->size)
- Curl_llist_destroy(list, NULL);
-
- if(servers) {
- Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor);
-
- /* Parse the URLs and populate the list */
- while(*servers) {
- struct blacklist_node *n;
- size_t len = strlen(*servers);
-
- n = malloc(sizeof(struct blacklist_node) + len);
- if(!n) {
- Curl_llist_destroy(list, NULL);
- return CURLM_OUT_OF_MEMORY;
- }
- strcpy(n->server_name, *servers);
-
- Curl_llist_insert_next(list, list->tail, n, &n->list);
- servers++;
- }
- }
-
-
- return CURLM_OK;
-}
-
-static bool pipe_head(struct Curl_easy *data,
- struct curl_llist *pipeline)
-{
- if(pipeline) {
- struct curl_llist_element *curr = pipeline->head;
- if(curr)
- return (curr->ptr == data) ? TRUE : FALSE;
- }
- return FALSE;
-}
-
-/* returns TRUE if the given handle is head of the recv pipe */
-bool Curl_recvpipe_head(struct Curl_easy *data,
- struct connectdata *conn)
-{
- return pipe_head(data, &conn->recv_pipe);
-}
-
-/* returns TRUE if the given handle is head of the send pipe */
-bool Curl_sendpipe_head(struct Curl_easy *data,
- struct connectdata *conn)
-{
- return pipe_head(data, &conn->send_pipe);
-}
-
-
-/*
- * Check if the write channel is available and this handle as at the head,
- * then grab the channel and return TRUE.
- *
- * If not available, return FALSE.
- */
-
-bool Curl_pipeline_checkget_write(struct Curl_easy *data,
- struct connectdata *conn)
-{
- if(conn->bits.multiplex)
- /* when multiplexing, we can use it at once */
- return TRUE;
-
- if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
- /* Grab the channel */
- conn->writechannel_inuse = TRUE;
- return TRUE;
- }
- return FALSE;
-}
-
-
-/*
- * Check if the read channel is available and this handle as at the head, then
- * grab the channel and return TRUE.
- *
- * If not available, return FALSE.
- */
-
-bool Curl_pipeline_checkget_read(struct Curl_easy *data,
- struct connectdata *conn)
-{
- if(conn->bits.multiplex)
- /* when multiplexing, we can use it at once */
- return TRUE;
-
- if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
- /* Grab the channel */
- conn->readchannel_inuse = TRUE;
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * The current user of the pipeline write channel gives it up.
- */
-void Curl_pipeline_leave_write(struct connectdata *conn)
-{
- conn->writechannel_inuse = FALSE;
-}
-
-/*
- * The current user of the pipeline read channel gives it up.
- */
-void Curl_pipeline_leave_read(struct connectdata *conn)
-{
- conn->readchannel_inuse = FALSE;
-}
-
-
-#if 0
-void print_pipeline(struct connectdata *conn)
-{
- struct curl_llist_element *curr;
- struct connectbundle *cb_ptr;
- struct Curl_easy *data = conn->data;
-
- cb_ptr = conn->bundle;
-
- if(cb_ptr) {
- curr = cb_ptr->conn_list->head;
- while(curr) {
- conn = curr->ptr;
- infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
- conn->connection_id,
- (void *)conn,
- conn->send_pipe->size,
- conn->recv_pipe->size);
- curr = curr->next;
- }
- }
-}
-
-#endif
diff --git a/lib/pipeline.h b/lib/pipeline.h
deleted file mode 100644
index 413ba31a0..000000000
--- a/lib/pipeline.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef HEADER_CURL_PIPELINE_H
-#define HEADER_CURL_PIPELINE_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
- *
- * 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.
- *
- ***************************************************************************/
-
-CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
- struct connectdata *conn);
-void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
- struct connectdata *conn);
-bool Curl_pipeline_penalized(struct Curl_easy *data,
- struct connectdata *conn);
-
-bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
- struct connectdata *conn);
-
-CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
- struct curl_llist *list_ptr);
-
-bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
- char *server_name);
-
-CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
- struct curl_llist *list_ptr);
-
-bool Curl_pipeline_checkget_write(struct Curl_easy *data,
- struct connectdata *conn);
-bool Curl_pipeline_checkget_read(struct Curl_easy *data,
- struct connectdata *conn);
-void Curl_pipeline_leave_write(struct connectdata *conn);
-void Curl_pipeline_leave_read(struct connectdata *conn);
-bool Curl_recvpipe_head(struct Curl_easy *data,
- struct connectdata *conn);
-bool Curl_sendpipe_head(struct Curl_easy *data,
- struct connectdata *conn);
-
-#endif /* HEADER_CURL_PIPELINE_H */
diff --git a/lib/pop3.c b/lib/pop3.c
index 0edbad461..ad3087e58 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -30,6 +30,7 @@
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
* RFC5034 POP3 SASL Authentication Mechanism
* RFC6749 OAuth 2.0 Authorization Framework
+ * RFC8314 Use of TLS for Email Submission and Access
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
*
***************************************************************************/
diff --git a/lib/progress.c b/lib/progress.c
index d37e1d5a6..f586d59b4 100644
--- a/lib/progress.c
+++ b/lib/progress.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
@@ -31,6 +31,7 @@
/* check rate limits within this many recent milliseconds, at minimum. */
#define MIN_RATE_LIMIT_PERIOD 3000
+#ifndef CURL_DISABLE_PROGRESS_METER
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
byte) */
static void time2str(char *r, curl_off_t seconds)
@@ -119,6 +120,7 @@ static char *max5data(curl_off_t bytes, char *max5)
return max5;
}
+#endif
/*
@@ -362,17 +364,13 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
}
}
-/*
- * Curl_pgrsUpdate() returns 0 for success or the value returned by the
- * progress callback!
- */
-int Curl_pgrsUpdate(struct connectdata *conn)
+#ifndef CURL_DISABLE_PROGRESS_METER
+static void progress_meter(struct connectdata *conn)
{
struct curltime now;
curl_off_t timespent;
curl_off_t timespent_ms; /* milliseconds */
struct Curl_easy *data = conn->data;
- int nowindex = data->progress.speeder_c% CURR_TIME;
bool shownow = FALSE;
curl_off_t dl = data->progress.downloaded;
curl_off_t ul = data->progress.uploaded;
@@ -399,7 +397,9 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Calculations done at most once a second, unless end is reached */
if(data->progress.lastshow != now.tv_sec) {
int countindex; /* amount of seconds stored in the speeder array */
- shownow = TRUE;
+ int nowindex = data->progress.speeder_c% CURR_TIME;
+ if(!(data->progress.flags & PGRS_HIDE))
+ shownow = TRUE;
data->progress.lastshow = now.tv_sec;
@@ -461,8 +461,12 @@ int Curl_pgrsUpdate(struct connectdata *conn)
data->progress.ulspeed + data->progress.dlspeed;
} /* Calculations end */
-
- if(!(data->progress.flags & PGRS_HIDE)) {
+ if(!shownow)
+ /* only show the internal progress meter once per second */
+ return;
+ else {
+ /* If there's no external callback set, use internal code to show
+ progress */
/* progress meter has not been shut off */
char max5[6][10];
curl_off_t dlpercen = 0;
@@ -477,42 +481,6 @@ int Curl_pgrsUpdate(struct connectdata *conn)
curl_off_t dlestimate = 0;
curl_off_t total_estimate;
- if(data->set.fxferinfo) {
- int result;
- /* There's a callback set, call that */
- Curl_set_in_callback(data, true);
- result = data->set.fxferinfo(data->set.progress_client,
- data->progress.size_dl,
- data->progress.downloaded,
- data->progress.size_ul,
- data->progress.uploaded);
- Curl_set_in_callback(data, false);
- if(result)
- failf(data, "Callback aborted");
- return result;
- }
- if(data->set.fprogress) {
- int result;
- /* The older deprecated callback is set, call that */
- Curl_set_in_callback(data, true);
- result = data->set.fprogress(data->set.progress_client,
- (double)data->progress.size_dl,
- (double)data->progress.downloaded,
- (double)data->progress.size_ul,
- (double)data->progress.uploaded);
- Curl_set_in_callback(data, false);
- if(result)
- failf(data, "Callback aborted");
- return result;
- }
-
- if(!shownow)
- /* only show the internal progress meter once per second */
- return 0;
-
- /* If there's no external callback set, use internal code to show
- progress */
-
if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if(data->state.resume_from) {
fprintf(data->set.err,
@@ -564,9 +532,9 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Get the total amount of data expected to get transferred */
total_expected_transfer =
- (data->progress.flags & PGRS_UL_SIZE_KNOWN?
+ ((data->progress.flags & PGRS_UL_SIZE_KNOWN)?
data->progress.size_ul:data->progress.uploaded)+
- (data->progress.flags & PGRS_DL_SIZE_KNOWN?
+ ((data->progress.flags & PGRS_DL_SIZE_KNOWN)?
data->progress.size_dl:data->progress.downloaded);
/* We have transferred this much so far */
@@ -595,13 +563,57 @@ int Curl_pgrsUpdate(struct connectdata *conn)
time_total, /* 8 letters */ /* total time */
time_spent, /* 8 letters */ /* time spent */
time_left, /* 8 letters */ /* time left */
- max5data(data->progress.current_speed, max5[5]) /* current speed */
- );
+ max5data(data->progress.current_speed, max5[5])
+ );
/* we flush the output stream to make it appear as soon as possible */
fflush(data->set.err);
+ } /* don't show now */
+}
+#else
+ /* progress bar disabled */
+#define progress_meter(x)
+#endif
+
- } /* !(data->progress.flags & PGRS_HIDE) */
+/*
+ * Curl_pgrsUpdate() returns 0 for success or the value returned by the
+ * progress callback!
+ */
+int Curl_pgrsUpdate(struct connectdata *conn)
+{
+ struct Curl_easy *data = conn->data;
+ if(!(data->progress.flags & PGRS_HIDE)) {
+ if(data->set.fxferinfo) {
+ int result;
+ /* There's a callback set, call that */
+ Curl_set_in_callback(data, true);
+ result = data->set.fxferinfo(data->set.progress_client,
+ data->progress.size_dl,
+ data->progress.downloaded,
+ data->progress.size_ul,
+ data->progress.uploaded);
+ Curl_set_in_callback(data, false);
+ if(result)
+ failf(data, "Callback aborted");
+ return result;
+ }
+ if(data->set.fprogress) {
+ int result;
+ /* The older deprecated callback is set, call that */
+ Curl_set_in_callback(data, true);
+ result = data->set.fprogress(data->set.progress_client,
+ (double)data->progress.size_dl,
+ (double)data->progress.downloaded,
+ (double)data->progress.size_ul,
+ (double)data->progress.uploaded);
+ Curl_set_in_callback(data, false);
+ if(result)
+ failf(data, "Callback aborted");
+ return result;
+ }
+ }
+ progress_meter(conn);
return 0;
}
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 73c681556..f3f8c6787 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -42,16 +42,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-/*
- * TODO (general)
- * -incoming server requests
- * -server CSeq counter
- * -digest authentication
- * -connect through proxy
- * -pipelining?
- */
-
-
#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1])))
#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \
@@ -236,7 +226,6 @@ static CURLcode rtsp_done(struct connectdata *conn,
if(data->set.rtspreq == RTSPREQ_RECEIVE &&
(conn->proto.rtspc.rtp_channel == -1)) {
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
- /* TODO CPC: Server -> Client logic here */
}
}
@@ -336,8 +325,6 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- /* TODO: proxy? */
-
/* Stream URI. Default to server '*' if not specified */
if(data->set.str[STRING_RTSP_STREAM_URI]) {
p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI];
diff --git a/lib/security.c b/lib/security.c
index eec6e6f44..82ae5c2cd 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -151,7 +151,6 @@ socket_read(curl_socket_t fd, void *to, size_t len)
to_p += nread;
}
else {
- /* FIXME: We are doing a busy wait */
if(result == CURLE_AGAIN)
continue;
return result;
@@ -179,7 +178,6 @@ socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
to_p += written;
}
else {
- /* FIXME: We are doing a busy wait */
if(result == CURLE_AGAIN)
continue;
return result;
@@ -265,13 +263,11 @@ static ssize_t sec_recv(struct connectdata *conn, int sockindex,
total_read += bytes_read;
buffer += bytes_read;
}
- /* FIXME: Check for overflow */
return total_read;
}
/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
and negociating with the server. |from| can be NULL. */
-/* FIXME: We don't check for errors nor report any! */
static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
const char *from, int length)
{
@@ -406,18 +402,14 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
if(buf[decoded_len - 1] == '\n')
buf[decoded_len - 1] = '\0';
- /* FIXME: Is |buffer| length always greater than |decoded_len|? */
strcpy(buffer, buf);
free(buf);
return ret_code;
}
-/* FIXME: The error code returned here is never checked. */
static int sec_set_protection_level(struct connectdata *conn)
{
int code;
- char *pbsz;
- static unsigned int buffer_size = 1 << 20; /* 1048576 */
enum protection_level level = conn->request_data_prot;
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
@@ -433,6 +425,9 @@ static int sec_set_protection_level(struct connectdata *conn)
return 0;
if(level) {
+ char *pbsz;
+ static unsigned int buffer_size = 1 << 20; /* 1048576 */
+
code = ftp_send_command(conn, "PBSZ %u", buffer_size);
if(code < 0)
return -1;
@@ -508,7 +503,6 @@ static CURLcode choose_mech(struct connectdata *conn)
infof(data, "Trying mechanism %s...\n", mech->name);
ret = ftp_send_command(conn, "AUTH %s", mech->name);
if(ret < 0)
- /* FIXME: This error is too generic but it is OK for now. */
return CURLE_COULDNT_CONNECT;
if(ret/100 != 3) {
@@ -575,7 +569,6 @@ Curl_sec_end(struct connectdata *conn)
conn->in_buffer.data = NULL;
conn->in_buffer.size = 0;
conn->in_buffer.index = 0;
- /* FIXME: Is this really needed? */
conn->in_buffer.eof_flag = 0;
}
conn->sec_complete = 0;
diff --git a/lib/sendf.c b/lib/sendf.c
index 9a04b4af2..5f1f7f316 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -595,7 +595,10 @@ static CURLcode chop_write(struct connectdata *conn,
size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
if(writebody) {
- size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
+ size_t wrote;
+ Curl_set_in_callback(data, true);
+ wrote = writebody(ptr, 1, chunklen, data->set.out);
+ Curl_set_in_callback(data, false);
if(CURL_WRITEFUNC_PAUSE == wrote) {
if(conn->handler->flags & PROTOPT_NONETWORK) {
@@ -724,10 +727,6 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
char *buffertofill = NULL;
struct Curl_easy *data = conn->data;
- /* if HTTP/1 pipelining is both wanted and possible */
- bool pipelining = Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
- (conn->bundle->multiuse == BUNDLE_PIPELINING);
-
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
If it is the second socket, we set num to 1. Otherwise to 0. This lets
us use the correct ssl handle. */
@@ -735,40 +734,13 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
*n = 0; /* reset amount to zero */
- /* If session can pipeline, check connection buffer */
- if(pipelining) {
- size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
- sizerequested);
-
- /* Copy from our master buffer first if we have some unread data there*/
- if(bytestocopy > 0) {
- memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
- conn->read_pos += bytestocopy;
- conn->bits.stream_was_rewound = FALSE;
-
- *n = (ssize_t)bytestocopy;
- return CURLE_OK;
- }
- /* If we come here, it means that there is no data to read from the buffer,
- * so we read from the socket */
- bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE);
- buffertofill = conn->master_buffer;
- }
- else {
- bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
- buffertofill = buf;
- }
+ bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
+ buffertofill = buf;
nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
if(nread < 0)
return result;
- if(pipelining) {
- memcpy(buf, conn->master_buffer, nread);
- conn->buf_len = nread;
- conn->read_pos = nread;
- }
-
*n += nread;
return CURLE_OK;
diff --git a/lib/setopt.c b/lib/setopt.c
index b5f74a93d..92cd5b271 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -61,6 +61,13 @@ CURLcode Curl_setstropt(char **charp, const char *s)
if(s) {
char *str = strdup(s);
+ if(str) {
+ size_t len = strlen(str);
+ if(len > CURL_MAX_INPUT_LENGTH) {
+ free(str);
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
if(!str)
return CURLE_OUT_OF_MEMORY;
@@ -118,6 +125,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
char *argptr;
CURLcode result = CURLE_OK;
long arg;
+ unsigned long uarg;
curl_off_t bigsize;
switch(option) {
@@ -128,23 +136,20 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.dns_cache_timeout = arg;
break;
case CURLOPT_DNS_USE_GLOBAL_CACHE:
-#if 0 /* deprecated */
- /* remember we want this enabled */
- arg = va_arg(param, long);
- data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE;
-#endif
+ /* deprecated */
break;
case CURLOPT_SSL_CIPHER_LIST:
/* set a list of cipher we want to use in the SSL connection */
result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_CIPHER_LIST:
/* set a list of cipher we want to use in the SSL connection for proxy */
result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
va_arg(param, char *));
break;
-
+#endif
case CURLOPT_TLS13_CIPHERS:
if(Curl_ssl_tls13_ciphersuites()) {
/* set preferred list of TLS 1.3 cipher suites */
@@ -154,6 +159,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
else
return CURLE_NOT_BUILT_IN;
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_TLS13_CIPHERS:
if(Curl_ssl_tls13_ciphersuites()) {
/* set preferred list of TLS 1.3 cipher suites for proxy */
@@ -163,7 +169,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
else
return CURLE_NOT_BUILT_IN;
break;
-
+#endif
case CURLOPT_RANDOM_FILE:
/*
* This is the path name to a file that contains random data to seed
@@ -271,27 +277,6 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
*/
data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
- case CURLOPT_FTP_CREATE_MISSING_DIRS:
- /*
- * An FTP option that modifies an upload to create missing directories on
- * the server.
- */
- switch(va_arg(param, long)) {
- case 0:
- data->set.ftp_create_missing_dirs = 0;
- break;
- case 1:
- data->set.ftp_create_missing_dirs = 1;
- break;
- case 2:
- data->set.ftp_create_missing_dirs = 2;
- break;
- default:
- /* reserve other values for future use */
- result = CURLE_UNKNOWN_OPTION;
- break;
- }
- break;
case CURLOPT_SERVER_RESPONSE_TIMEOUT:
/*
* Option that specifies how quickly an server response must be obtained
@@ -303,6 +288,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
else
return CURLE_BAD_FUNCTION_ARGUMENT;
break;
+#ifndef CURL_DISABLE_TFTP
case CURLOPT_TFTP_NO_OPTIONS:
/*
* Option that prevents libcurl from sending TFTP option requests to the
@@ -319,28 +305,8 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.tftp_blksize = arg;
break;
- case CURLOPT_DIRLISTONLY:
- /*
- * An option that changes the command to one that asks for a list
- * only, no file info details.
- */
- data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
- break;
- case CURLOPT_APPEND:
- /*
- * We want to upload and append to an existing file.
- */
- data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
- break;
- case CURLOPT_FTP_FILEMETHOD:
- /*
- * How do access files over FTP.
- */
- arg = va_arg(param, long);
- if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD))
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.ftp_filemethod = (curl_ftpfile)arg;
- break;
+#endif
+#ifndef CURL_DISABLE_NETRC
case CURLOPT_NETRC:
/*
* Parse the $HOME/.netrc file
@@ -357,6 +323,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE],
va_arg(param, char *));
break;
+#endif
case CURLOPT_TRANSFERTEXT:
/*
* This option was previously named 'FTPASCII'. Renamed to work with
@@ -664,6 +631,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
break;
#ifndef CURL_DISABLE_HTTP
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXYHEADER:
/*
* Set a list with proxy headers to use (or replace internals with)
@@ -677,7 +645,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
*/
data->set.proxyheaders = va_arg(param, struct curl_slist *);
break;
-
+#endif
case CURLOPT_HEADEROPT:
/*
* Set header option.
@@ -1072,7 +1040,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
#endif
-
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_SOCKS5_GSSAPI_SERVICE:
case CURLOPT_PROXY_SERVICE_NAME:
/*
@@ -1081,7 +1049,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
va_arg(param, char *));
break;
-
+#endif
case CURLOPT_SERVICE_NAME:
/*
* Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
@@ -1110,6 +1078,33 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
*/
data->set.out = va_arg(param, void *);
break;
+
+ case CURLOPT_DIRLISTONLY:
+ /*
+ * An option that changes the command to one that asks for a list only, no
+ * file info details. Used for FTP, POP3 and SFTP.
+ */
+ data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
+
+ case CURLOPT_APPEND:
+ /*
+ * We want to upload and append to an existing file. Used for FTP and
+ * SFTP.
+ */
+ data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
+
+#ifndef CURL_DISABLE_FTP
+ case CURLOPT_FTP_FILEMETHOD:
+ /*
+ * How do access files over FTP.
+ */
+ arg = va_arg(param, long);
+ if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.ftp_filemethod = (curl_ftpfile)arg;
+ break;
case CURLOPT_FTPPORT:
/*
* Use FTP PORT, this also specifies which IP address to use
@@ -1146,6 +1141,55 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
+ case CURLOPT_FTP_ACCOUNT:
+ result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+ result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_FTPSSLAUTH:
+ /*
+ * Set a specific auth for FTP-SSL transfers.
+ */
+ arg = va_arg(param, long);
+ if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.ftpsslauth = (curl_ftpauth)arg;
+ break;
+ case CURLOPT_KRBLEVEL:
+ /*
+ * A string that defines the kerberos security level.
+ */
+ result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL],
+ va_arg(param, char *));
+ data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
+ break;
+#endif
+ case CURLOPT_FTP_CREATE_MISSING_DIRS:
+ /*
+ * An FTP/SFTP option that modifies an upload to create missing
+ * directories on the server.
+ */
+ switch(va_arg(param, long)) {
+ case 0:
+ data->set.ftp_create_missing_dirs = 0;
+ break;
+ case 1:
+ data->set.ftp_create_missing_dirs = 1;
+ break;
+ case 2:
+ data->set.ftp_create_missing_dirs = 2;
+ break;
+ default:
+ /* reserve other values for future use */
+ result = CURLE_UNKNOWN_OPTION;
+ break;
+ }
+ break;
case CURLOPT_READDATA:
/*
* FILE pointer to read the file to be uploaded from. Or possibly
@@ -1554,6 +1598,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLCERT:
/*
* String that holds file name of the SSL certificate to use for proxy
@@ -1561,6 +1606,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_SSLCERTTYPE:
/*
* String that holds file type of the SSL certificate to use
@@ -1568,6 +1614,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLCERTTYPE:
/*
* String that holds file type of the SSL certificate to use for proxy
@@ -1575,6 +1622,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_SSLKEY:
/*
* String that holds file name of the SSL key to use
@@ -1582,6 +1630,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLKEY:
/*
* String that holds file name of the SSL key to use for proxy
@@ -1589,6 +1638,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_SSLKEYTYPE:
/*
* String that holds file type of the SSL key to use
@@ -1596,6 +1646,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSLKEYTYPE:
/*
* String that holds file type of the SSL key to use for proxy
@@ -1603,6 +1654,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_KEYPASSWD:
/*
* String that holds the SSL or SSH private key password.
@@ -1610,6 +1662,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_KEYPASSWD:
/*
* String that holds the SSL private key password for proxy.
@@ -1617,6 +1670,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_SSLENGINE:
/*
* String that holds the SSL crypto engine.
@@ -1643,14 +1697,14 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
*/
data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
-
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_HAPROXYPROTOCOL:
/*
* Set to send the HAProxy Proxy Protocol header
*/
data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
-
+#endif
case CURLOPT_INTERFACE:
/*
* Set what interface or address/hostname to bind the socket to when
@@ -1677,14 +1731,6 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.localportrange = curlx_sltosi(arg);
break;
- case CURLOPT_KRBLEVEL:
- /*
- * A string that defines the kerberos security level.
- */
- result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL],
- va_arg(param, char *));
- data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
- break;
case CURLOPT_GSSAPI_DELEGATION:
/*
* GSS-API credential delegation bitmask
@@ -1707,6 +1753,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.ssl.primary.verifypeer;
}
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_VERIFYPEER:
/*
* Enable peer SSL verifying for proxy.
@@ -1720,6 +1767,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.proxy_ssl.primary.verifypeer;
}
break;
+#endif
case CURLOPT_SSL_VERIFYHOST:
/*
* Enable verification of the host name in the peer certificate
@@ -1744,6 +1792,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.ssl.primary.verifyhost;
}
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_VERIFYHOST:
/*
* Enable verification of the host name in the peer certificate for proxy
@@ -1768,6 +1817,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.proxy_ssl.primary.verifyhost;
}
break;
+#endif
case CURLOPT_SSL_VERIFYSTATUS:
/*
* Enable certificate status verifying.
@@ -1840,6 +1890,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
#endif
result = CURLE_NOT_BUILT_IN;
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_PINNEDPUBLICKEY:
/*
* Set pinned public key for SSL connection.
@@ -1853,6 +1904,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
#endif
result = CURLE_NOT_BUILT_IN;
break;
+#endif
case CURLOPT_CAINFO:
/*
* Set CA info for SSL connection. Specify file name of the CA certificate
@@ -1860,6 +1912,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_CAINFO:
/*
* Set CA info SSL connection for proxy. Specify file name of the
@@ -1868,6 +1921,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_CAPATH:
/*
* Set CA path info for SSL connection. Specify directory name of the CA
@@ -1882,6 +1936,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
#endif
result = CURLE_NOT_BUILT_IN;
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_CAPATH:
/*
* Set CA path info for SSL connection proxy. Specify directory name of the
@@ -1896,6 +1951,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
#endif
result = CURLE_NOT_BUILT_IN;
break;
+#endif
case CURLOPT_CRLFILE:
/*
* Set CRL file info for SSL connection. Specify file name of the CRL
@@ -1904,6 +1960,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_CRLFILE:
/*
* Set CRL file info for SSL connection for proxy. Specify file name of the
@@ -1912,6 +1969,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
va_arg(param, char *));
break;
+#endif
case CURLOPT_ISSUERCERT:
/*
* Set Issuer certificate file
@@ -1920,13 +1978,14 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
va_arg(param, char *));
break;
+#ifndef CURL_DISABLE_TELNET
case CURLOPT_TELNETOPTIONS:
/*
* Set a linked list of telnet options
*/
data->set.telnet_options = va_arg(param, struct curl_slist *);
break;
-
+#endif
case CURLOPT_BUFFERSIZE:
/*
* The application kindly asks for a differently sized receive buffer.
@@ -2084,24 +2143,16 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
break;
+#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_OPTIONS:
arg = va_arg(param, long);
data->set.proxy_ssl.enable_beast =
(bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
break;
-
#endif
- case CURLOPT_FTPSSLAUTH:
- /*
- * Set a specific auth for FTP-SSL transfers.
- */
- arg = va_arg(param, long);
- if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS))
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.ftpsslauth = (curl_ftpauth)arg;
- break;
+#endif
case CURLOPT_IPRESOLVE:
arg = va_arg(param, long);
if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6))
@@ -2127,11 +2178,6 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
- case CURLOPT_FTP_ACCOUNT:
- result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT],
- va_arg(param, char *));
- break;
-
case CURLOPT_IGNORE_CONTENT_LENGTH:
data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
@@ -2143,11 +2189,6 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
- case CURLOPT_FTP_ALTERNATIVE_TO_USER:
- result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
- va_arg(param, char *));
- break;
-
case CURLOPT_SOCKOPTFUNCTION:
/*
* socket callback function: called after socket() but before connect()
@@ -2213,7 +2254,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
break;
-#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
+#ifdef USE_SSH
/* we only include SSH options if explicitly built to support SSH */
case CURLOPT_SSH_AUTH_TYPES:
data->set.ssh_auth_types = va_arg(param, long);
@@ -2263,7 +2304,11 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
*/
data->set.ssh_keyfunc_userp = va_arg(param, void *);
break;
-#endif /* USE_LIBSSH2 */
+
+ case CURLOPT_SSH_COMPRESSION:
+ data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+#endif /* USE_SSH */
case CURLOPT_HTTP_TRANSFER_DECODING:
/*
@@ -2279,6 +2324,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
break;
+#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
case CURLOPT_NEW_FILE_PERMS:
/*
* Uses these permissions instead of 0644
@@ -2298,17 +2344,20 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.new_directory_perms = arg;
break;
+#endif
case CURLOPT_ADDRESS_SCOPE:
/*
- * We always get longs when passed plain numericals, but for this value we
- * know that an unsigned int will always hold the value so we blindly
- * typecast to this type
+ * Use this scope id when using IPv6
+ * We always get longs when passed plain numericals so we should check
+ * that the value fits into an unsigned 32 bit integer.
*/
- arg = va_arg(param, long);
- if((arg < 0) || (arg > 0xf))
+ uarg = va_arg(param, unsigned long);
+#if SIZEOF_LONG > 4
+ if(uarg > UINT_MAX)
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.scope_id = curlx_sltoui(arg);
+#endif
+ data->set.scope_id = (unsigned int)uarg;
break;
case CURLOPT_PROTOCOLS:
@@ -2332,7 +2381,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
va_arg(param, char *));
break;
-
+#ifndef CURL_DISABLE_SMTP
case CURLOPT_MAIL_FROM:
/* Set the SMTP mail originator */
result = Curl_setstropt(&data->set.str[STRING_MAIL_FROM],
@@ -2349,12 +2398,13 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
/* Set the list of mail recipients */
data->set.mail_rcpt = va_arg(param, struct curl_slist *);
break;
+#endif
case CURLOPT_SASL_IR:
/* Enable/disable SASL initial response */
data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
-
+#ifndef CURL_DISABLE_RTSP
case CURLOPT_RTSP_REQUEST:
{
/*
@@ -2463,7 +2513,8 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
/* Set the user defined RTP write function */
data->set.fwrite_rtp = va_arg(param, curl_write_callback);
break;
-
+#endif
+#ifndef CURL_DISABLE_FTP
case CURLOPT_WILDCARDMATCH:
data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
@@ -2482,6 +2533,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_FNMATCH_DATA:
data->set.fnmatch_data = va_arg(param, void *);
break;
+#endif
#ifdef USE_TLS_SRP
case CURLOPT_TLSAUTH_USERNAME:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
@@ -2526,6 +2578,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
break;
#endif
+#ifdef USE_ARES
case CURLOPT_DNS_SERVERS:
result = Curl_set_dns_servers(data, va_arg(param, char *));
break;
@@ -2538,7 +2591,7 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_DNS_LOCAL_IP6:
result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
break;
-
+#endif
case CURLOPT_TCP_KEEPALIVE:
data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
@@ -2562,13 +2615,14 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
result = CURLE_NOT_BUILT_IN;
#endif
break;
+#ifdef USE_NGHTTP2
case CURLOPT_SSL_ENABLE_NPN:
data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
case CURLOPT_SSL_ENABLE_ALPN:
data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
-
+#endif
#ifdef USE_UNIX_SOCKETS
case CURLOPT_UNIX_SOCKET_PATH:
data->set.abstract_unix_socket = FALSE;
@@ -2619,33 +2673,40 @@ static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_SUPPRESS_CONNECT_HEADERS:
data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
break;
- case CURLOPT_SSH_COMPRESSION:
- data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
- break;
case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
arg = va_arg(param, long);
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.happy_eyeballs_timeout = arg;
break;
+#ifndef CURL_DISABLE_SHUFFLE_DNS
case CURLOPT_DNS_SHUFFLE_ADDRESSES:
data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE;
break;
+#endif
case CURLOPT_DISALLOW_USERNAME_IN_URL:
data->set.disallow_username_in_url =
(0 != va_arg(param, long)) ? TRUE : FALSE;
break;
+#ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_URL:
result = Curl_setstropt(&data->set.str[STRING_DOH],
va_arg(param, char *));
data->set.doh = data->set.str[STRING_DOH]?TRUE:FALSE;
break;
+#endif
case CURLOPT_UPKEEP_INTERVAL_MS:
arg = va_arg(param, long);
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.upkeep_interval_ms = arg;
break;
+ case CURLOPT_MAXAGE_CONN:
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.maxage_conn = arg;
+ break;
case CURLOPT_TRAILERFUNCTION:
#ifndef CURL_DISABLE_HTTP
data->set.trailer_callback = va_arg(param, curl_trailer_callback);
diff --git a/lib/smtp.c b/lib/smtp.c
index b9304a4f7..106bd906f 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -28,6 +28,7 @@
* RFC4954 SMTP Authentication
* RFC5321 SMTP protocol
* RFC6749 OAuth 2.0 Authorization Framework
+ * RFC8314 Use of TLS for Email Submission and Access
* Draft SMTP URL Interface <draft-earhart-url-smtp-00.txt>
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
*
@@ -1218,7 +1219,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
returned CURLE_AGAIN, we duplicate the EOB now rather than when the
bytes written doesn't equal len. */
if(smtp->trailing_crlf || !conn->data->state.infilesize) {
- eob = strdup(SMTP_EOB + 2);
+ eob = strdup(&SMTP_EOB[2]);
len = SMTP_EOB_LEN - 2;
}
else {
@@ -1252,12 +1253,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
state(conn, SMTP_POSTDATA);
- /* Run the state-machine
-
- TODO: when the multi interface is used, this _really_ should be using
- the smtp_multi_statemach function but we have no general support for
- non-blocking DONE operations!
- */
+ /* Run the state-machine */
result = smtp_block_statemach(conn, FALSE);
}
diff --git a/lib/socks.c b/lib/socks.c
index d0aba0605..d8fcc3bbb 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -155,7 +155,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
Curl_addrinfo *hp = NULL;
int rc;
- rc = Curl_resolv(conn, hostname, remote_port, &dns);
+ rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
if(rc == CURLRESOLV_ERROR)
return CURLE_COULDNT_RESOLVE_PROXY;
@@ -290,7 +290,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
/* wrong version ? */
if(socksreq[0] != 0) {
failf(data,
- "SOCKS4 reply has wrong version, version should be 4.");
+ "SOCKS4 reply has wrong version, version should be 0.");
return CURLE_COULDNT_CONNECT;
}
@@ -527,12 +527,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
len = 0;
socksreq[len++] = 1; /* username/pw subnegotiation version */
socksreq[len++] = (unsigned char) proxy_user_len;
- if(proxy_user && proxy_user_len)
+ if(proxy_user && proxy_user_len) {
+ /* the length must fit in a single byte */
+ if(proxy_user_len >= 255) {
+ failf(data, "Excessive user name length for proxy auth");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
memcpy(socksreq + len, proxy_user, proxy_user_len);
+ }
len += proxy_user_len;
socksreq[len++] = (unsigned char) proxy_password_len;
- if(proxy_password && proxy_password_len)
+ if(proxy_password && proxy_password_len) {
+ /* the length must fit in a single byte */
+ if(proxy_password_len > 255) {
+ failf(data, "Excessive password length for proxy auth");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
memcpy(socksreq + len, proxy_password, proxy_password_len);
+ }
len += proxy_password_len;
code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
@@ -597,7 +609,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
else {
struct Curl_dns_entry *dns;
Curl_addrinfo *hp = NULL;
- int rc = Curl_resolv(conn, hostname, remote_port, &dns);
+ int rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
if(rc == CURLRESOLV_ERROR)
return CURLE_COULDNT_RESOLVE_HOST;
diff --git a/lib/splay.c b/lib/splay.c
index baf07e00d..0f5fcd1e8 100644
--- a/lib/splay.c
+++ b/lib/splay.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1997 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 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
@@ -198,7 +198,7 @@ struct Curl_tree *Curl_splaygetbest(struct curltime i,
/* Deletes the very node we point out from the tree if it's there. Stores a
* pointer to the new resulting tree in 'newroot'.
*
- * Returns zero on success and non-zero on errors! TODO: document error codes.
+ * Returns zero on success and non-zero on errors!
* When returning error, it does not touch the 'newroot' pointer.
*
* NOTE: when the last node of the tree is removed, there's no tree left so
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index f75fcd5ff..42ff56b69 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -1946,14 +1946,13 @@ static int myssh_getsock(struct connectdata *conn,
static void myssh_block2waitfor(struct connectdata *conn, bool block)
{
struct ssh_conn *sshc = &conn->proto.sshc;
- int dir;
/* 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) {
- dir = ssh_get_poll_flags(sshc->ssh_session);
+ 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;
@@ -2012,9 +2011,7 @@ static CURLcode myssh_block_statemach(struct connectdata *conn,
}
if(!result && block) {
- curl_socket_t sock = conn->sock[FIRSTSOCKET];
- curl_socket_t fd_read = CURL_SOCKET_BAD;
- fd_read = sock;
+ 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);
@@ -2052,7 +2049,6 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
CURLcode result;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
struct Curl_easy *data = conn->data;
- int rc;
/* initialize per-handle data if not already */
if(!data->req.protop)
@@ -2106,8 +2102,8 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
ssh->pubkey = NULL;
if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
- rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
- &ssh->pubkey);
+ 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 */
@@ -2227,12 +2223,7 @@ static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
struct SSHPROTO *protop = conn->data->req.protop;
if(!status) {
- /* run the state-machine
-
- TODO: when the multi interface is used, this _really_ should be using
- the ssh_multi_statemach function but we have no general support for
- non-blocking DONE operations!
- */
+ /* run the state-machine */
result = myssh_block_statemach(conn, FALSE);
}
else
diff --git a/lib/ssh.c b/lib/ssh.c
index b1b7b730a..267080f12 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -290,10 +290,6 @@ static CURLcode libssh2_session_error_to_CURLE(int err)
return CURLE_AGAIN;
}
- /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
- error code, and possibly add a few new SSH-related one. We must however
- not return or even depend on libssh2 errors in the public libcurl API */
-
return CURLE_SSH;
}
@@ -591,13 +587,13 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn)
struct Curl_easy *data = conn->data;
const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
char md5buffer[33];
- int i;
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);
@@ -737,18 +733,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
(strstr(sshc->authlist, "publickey") != NULL)) {
- char *home = NULL;
bool out_of_memory = FALSE;
sshc->rsa_pub = sshc->rsa = NULL;
- /* To ponder about: should really the lib be messing about with the
- HOME environment variable etc? */
- home = curl_getenv("HOME");
-
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. */
@@ -764,6 +759,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_safefree(sshc->rsa);
}
}
+ free(home);
}
if(!out_of_memory && !sshc->rsa) {
/* Nothing found; try the current dir. */
@@ -795,7 +791,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
if(out_of_memory || sshc->rsa == NULL) {
- free(home);
Curl_safefree(sshc->rsa);
Curl_safefree(sshc->rsa_pub);
state(conn, SSH_SESSION_FREE);
@@ -807,8 +802,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(!sshc->passphrase)
sshc->passphrase = "";
- free(home);
-
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);
@@ -3065,12 +3058,7 @@ static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
struct SSHPROTO *sftp_scp = conn->data->req.protop;
if(!status) {
- /* run the state-machine
-
- TODO: when the multi interface is used, this _really_ should be using
- the ssh_multi_statemach function but we have no general support for
- non-blocking DONE operations!
- */
+ /* run the state-machine */
result = ssh_block_statemach(conn, FALSE);
}
else
diff --git a/lib/tftp.c b/lib/tftp.c
index 73ddc1376..4713332d2 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -1009,7 +1009,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 = TFTP_BLKSIZE_DEFAULT;
+ state->blksize = blksize;
state->requested_blksize = blksize;
((struct sockaddr *)&state->local_addr)->sa_family =
diff --git a/lib/timeval.c b/lib/timeval.c
index ff8d8a69a..e2bd7fd14 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -66,7 +66,9 @@ struct curltime Curl_now(void)
** in any case the time starting point does not change once that the
** system has started up.
*/
+#ifdef HAVE_GETTIMEOFDAY
struct timeval now;
+#endif
struct curltime cnow;
struct timespec tsnow;
diff --git a/lib/transfer.c b/lib/transfer.c
index ea1b1e16f..b7c7b9bd1 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -157,15 +157,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
size_t buffersize = bytes;
size_t nread;
-#ifndef CURL_DISABLE_HTTP
- struct curl_slist *trailers = NULL;
- CURLcode c;
- int trailers_ret_code;
-#endif
-
curl_read_callback readfunc = NULL;
void *extra_data = NULL;
- bool added_crlf = FALSE;
#ifdef CURL_DOES_CONVERSIONS
bool sending_http_headers = FALSE;
@@ -182,6 +175,10 @@ 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;
+ int trailers_ret_code;
+
/* at this point we already verified that the callback exists
so we compile and store the trailers buffer, then proceed */
infof(data,
@@ -296,7 +293,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
here, knowing they'll become CRLFs later on.
*/
- char hexbuffer[11] = "";
+ bool added_crlf = FALSE;
int hexlen = 0;
const char *endofline_native;
const char *endofline_network;
@@ -317,6 +314,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
/* if we're not handling trailing data, proceed as usual */
if(data->state.trailers_state != TRAILERS_SENDING) {
+ char hexbuffer[11] = "";
hexlen = msnprintf(hexbuffer, sizeof(hexbuffer),
"%zx%s", nread, endofline_native);
@@ -463,7 +461,6 @@ CURLcode Curl_readrewind(struct connectdata *conn)
infof(data, "the ioctl callback returned %d\n", (int)err);
if(err) {
- /* FIXME: convert to a human readable error message */
failf(data, "ioctl callback returned error %d", (int)err);
return CURLE_SEND_FAIL_REWIND;
}
@@ -506,35 +503,6 @@ static int data_pending(const struct connectdata *conn)
#endif
}
-static void read_rewind(struct connectdata *conn,
- size_t thismuch)
-{
- DEBUGASSERT(conn->read_pos >= thismuch);
-
- conn->read_pos -= thismuch;
- conn->bits.stream_was_rewound = TRUE;
-
-#ifdef DEBUGBUILD
- {
- char buf[512 + 1];
- size_t show;
-
- show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
- if(conn->master_buffer) {
- memcpy(buf, conn->master_buffer + conn->read_pos, show);
- buf[show] = '\0';
- }
- else {
- buf[0] = '\0';
- }
-
- DEBUGF(infof(conn->data,
- "Buffer after stream rewind (read_pos = %zu): [%s]\n",
- conn->read_pos, buf));
- }
-#endif
-}
-
/*
* Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
* remote document with the time provided by CURLOPT_TIMEVAL
@@ -609,9 +577,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
conn->httpversion == 20) &&
#endif
k->size != -1 && !k->header) {
- /* make sure we don't read "too much" if we can help it since we
- might be pipelining and then someone else might want to read what
- follows! */
+ /* make sure we don't read too much */
curl_off_t totalleft = k->size - k->bytecount;
if(totalleft < (curl_off_t)bytestoread)
bytestoread = (size_t)totalleft;
@@ -650,7 +616,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(0 < nread || is_empty_data) {
k->buf[nread] = 0;
}
- else if(0 >= nread) {
+ else {
/* if we receive 0 or less here, the server closed the connection
and we bail out from this! */
DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
@@ -693,20 +659,11 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* We've stopped dealing with input, get out of the do-while loop */
if(nread > 0) {
- if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
- infof(data,
- "Rewinding stream by : %zd"
- " bytes on url %s (zero-length body)\n",
- nread, data->state.up.path);
- read_rewind(conn, (size_t)nread);
- }
- else {
- infof(data,
- "Excess found in a non pipelined read:"
- " excess = %zd"
- " url = %s (zero-length body)\n",
- nread, data->state.up.path);
- }
+ infof(data,
+ "Excess found:"
+ " excess = %zd"
+ " url = %s (zero-length body)\n",
+ nread, data->state.up.path);
}
break;
@@ -837,19 +794,12 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* There are now possibly N number of bytes at the end of the
str buffer that weren't written to the client.
-
- We DO care about this data if we are pipelining.
Push it back to be read on the next pass. */
dataleft = conn->chunk.dataleft;
if(dataleft != 0) {
infof(conn->data, "Leftovers after chunking: %zu bytes\n",
dataleft);
- if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
- /* only attempt the rewind if we truly are pipelining */
- infof(conn->data, "Rewinding %zu bytes\n",dataleft);
- read_rewind(conn, dataleft);
- }
}
}
/* If it returned OK, we just keep going */
@@ -868,25 +818,13 @@ static CURLcode readwrite_data(struct Curl_easy *data,
excess = (size_t)(k->bytecount + nread - k->maxdownload);
if(excess > 0 && !k->ignorebody) {
- if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
- infof(data,
- "Rewinding stream by : %zu"
- " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T
- ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
- ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n",
- excess, data->state.up.path,
- k->size, k->maxdownload, k->bytecount, nread);
- read_rewind(conn, excess);
- }
- else {
- infof(data,
- "Excess found in a non pipelined read:"
- " excess = %zu"
- ", size = %" CURL_FORMAT_CURL_OFF_T
- ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
- ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
- excess, k->size, k->maxdownload, k->bytecount);
- }
+ infof(data,
+ "Excess found in a read:"
+ " excess = %zu"
+ ", size = %" CURL_FORMAT_CURL_OFF_T
+ ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+ ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
+ excess, k->size, k->maxdownload, k->bytecount);
}
nread = (ssize_t) (k->maxdownload - k->bytecount);
@@ -1565,6 +1503,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
data->state.authhost.picked &= data->state.authhost.want;
data->state.authproxy.picked &= data->state.authproxy.want;
+#ifndef CURL_DISABLE_FTP
if(data->state.wildcardmatch) {
struct WildcardData *wc = &data->wildcard;
if(wc->state < CURLWC_INIT) {
@@ -1573,6 +1512,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
return CURLE_OUT_OF_MEMORY;
}
}
+#endif
}
return result;
diff --git a/lib/url.c b/lib/url.c
index eb09a24be..c441ae716 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -109,14 +109,12 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "connect.h"
#include "inet_ntop.h"
#include "http_ntlm.h"
-#include "curl_ntlm_wb.h"
#include "socks.h"
#include "curl_rtmp.h"
#include "gopher.h"
#include "http_proxy.h"
#include "conncache.h"
#include "multihandle.h"
-#include "pipeline.h"
#include "dotdot.h"
#include "strdup.h"
#include "setopt.h"
@@ -187,11 +185,11 @@ static const struct Curl_handler * const protocols[] = {
&Curl_handler_tftp,
#endif
-#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
+#if defined(USE_SSH)
&Curl_handler_scp,
#endif
-#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
+#if defined(USE_SSH)
&Curl_handler_sftp,
#endif
@@ -304,8 +302,7 @@ static void up_free(struct Curl_easy *data)
Curl_safefree(up->options);
Curl_safefree(up->path);
Curl_safefree(up->query);
- if(data->set.uh != data->state.uh)
- curl_url_cleanup(data->state.uh);
+ curl_url_cleanup(data->state.uh);
data->state.uh = NULL;
}
@@ -381,7 +378,9 @@ CURLcode Curl_close(struct Curl_easy *data)
Curl_altsvc_cleanup(data->asi);
data->asi = NULL;
#endif
- Curl_digest_cleanup(data);
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+ Curl_http_auth_cleanup_digest(data);
+#endif
Curl_safefree(data->info.contenttype);
Curl_safefree(data->info.wouldredirect);
@@ -440,11 +439,12 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->httpreq = HTTPREQ_GET; /* Default HTTP request */
set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
+#ifndef CURL_DISABLE_FILE
set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
set->ftp_filemethod = FTPFILE_MULTICWD;
-
+#endif
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
/* Set the default size of the SSL session ID cache */
@@ -543,6 +543,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->fnmatch = ZERO_NULL;
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->httpversion =
#ifdef USE_NGHTTP2
@@ -694,11 +695,6 @@ static void conn_shutdown(struct connectdata *conn)
if(CURL_SOCKET_BAD != conn->tempsock[1])
Curl_closesocket(conn, conn->tempsock[1]);
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
- defined(NTLM_WB_ENABLED)
- Curl_ntlm_wb_cleanup(conn);
-#endif
-
/* unlink ourselves. this should be called last since other shutdown
procedures need a valid conn->data and this may clear it. */
Curl_conncache_remove_conn(conn->data, conn, TRUE);
@@ -739,14 +735,10 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->secondaryhostname);
Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
- Curl_safefree(conn->master_buffer);
Curl_safefree(conn->connect_state);
conn_reset_all_postponed_data(conn);
-
- Curl_llist_destroy(&conn->send_pipe, NULL);
- Curl_llist_destroy(&conn->recv_pipe, NULL);
-
+ Curl_llist_destroy(&conn->easyq, NULL);
Curl_safefree(conn->localdev);
Curl_free_primary_ssl_config(&conn->ssl_config);
Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
@@ -804,17 +796,21 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
/* Cleanup NTLM connection-related data */
- Curl_http_ntlm_cleanup(conn);
+ Curl_http_auth_cleanup_ntlm(conn);
#endif
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
/* Cleanup NEGOTIATE connection-related data */
- Curl_cleanup_negotiate(conn);
+ Curl_http_auth_cleanup_negotiate(conn);
#endif
/* the protocol specific disconnect handler and conn_shutdown need a transfer
for the connection! */
conn->data = data;
+ if(conn->bits.connect_only)
+ /* treat the connection as dead in CONNECT_ONLY situations */
+ dead_connection = TRUE;
+
if(conn->handler->disconnect)
/* This is set if protocol-specific cleanups should be made */
conn->handler->disconnect(conn, dead_connection);
@@ -843,28 +839,21 @@ static bool SocketIsDead(curl_socket_t sock)
}
/*
- * IsPipeliningPossible()
+ * IsMultiplexingPossible()
*
- * Return a bitmask with the available pipelining and multiplexing options for
- * the given requested connection.
+ * Return a bitmask with the available multiplexing options for the given
+ * requested connection.
*/
-static int IsPipeliningPossible(const struct Curl_easy *handle,
- const struct connectdata *conn)
+static int IsMultiplexingPossible(const struct Curl_easy *handle,
+ const struct connectdata *conn)
{
int avail = 0;
- /* If a HTTP protocol and pipelining is enabled */
+ /* If a HTTP protocol and multiplexing is enabled */
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
(!conn->bits.protoconnstart || !conn->bits.close)) {
- if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
- (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
- (handle->set.httpreq == HTTPREQ_GET ||
- handle->set.httpreq == HTTPREQ_HEAD))
- /* didn't ask for HTTP/1.0 and a GET or HEAD */
- avail |= CURLPIPE_HTTP1;
-
- if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
+ if(Curl_multiplex_wanted(handle->multi) &&
(handle->set.httpversion >= CURL_HTTP_VERSION_2))
/* allows HTTP/2 */
avail |= CURLPIPE_MULTIPLEX;
@@ -872,84 +861,7 @@ static int IsPipeliningPossible(const struct Curl_easy *handle,
return avail;
}
-/* Returns non-zero if a handle was removed */
-int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
- struct curl_llist *pipeline)
-{
- if(pipeline) {
- struct curl_llist_element *curr;
-
- curr = pipeline->head;
- while(curr) {
- if(curr->ptr == handle) {
- Curl_llist_remove(pipeline, curr, NULL);
- return 1; /* we removed a handle */
- }
- curr = curr->next;
- }
- }
-
- return 0;
-}
-
-#if 0 /* this code is saved here as it is useful for debugging purposes */
-static void Curl_printPipeline(struct curl_llist *pipeline)
-{
- struct curl_llist_element *curr;
-
- curr = pipeline->head;
- while(curr) {
- struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
- infof(data, "Handle in pipeline: %s\n", data->state.path);
- curr = curr->next;
- }
-}
-#endif
-
-static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
-{
- struct curl_llist_element *curr = pipeline->head;
-#ifdef DEBUGBUILD
- {
- struct curl_llist_element *p = pipeline->head;
- while(p) {
- struct Curl_easy *e = p->ptr;
- DEBUGASSERT(GOOD_EASY_HANDLE(e));
- p = p->next;
- }
- }
-#endif
- if(curr) {
- return (struct Curl_easy *) curr->ptr;
- }
-
- return NULL;
-}
-
-/* remove the specified connection from all (possible) pipelines and related
- queues */
-void Curl_getoff_all_pipelines(struct Curl_easy *data,
- struct connectdata *conn)
-{
- if(!conn->bundle)
- return;
- if(conn->bundle->multiuse == BUNDLE_PIPELINING) {
- bool recv_head = (conn->readchannel_inuse &&
- Curl_recvpipe_head(data, conn));
- bool send_head = (conn->writechannel_inuse &&
- Curl_sendpipe_head(data, conn));
-
- if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
- Curl_pipeline_leave_read(conn);
- if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
- Curl_pipeline_leave_write(conn);
- }
- else {
- (void)Curl_removeHandleFromPipeline(data, &conn->recv_pipe);
- (void)Curl_removeHandleFromPipeline(data, &conn->send_pipe);
- }
-}
-
+#ifndef CURL_DISABLE_PROXY
static bool
proxy_info_matches(const struct proxy_info* data,
const struct proxy_info* needle)
@@ -961,6 +873,10 @@ proxy_info_matches(const struct proxy_info* data,
return FALSE;
}
+#else
+/* disabled, won't get called */
+#define proxy_info_matches(x,y) FALSE
+#endif
/*
* This function checks if the given connection is dead and extracts it from
@@ -974,10 +890,8 @@ proxy_info_matches(const struct proxy_info* data,
static bool extract_if_dead(struct connectdata *conn,
struct Curl_easy *data)
{
- size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
- if(!pipeLen && !CONN_INUSE(conn) && !conn->data) {
- /* The check for a dead socket makes sense only if there are no
- handles in pipeline and the connection isn't already marked in
+ if(!CONN_INUSE(conn) && !conn->data) {
+ /* The check for a dead socket makes sense only if the connection isn't in
use */
bool dead;
if(conn->handler->connection_check) {
@@ -1047,13 +961,25 @@ static void prune_dead_connections(struct Curl_easy *data)
}
}
+/* A connection has to have been idle for a shorter time than 'maxage_conn' to
+ be subject for reuse. The success rate is just too low after this. */
-static size_t max_pipeline_length(struct Curl_multi *multi)
+static bool conn_maxage(struct Curl_easy *data,
+ struct connectdata *conn,
+ struct curltime now)
{
- return multi ? multi->max_pipeline_length : 0;
-}
-
+ if(!conn->data) {
+ timediff_t idletime = Curl_timediff(now, conn->lastused);
+ idletime /= 1000; /* integer seconds is fine */
+ if(idletime/1000 > data->set.maxage_conn) {
+ infof(data, "Too old connection (%ld seconds), disconnect it\n",
+ idletime);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
/*
* Given one filled in connection struct (named needle), this function should
* detect if there already is one that has all the significant details
@@ -1063,8 +989,7 @@ static size_t max_pipeline_length(struct Curl_multi *multi)
* connection as 'in-use'. It must later be called with ConnectionDone() to
* return back to 'idle' (unused) state.
*
- * The force_reuse flag is set if the connection must be used, even if
- * the pipelining strategy wants to open a new connection instead of reusing.
+ * The force_reuse flag is set if the connection must be used.
*/
static bool
ConnectionExists(struct Curl_easy *data,
@@ -1076,8 +1001,9 @@ ConnectionExists(struct Curl_easy *data,
struct connectdata *check;
struct connectdata *chosen = 0;
bool foundPendingCandidate = FALSE;
- int canpipe = IsPipeliningPossible(data, needle);
+ bool canmultiplex = IsMultiplexingPossible(data, needle);
struct connectbundle *bundle;
+ struct curltime now = Curl_now();
#ifdef USE_NTLM
bool wantNTLMhttp = ((data->state.authhost.want &
@@ -1092,59 +1018,47 @@ ConnectionExists(struct Curl_easy *data,
*force_reuse = FALSE;
*waitpipe = FALSE;
- /* We can't pipeline if the site is blacklisted */
- if((canpipe & CURLPIPE_HTTP1) &&
- Curl_pipeline_site_blacklisted(data, needle))
- canpipe &= ~ CURLPIPE_HTTP1;
-
/* Look up the bundle with all the connections to this particular host.
Locks the connection cache, beware of early returns! */
bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
if(bundle) {
/* Max pipe length is zero (unlimited) for multiplexed connections */
- size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
- max_pipeline_length(data->multi):0;
- size_t best_pipe_len = max_pipe_len;
struct curl_llist_element *curr;
infof(data, "Found bundle for host %s: %p [%s]\n",
(needle->bits.conn_to_host ? needle->conn_to_host.name :
needle->host.name), (void *)bundle,
- (bundle->multiuse == BUNDLE_PIPELINING ?
- "can pipeline" :
- (bundle->multiuse == BUNDLE_MULTIPLEX ?
- "can multiplex" : "serially")));
-
- /* We can't pipeline if we don't know anything about the server */
- if(canpipe) {
- if(bundle->multiuse <= BUNDLE_UNKNOWN) {
+ (bundle->multiuse == BUNDLE_MULTIPLEX ?
+ "can multiplex" : "serially"));
+
+ /* We can't multiplex if we don't know anything about the server */
+ if(canmultiplex) {
+ if(bundle->multiuse == BUNDLE_UNKNOWN) {
if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
- infof(data, "Server doesn't support multi-use yet, wait\n");
+ infof(data, "Server doesn't support multiplex yet, wait\n");
*waitpipe = TRUE;
Curl_conncache_unlock(data);
return FALSE; /* no re-use */
}
- infof(data, "Server doesn't support multi-use (yet)\n");
- canpipe = 0;
- }
- if((bundle->multiuse == BUNDLE_PIPELINING) &&
- !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) {
- /* not asked for, switch off */
- infof(data, "Could pipeline, but not asked to!\n");
- canpipe = 0;
+ infof(data, "Server doesn't support multiplex (yet)\n");
+ canmultiplex = FALSE;
}
- else if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
- !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) {
+ if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
+ !Curl_multiplex_wanted(data->multi)) {
infof(data, "Could multiplex, but not asked to!\n");
- canpipe = 0;
+ canmultiplex = FALSE;
+ }
+ if(bundle->multiuse == BUNDLE_NO_MULTIUSE) {
+ infof(data, "Can not multiplex, even if we wanted to!\n");
+ canmultiplex = FALSE;
}
}
curr = bundle->conn_list.head;
while(curr) {
bool match = FALSE;
- size_t pipeLen;
+ size_t multiplexed;
/*
* Note that if we use a HTTP proxy in normal mode (no tunneling), we
@@ -1157,35 +1071,21 @@ ConnectionExists(struct Curl_easy *data,
/* connect-only connections will not be reused */
continue;
- if(extract_if_dead(check, data)) {
+ if(conn_maxage(data, check, now) || extract_if_dead(check, data)) {
/* disconnect it */
(void)Curl_disconnect(data, check, /* dead_connection */TRUE);
continue;
}
- pipeLen = check->send_pipe.size + check->recv_pipe.size;
+ multiplexed = CONN_INUSE(check) &&
+ (bundle->multiuse == BUNDLE_MULTIPLEX);
- if(canpipe) {
+ if(canmultiplex) {
if(check->bits.protoconnstart && check->bits.close)
continue;
-
- if(!check->bits.multiplex) {
- /* If not multiplexing, make sure the connection is fine for HTTP/1
- pipelining */
- struct Curl_easy* sh = gethandleathead(&check->send_pipe);
- struct Curl_easy* rh = gethandleathead(&check->recv_pipe);
- if(sh) {
- if(!(IsPipeliningPossible(sh, check) & CURLPIPE_HTTP1))
- continue;
- }
- else if(rh) {
- if(!(IsPipeliningPossible(rh, check) & CURLPIPE_HTTP1))
- continue;
- }
- }
}
else {
- if(pipeLen > 0) {
+ if(multiplexed) {
/* can only happen within multi handles, and means that another easy
handle is using this connection */
continue;
@@ -1210,13 +1110,6 @@ ConnectionExists(struct Curl_easy *data,
to get closed. */
infof(data, "Connection #%ld isn't open enough, can't reuse\n",
check->connection_id);
-#ifdef DEBUGBUILD
- if(check->recv_pipe.size > 0) {
- infof(data,
- "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
- check->connection_id);
- }
-#endif
continue;
}
}
@@ -1287,15 +1180,15 @@ ConnectionExists(struct Curl_easy *data,
}
}
- if(!canpipe && check->data)
- /* this request can't be pipelined but the checked connection is
+ if(!canmultiplex && check->data)
+ /* this request can't be multiplexed but the checked connection is
already in use so we skip it */
continue;
if(CONN_INUSE(check) && check->data &&
(check->data->multi != needle->data->multi))
- /* this could be subject for pipeline/multiplex use, but only if they
- belong to the same multi handle */
+ /* this could be subject for multiplex use, but only if they belong to
+ * the same multi handle */
continue;
if(needle->localdev || needle->localport) {
@@ -1386,7 +1279,7 @@ ConnectionExists(struct Curl_easy *data,
strcmp(needle->passwd, check->passwd))
continue;
}
- else if(check->ntlm.state != NTLMSTATE_NONE) {
+ else if(check->http_ntlm_state != NTLMSTATE_NONE) {
/* Connection is using NTLM auth but we don't want NTLM */
continue;
}
@@ -1402,7 +1295,7 @@ ConnectionExists(struct Curl_easy *data,
strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
continue;
}
- else if(check->proxyntlm.state != NTLMSTATE_NONE) {
+ else if(check->proxy_ntlm_state != NTLMSTATE_NONE) {
/* Proxy connection is using NTLM auth but we don't want NTLM */
continue;
}
@@ -1412,9 +1305,9 @@ ConnectionExists(struct Curl_easy *data,
chosen = check;
if((wantNTLMhttp &&
- (check->ntlm.state != NTLMSTATE_NONE)) ||
+ (check->http_ntlm_state != NTLMSTATE_NONE)) ||
(wantProxyNTLMhttp &&
- (check->proxyntlm.state != NTLMSTATE_NONE))) {
+ (check->proxy_ntlm_state != NTLMSTATE_NONE))) {
/* We must use this connection, no other */
*force_reuse = TRUE;
break;
@@ -1424,55 +1317,32 @@ ConnectionExists(struct Curl_easy *data,
continue;
}
#endif
- if(canpipe) {
- /* We can pipeline if we want to. Let's continue looking for
- the optimal connection to use, i.e the shortest pipe that is not
- blacklisted. */
+ if(canmultiplex) {
+ /* We can multiplex if we want to. Let's continue looking for
+ the optimal connection to use. */
- if(pipeLen == 0) {
+ if(!multiplexed) {
/* We have the optimal connection. Let's stop looking. */
chosen = check;
break;
}
- /* We can't use the connection if the pipe is full */
- if(max_pipe_len && (pipeLen >= max_pipe_len)) {
- infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
- continue;
- }
#ifdef USE_NGHTTP2
/* If multiplexed, make sure we don't go over concurrency limit */
if(check->bits.multiplex) {
/* Multiplexed connections can only be HTTP/2 for now */
struct http_conn *httpc = &check->proto.httpc;
- if(pipeLen >= httpc->settings.max_concurrent_streams) {
+ if(multiplexed >= httpc->settings.max_concurrent_streams) {
infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
- pipeLen);
+ multiplexed);
continue;
}
}
#endif
- /* We can't use the connection if the pipe is penalized */
- if(Curl_pipeline_penalized(data, check)) {
- infof(data, "Penalized, skip\n");
- continue;
- }
-
- if(max_pipe_len) {
- if(pipeLen < best_pipe_len) {
- /* This connection has a shorter pipe so far. We'll pick this
- and continue searching */
- chosen = check;
- best_pipe_len = pipeLen;
- continue;
- }
- }
- else {
- /* When not pipelining (== multiplexed), we have a match here! */
- chosen = check;
- infof(data, "Multiplexed connection found!\n");
- break;
- }
+ /* When not multiplexed, we have a match here! */
+ chosen = check;
+ infof(data, "Multiplexed connection found!\n");
+ break;
}
else {
/* We have found a connection. Let's stop searching. */
@@ -1874,16 +1744,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->http_proxy.proxytype = data->set.proxytype;
conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
-#ifdef CURL_DISABLE_PROXY
-
- conn->bits.proxy = FALSE;
- conn->bits.httpproxy = FALSE;
- conn->bits.socksproxy = FALSE;
- conn->bits.proxy_user_passwd = FALSE;
- conn->bits.tunnel_proxy = FALSE;
-
-#else /* CURL_DISABLE_PROXY */
-
+#if !defined(CURL_DISABLE_PROXY)
/* note that these two proxy bits are now just on what looks to be
requested, they may be altered down the road */
conn->bits.proxy = (data->set.str[STRING_PROXY] &&
@@ -1904,13 +1765,13 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->bits.proxy_user_passwd =
(data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
-
#endif /* CURL_DISABLE_PROXY */
conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE;
+#ifndef CURL_DISABLE_FTP
conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
-
+#endif
conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
@@ -1924,22 +1785,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
defined(NTLM_WB_ENABLED)
conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
- conn->ntlm_auth_hlpr_pid = 0;
- conn->challenge_header = NULL;
- conn->response_header = NULL;
#endif
- if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
- !conn->master_buffer) {
- /* Allocate master_buffer to be used for HTTP/1 pipelining */
- conn->master_buffer = calloc(MASTERBUF_SIZE, sizeof(char));
- if(!conn->master_buffer)
- goto error;
- }
-
- /* Initialize the pipeline lists */
- Curl_llist_init(&conn->send_pipe, (curl_llist_dtor) llist_dtor);
- Curl_llist_init(&conn->recv_pipe, (curl_llist_dtor) llist_dtor);
+ /* Initialize the easy handle list */
+ Curl_llist_init(&conn->easyq, (curl_llist_dtor) llist_dtor);
#ifdef HAVE_GSSAPI
conn->data_prot = PROT_CLEAR;
@@ -1962,10 +1811,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
return conn;
error:
- Curl_llist_destroy(&conn->send_pipe, NULL);
- Curl_llist_destroy(&conn->recv_pipe, NULL);
-
- free(conn->master_buffer);
+ Curl_llist_destroy(&conn->easyq, NULL);
free(conn->localdev);
#ifdef USE_SSL
free(conn->ssl_extra);
@@ -2052,7 +1898,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
/* parse the URL */
if(data->set.uh) {
- uh = data->state.uh = data->set.uh;
+ uh = data->state.uh = curl_url_dup(data->set.uh);
}
else {
uh = data->state.uh = curl_url();
@@ -2156,61 +2002,40 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
hostname = (char *)"";
if(hostname[0] == '[') {
- /* This looks like an IPv6 address literal. See if there is an address
+ /* This looks like an IPv6 address literal. See if there is an address
scope. */
- char *percent = strchr(++hostname, '%');
+ char *zoneid;
+ size_t hlen;
+ uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
conn->bits.ipv6_ip = TRUE;
- if(percent) {
- unsigned int identifier_offset = 3;
+
+ /* cut off the brackets! */
+ hostname++;
+ hlen = strlen(hostname);
+ hostname[hlen - 1] = 0;
+ if(!uc && zoneid) {
char *endp;
unsigned long scope;
- if(strncmp("%25", percent, 3) != 0) {
- infof(data,
- "Please URL encode %% as %%25, see RFC 6874.\n");
- identifier_offset = 1;
- }
- scope = strtoul(percent + identifier_offset, &endp, 10);
- if(*endp == ']') {
- /* The address scope was well formed. Knock it out of the
- hostname. */
- memmove(percent, endp, strlen(endp) + 1);
+ scope = strtoul(zoneid, &endp, 10);
+ if(!*endp && (scope < UINT_MAX)) {
+ /* A plain number, use it direcly as a scope id. */
conn->scope_id = (unsigned int)scope;
}
+#ifdef HAVE_IF_NAMETOINDEX
else {
/* Zone identifier is not numeric */
-#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
- char ifname[IFNAMSIZ + 2];
- char *square_bracket;
unsigned int scopeidx = 0;
- strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
- /* Ensure nullbyte termination */
- ifname[IFNAMSIZ + 1] = '\0';
- square_bracket = strchr(ifname, ']');
- if(square_bracket) {
- /* Remove ']' */
- *square_bracket = '\0';
- scopeidx = if_nametoindex(ifname);
- if(scopeidx == 0) {
- infof(data, "Invalid network interface: %s; %s\n", ifname,
- strerror(errno));
- }
- }
- if(scopeidx > 0) {
- char *p = percent + identifier_offset + strlen(ifname);
-
- /* Remove zone identifier from hostname */
- memmove(percent, p, strlen(p) + 1);
- conn->scope_id = scopeidx;
- }
+ scopeidx = if_nametoindex(zoneid);
+ if(!scopeidx)
+ infof(data, "Invalid zoneid id: %s; %s\n", zoneid,
+ strerror(errno));
else
-#endif /* HAVE_NET_IF_H && IFNAMSIZ */
- infof(data, "Invalid IPv6 address format\n");
+ conn->scope_id = scopeidx;
+
}
+#endif /* HAVE_IF_NAMETOINDEX */
+ free(zoneid);
}
- percent = strchr(hostname, ']');
- if(percent)
- /* terminate IPv6 numerical at end bracket */
- *percent = 0;
}
/* make sure the connect struct gets its own copy of the host name */
@@ -2473,46 +2298,55 @@ static CURLcode parse_proxy(struct Curl_easy *data,
struct connectdata *conn, char *proxy,
curl_proxytype proxytype)
{
- char *prox_portno;
- char *endofprot;
-
- /* We use 'proxyptr' to point to the proxy name from now on... */
- char *proxyptr;
char *portptr;
- char *atsign;
long port = -1;
char *proxyuser = NULL;
char *proxypasswd = NULL;
+ char *host;
bool sockstype;
+ CURLUcode uc;
+ struct proxy_info *proxyinfo;
+ CURLU *uhp = curl_url();
+ CURLcode result = CURLE_OK;
+ char *scheme = NULL;
- /* We do the proxy host string parsing here. We want the host name and the
- * port name. Accept a protocol:// prefix
- */
+ /* When parsing the proxy, allowing non-supported schemes since we have
+ these made up ones for proxies. Guess scheme for URLs without it. */
+ uc = curl_url_set(uhp, CURLUPART_URL, proxy,
+ CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME);
+ if(!uc) {
+ /* parsed okay as a URL */
+ uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0);
+ if(uc) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
- /* Parse the protocol part if present */
- endofprot = strstr(proxy, "://");
- if(endofprot) {
- proxyptr = endofprot + 3;
- if(checkprefix("https", proxy))
+ if(strcasecompare("https", scheme))
proxytype = CURLPROXY_HTTPS;
- else if(checkprefix("socks5h", proxy))
+ else if(strcasecompare("socks5h", scheme))
proxytype = CURLPROXY_SOCKS5_HOSTNAME;
- else if(checkprefix("socks5", proxy))
+ else if(strcasecompare("socks5", scheme))
proxytype = CURLPROXY_SOCKS5;
- else if(checkprefix("socks4a", proxy))
+ else if(strcasecompare("socks4a", scheme))
proxytype = CURLPROXY_SOCKS4A;
- else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
+ else if(strcasecompare("socks4", scheme) ||
+ strcasecompare("socks", scheme))
proxytype = CURLPROXY_SOCKS4;
- else if(checkprefix("http:", proxy))
+ else if(strcasecompare("http", scheme))
; /* leave it as HTTP or HTTP/1.0 */
else {
/* Any other xxx:// reject! */
failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
- return CURLE_COULDNT_CONNECT;
+ result = CURLE_COULDNT_CONNECT;
+ goto error;
}
}
- else
- proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
+ else {
+ failf(data, "Unsupported proxy syntax in \'%s\'", proxy);
+ result = CURLE_COULDNT_RESOLVE_PROXY;
+ goto error;
+ }
#ifdef USE_SSL
if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY))
@@ -2520,93 +2354,44 @@ static CURLcode parse_proxy(struct Curl_easy *data,
if(proxytype == CURLPROXY_HTTPS) {
failf(data, "Unsupported proxy \'%s\', libcurl is built without the "
"HTTPS-proxy support.", proxy);
- return CURLE_NOT_BUILT_IN;
+ result = CURLE_NOT_BUILT_IN;
+ goto error;
}
- sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- proxytype == CURLPROXY_SOCKS5 ||
- proxytype == CURLPROXY_SOCKS4A ||
- proxytype == CURLPROXY_SOCKS4;
+ sockstype =
+ proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+ proxytype == CURLPROXY_SOCKS5 ||
+ proxytype == CURLPROXY_SOCKS4A ||
+ proxytype == CURLPROXY_SOCKS4;
- /* Is there a username and password given in this proxy url? */
- atsign = strchr(proxyptr, '@');
- if(atsign) {
- CURLcode result =
- Curl_parse_login_details(proxyptr, atsign - proxyptr,
- &proxyuser, &proxypasswd, NULL);
- if(result)
- return result;
- proxyptr = atsign + 1;
- }
-
- /* start scanning for port number at this point */
- portptr = proxyptr;
+ proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy;
+ proxyinfo->proxytype = proxytype;
- /* detect and extract RFC6874-style IPv6-addresses */
- if(*proxyptr == '[') {
- char *ptr = ++proxyptr; /* advance beyond the initial bracket */
- while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
- ptr++;
- if(*ptr == '%') {
- /* There might be a zone identifier */
- if(strncmp("%25", ptr, 3))
- infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
- ptr++;
- /* Allow unreserved characters as defined in RFC 3986 */
- while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
- (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
- ptr++;
+ /* Is there a username and password given in this proxy url? */
+ curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE);
+ curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE);
+ if(proxyuser || proxypasswd) {
+ Curl_safefree(proxyinfo->user);
+ proxyinfo->user = proxyuser;
+ Curl_safefree(proxyinfo->passwd);
+ if(!proxypasswd) {
+ proxypasswd = strdup("");
+ if(!proxypasswd) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
}
- if(*ptr == ']')
- /* yeps, it ended nicely with a bracket as well */
- *ptr++ = 0;
- else
- infof(data, "Invalid IPv6 address format\n");
- portptr = ptr;
- /* Note that if this didn't end with a bracket, we still advanced the
- * proxyptr first, but I can't see anything wrong with that as no host
- * name nor a numeric can legally start with a bracket.
- */
+ proxyinfo->passwd = proxypasswd;
+ conn->bits.proxy_user_passwd = TRUE; /* enable it */
}
- /* Get port number off proxy.server.com:1080 */
- prox_portno = strchr(portptr, ':');
- if(prox_portno) {
- char *endp = NULL;
+ curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
- *prox_portno = 0x0; /* cut off number from host name */
- prox_portno ++;
- /* now set the local port number */
- port = strtol(prox_portno, &endp, 10);
- if((endp && *endp && (*endp != '/') && (*endp != ' ')) ||
- (port < 0) || (port > 65535)) {
- /* meant to detect for example invalid IPv6 numerical addresses without
- brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only
- because we then allow "URL style" with the number followed by a
- slash, used in curl test cases already. Space is also an acceptable
- terminating symbol. */
- infof(data, "No valid port number in proxy string (%s)\n",
- prox_portno);
- }
- else
- conn->port = port;
+ if(portptr) {
+ port = strtol(portptr, NULL, 10);
+ free(portptr);
}
else {
- if(proxyptr[0]=='/') {
- /* If the first character in the proxy string is a slash, fail
- immediately. The following code will otherwise clear the string which
- will lead to code running as if no proxy was set! */
- Curl_safefree(proxyuser);
- Curl_safefree(proxypasswd);
- return CURLE_COULDNT_RESOLVE_PROXY;
- }
-
- /* without a port number after the host name, some people seem to use
- a slash so we strip everything from the first slash */
- atsign = strchr(proxyptr, '/');
- if(atsign)
- *atsign = '\0'; /* cut off path part from host name */
-
if(data->set.proxyport)
/* None given in the proxy string, then get the default one if it is
given */
@@ -2618,57 +2403,32 @@ static CURLcode parse_proxy(struct Curl_easy *data,
port = CURL_DEFAULT_PROXY_PORT;
}
}
-
- if(*proxyptr) {
- struct proxy_info *proxyinfo =
- sockstype ? &conn->socks_proxy : &conn->http_proxy;
- proxyinfo->proxytype = proxytype;
-
- if(proxyuser) {
- /* found user and password, rip them out. note that we are unescaping
- them, as there is otherwise no way to have a username or password
- with reserved characters like ':' in them. */
- Curl_safefree(proxyinfo->user);
- proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
- Curl_safefree(proxyuser);
-
- if(!proxyinfo->user) {
- Curl_safefree(proxypasswd);
- return CURLE_OUT_OF_MEMORY;
- }
-
- Curl_safefree(proxyinfo->passwd);
- if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
- proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
- else
- proxyinfo->passwd = strdup("");
- Curl_safefree(proxypasswd);
-
- if(!proxyinfo->passwd)
- return CURLE_OUT_OF_MEMORY;
-
- conn->bits.proxy_user_passwd = TRUE; /* enable it */
- }
-
- if(port >= 0) {
- proxyinfo->port = port;
- if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
- conn->port = port;
- }
-
- /* now, clone the cleaned proxy host name */
- Curl_safefree(proxyinfo->host.rawalloc);
- proxyinfo->host.rawalloc = strdup(proxyptr);
- proxyinfo->host.name = proxyinfo->host.rawalloc;
-
- if(!proxyinfo->host.rawalloc)
- return CURLE_OUT_OF_MEMORY;
+ if(port >= 0) {
+ proxyinfo->port = port;
+ if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
+ conn->port = port;
}
- Curl_safefree(proxyuser);
- Curl_safefree(proxypasswd);
+ /* now, clone the proxy host name */
+ uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE);
+ if(uc) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ Curl_safefree(proxyinfo->host.rawalloc);
+ proxyinfo->host.rawalloc = host;
+ if(host[0] == '[') {
+ /* this is a numerical IPv6, strip off the brackets */
+ size_t len = strlen(host);
+ host[len-1] = 0; /* clear the trailing bracket */
+ host++;
+ }
+ proxyinfo->host.name = host;
- return CURLE_OK;
+ error:
+ free(scheme);
+ curl_url_cleanup(uhp);
+ return result;
}
/*
@@ -3614,11 +3374,7 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->http_proxy.passwd);
Curl_safefree(old_conn->socks_proxy.passwd);
Curl_safefree(old_conn->localdev);
-
- Curl_llist_destroy(&old_conn->send_pipe, NULL);
- Curl_llist_destroy(&old_conn->recv_pipe, NULL);
-
- Curl_safefree(old_conn->master_buffer);
+ Curl_llist_destroy(&old_conn->easyq, NULL);
#ifdef USE_UNIX_SOCKETS
Curl_safefree(old_conn->unix_domain_socket);
@@ -3933,12 +3689,12 @@ static CURLcode create_conn(struct Curl_easy *data,
reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
/* If we found a reusable connection that is now marked as in use, we may
- still want to open a new connection if we are pipelining. */
- if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
- size_t pipelen = conn_temp->send_pipe.size + conn_temp->recv_pipe.size;
- if(pipelen > 0) {
- infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
- conn_temp->connection_id, pipelen);
+ still want to open a new connection if we are multiplexing. */
+ if(reuse && !force_reuse && IsMultiplexingPossible(data, conn_temp)) {
+ size_t multiplexed = CONN_INUSE(conn_temp);
+ if(multiplexed > 0) {
+ infof(data, "Found connection %ld, with %zu requests on it\n",
+ conn_temp->connection_id, multiplexed);
if(Curl_conncache_bundle_size(conn_temp) < max_host_connections &&
Curl_conncache_size(data) < max_total_connections) {
@@ -3988,7 +3744,7 @@ static CURLcode create_conn(struct Curl_easy *data,
}
if(waitpipe)
- /* There is a connection that *might* become usable for pipelining
+ /* There is a connection that *might* become usable for multiplexing
"soon", and we wait for that */
connections_available = FALSE;
else {
@@ -4201,7 +3957,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
if(!result) {
if(CONN_INUSE(conn))
- /* pipelining */
+ /* multiplexed */
*protocol_done = TRUE;
else if(!*asyncp) {
/* DNS resolution is done: that's either because this is a reused
@@ -4219,7 +3975,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
connectdata struct, free those here */
Curl_disconnect(data, conn, TRUE);
}
- else if(!data->conn)
+ else if(!result && !data->conn)
/* FILE: transfers already have the connection attached */
Curl_attach_connnection(data, conn);
diff --git a/lib/url.h b/lib/url.h
index fbd8ef925..4db9e8653 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -71,14 +71,7 @@ int Curl_doing_getsock(struct connectdata *conn,
CURLcode Curl_parse_login_details(const char *login, const size_t len,
char **userptr, char **passwdptr,
char **optionsptr);
-
-int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
- struct curl_llist *pipeline);
-/* remove the specified connection from all (possible) pipelines and related
- queues */
-void Curl_getoff_all_pipelines(struct Curl_easy *data,
- struct connectdata *conn);
-
+void Curl_close_connections(struct Curl_easy *data);
CURLcode Curl_upkeep(struct conncache *conn_cache, void *data);
const struct Curl_handler *Curl_builtin_scheme(const char *scheme);
diff --git a/lib/urlapi-int.h b/lib/urlapi-int.h
index 75a360542..5f059c203 100644
--- a/lib/urlapi-int.h
+++ b/lib/urlapi-int.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
@@ -22,9 +22,8 @@
*
***************************************************************************/
#include "curl_setup.h"
-/* scheme is not URL encoded, the longest libcurl supported ones are 6
- letters */
-#define MAX_SCHEME_LEN 8
+/* scheme is not URL encoded, the longest libcurl supported ones are... */
+#define MAX_SCHEME_LEN 40
bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
char *Curl_concat_url(const char *base, const char *relurl);
diff --git a/lib/urlapi.c b/lib/urlapi.c
index a19867eb0..d07e4f5df 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -56,6 +56,7 @@ struct Curl_URL {
char *password;
char *options; /* IMAP only? */
char *host;
+ char *zoneid; /* for numerical IPv6 addresses */
char *port;
char *path;
char *query;
@@ -74,6 +75,7 @@ static void free_urlhandle(struct Curl_URL *u)
free(u->password);
free(u->options);
free(u->host);
+ free(u->zoneid);
free(u->port);
free(u->path);
free(u->query);
@@ -504,7 +506,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
portptr = &hostname[len];
else if('%' == endbracket) {
int zonelen = len;
- if(1 == sscanf(hostname + zonelen, "25%*[^]]%c%n", &endbracket, &len)) {
+ if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) {
if(']' != endbracket)
return CURLUE_MALFORMED_INPUT;
portptr = &hostname[--zonelen + len + 1];
@@ -587,25 +589,45 @@ static CURLUcode junkscan(char *part)
return CURLUE_OK;
}
-static CURLUcode hostname_check(char *hostname, unsigned int flags)
+static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
{
const char *l = NULL; /* accepted characters */
size_t len;
size_t hlen = strlen(hostname);
- (void)flags;
if(hostname[0] == '[') {
hostname++;
- l = "0123456789abcdefABCDEF::.%";
+ l = "0123456789abcdefABCDEF::.";
hlen -= 2;
}
if(l) {
/* only valid letters are ok */
len = strspn(hostname, l);
- if(hlen != len)
- /* hostname with bad content */
- return CURLUE_MALFORMED_INPUT;
+ if(hlen != len) {
+ if(hostname[len] == '%') {
+ /* this could now be '%[zone id]' */
+ char zoneid[16];
+ int i = 0;
+ char *h = &hostname[len + 1];
+ /* pass '25' if present and is a url encoded percent sign */
+ if(!strncmp(h, "25", 2) && h[2] && (h[2] != ']'))
+ h += 2;
+ while(*h && (*h != ']') && (i < 15))
+ zoneid[i++] = *h++;
+ if(!i || (']' != *h))
+ return CURLUE_MALFORMED_INPUT;
+ zoneid[i] = 0;
+ u->zoneid = strdup(zoneid);
+ if(!u->zoneid)
+ return CURLUE_OUT_OF_MEMORY;
+ hostname[len] = ']'; /* insert end bracket */
+ hostname[len + 1] = 0; /* terminate the hostname */
+ }
+ else
+ return CURLUE_MALFORMED_INPUT;
+ /* hostname is fine */
+ }
}
else {
/* letters from the second string is not ok */
@@ -614,6 +636,8 @@ static CURLUcode hostname_check(char *hostname, unsigned int flags)
/* hostname with bad content */
return CURLUE_MALFORMED_INPUT;
}
+ if(!hostname[0])
+ return CURLUE_NO_HOST;
return CURLUE_OK;
}
@@ -628,7 +652,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
char *fragment = NULL;
CURLUcode result;
bool url_has_scheme = FALSE;
- char schemebuf[MAX_SCHEME_LEN];
+ char schemebuf[MAX_SCHEME_LEN + 1];
char *schemep = NULL;
size_t schemelen = 0;
size_t urllen;
@@ -642,6 +666,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
************************************************************/
/* allocate scratch area */
urllen = strlen(url);
+ if(urllen > CURL_MAX_INPUT_LENGTH)
+ /* excessive input length */
+ return CURLUE_MALFORMED_INPUT;
+
path = u->scratch = malloc(urllen * 2 + 2);
if(!path)
return CURLUE_OUT_OF_MEMORY;
@@ -852,7 +880,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(result)
return result;
- result = hostname_check(hostname, flags);
+ result = hostname_check(u, hostname);
if(result)
return result;
@@ -971,6 +999,9 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
ptr = u->host;
ifmissing = CURLUE_NO_HOST;
break;
+ case CURLUPART_ZONEID:
+ ptr = u->zoneid;
+ break;
case CURLUPART_PORT:
ptr = u->port;
ifmissing = CURLUE_NO_PORT;
@@ -1017,6 +1048,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
char *scheme;
char *options = u->options;
char *port = u->port;
+ char *allochost = NULL;
if(u->scheme && strcasecompare("file", u->scheme)) {
url = aprintf("file://%s%s%s",
u->path,
@@ -1055,6 +1087,18 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
if(h && !(h->flags & PROTOPT_URLOPTIONS))
options = NULL;
+ if((u->host[0] == '[') && u->zoneid) {
+ /* make it '[ host %25 zoneid ]' */
+ size_t hostlen = strlen(u->host);
+ size_t alen = hostlen + 3 + strlen(u->zoneid) + 1;
+ allochost = malloc(alen);
+ if(!allochost)
+ return CURLUE_OUT_OF_MEMORY;
+ memcpy(allochost, u->host, hostlen - 1);
+ msnprintf(&allochost[hostlen - 1], alen - hostlen + 1,
+ "%%25%s]", u->zoneid);
+ }
+
url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
scheme,
u->user ? u->user : "",
@@ -1063,7 +1107,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
options ? ";" : "",
options ? options : "",
(u->user || u->password || options) ? "@": "",
- u->host,
+ allochost ? allochost : u->host,
port ? ":": "",
port ? port : "",
(u->path && (u->path[0] != '/')) ? "/": "",
@@ -1072,6 +1116,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
(u->query && u->query[0]) ? u->query : "",
u->fragment? "#": "",
u->fragment? u->fragment : "");
+ free(allochost);
}
if(!url)
return CURLUE_OUT_OF_MEMORY;
@@ -1144,7 +1189,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
case CURLUPART_HOST:
storep = &u->host;
break;
+ case CURLUPART_ZONEID:
+ storep = &u->zoneid;
+ break;
case CURLUPART_PORT:
+ u->portnum = 0;
storep = &u->port;
break;
case CURLUPART_PATH:
@@ -1168,6 +1217,9 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
switch(what) {
case CURLUPART_SCHEME:
+ if(strlen(part) > MAX_SCHEME_LEN)
+ /* too long */
+ return CURLUE_MALFORMED_INPUT;
if(!(flags & CURLU_NON_SUPPORT_SCHEME) &&
/* verify that it is a fine scheme */
!Curl_builtin_scheme(part))
@@ -1186,14 +1238,25 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
break;
case CURLUPART_HOST:
storep = &u->host;
+ free(u->zoneid);
+ u->zoneid = NULL;
+ break;
+ case CURLUPART_ZONEID:
+ storep = &u->zoneid;
break;
case CURLUPART_PORT:
+ {
+ char *endp;
urlencode = FALSE; /* never */
- port = strtol(part, NULL, 10); /* Port number must be decimal */
+ port = strtol(part, &endp, 10); /* Port number must be decimal */
if((port <= 0) || (port > 0xffff))
return CURLUE_BAD_PORT_NUMBER;
+ if(*endp)
+ /* weirdly provided number, not good! */
+ return CURLUE_MALFORMED_INPUT;
storep = &u->port;
- break;
+ }
+ break;
case CURLUPART_PATH:
urlskipslash = TRUE;
storep = &u->path;
@@ -1219,7 +1282,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
char *redired_url;
CURLU *handle2;
- if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN)) {
+ if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) {
handle2 = curl_url();
if(!handle2)
return CURLUE_OUT_OF_MEMORY;
@@ -1272,8 +1335,12 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
const char *newp = part;
size_t nalloc = strlen(part);
+ if(nalloc > CURL_MAX_INPUT_LENGTH)
+ /* excessive input length */
+ return CURLUE_MALFORMED_INPUT;
+
if(urlencode) {
- const char *i;
+ const unsigned char *i;
char *o;
bool free_part = FALSE;
char *enc = malloc(nalloc * 3 + 1); /* for worst case! */
@@ -1281,7 +1348,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_OUT_OF_MEMORY;
if(plusencode) {
/* space to plus */
- i = part;
+ i = (const unsigned char *)part;
for(o = enc; *i; ++o, ++i)
*o = (*i == ' ') ? '+' : *i;
*o = 0; /* zero terminate */
@@ -1292,7 +1359,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
free_part = TRUE;
}
- for(i = part, o = enc; *i; i++) {
+ for(i = (const unsigned char *)part, o = enc; *i; i++) {
if(Curl_isunreserved(*i) ||
((*i == '/') && urlskipslash) ||
((*i == '=') && equalsencode) ||
@@ -1355,6 +1422,13 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
}
+ if(what == CURLUPART_HOST) {
+ if(hostname_check(u, (char *)newp)) {
+ free((char *)newp);
+ return CURLUE_MALFORMED_INPUT;
+ }
+ }
+
free(*storep);
*storep = (char *)newp;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 0681e8da7..5ca202f2e 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -79,6 +79,10 @@
*/
#define RESP_TIMEOUT (120*1000)
+/* Max string intput length is a precaution against abuse and to detect junk
+ input easier and better. */
+#define CURL_MAX_INPUT_LENGTH 8000000
+
#include "cookie.h"
#include "psl.h"
#include "formdata.h"
@@ -144,10 +148,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#include <libssh2_sftp.h>
#endif /* HAVE_LIBSSH2_H */
-
-/* The "master buffer" is for HTTP pipelining */
-#define MASTERBUF_SIZE 16384
-
/* Initial size of the buffer to store headers in, it'll be enlarged in case
of need. */
#define HEADERSIZE 256
@@ -304,6 +304,14 @@ typedef enum {
NTLMSTATE_LAST
} curlntlm;
+typedef enum {
+ GSS_AUTHNONE,
+ GSS_AUTHRECV,
+ GSS_AUTHSENT,
+ GSS_AUTHDONE,
+ GSS_AUTHSUCC
+} curlnegotiate;
+
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
#include <iconv.h>
#endif
@@ -329,7 +337,6 @@ struct kerberos5data {
/* Struct used for NTLM challenge-response authentication */
#if defined(USE_NTLM)
struct ntlmdata {
- curlntlm state;
#ifdef USE_WINDOWS_SSPI
/* The sslContext is used for the Schannel bindings. The
* api is available on the Windows 7 SDK and later.
@@ -355,13 +362,9 @@ struct ntlmdata {
};
#endif
+/* Struct used for Negotiate (SPNEGO) authentication */
#ifdef USE_SPNEGO
struct negotiatedata {
- /* When doing Negotiate (SPNEGO) auth, we first need to send a token
- and then validate the received one. */
- enum {
- GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT, GSS_AUTHDONE, GSS_AUTHSUCC
- } state;
#ifdef HAVE_GSSAPI
OM_uint32 status;
gss_ctx_id_t context;
@@ -432,6 +435,7 @@ struct ConnectBits {
though it will be discarded. When the whole send
operation is done, we must call the data rewind
callback. */
+#ifndef CURL_DISABLE_FTP
bit ftp_use_epsv:1; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
EPSV doesn't work we disable it for the forthcoming
requests */
@@ -439,6 +443,7 @@ struct ConnectBits {
EPRT doesn't work we disable it for the forthcoming
requests */
bit ftp_use_data_ssl:1; /* Enabled SSL for the data connection */
+#endif
bit netrc:1; /* name+password provided by netrc */
bit userpwd_in_url:1; /* name+password found in url */
bit stream_was_rewound:1; /* The stream was rewound after a request read
@@ -605,7 +610,9 @@ struct SingleRequest {
char *upload_fromhere;
void *protop; /* Allocated protocol-specific data. Each protocol
handler makes sure this points to data it needs. */
+#ifndef CURL_DISABLE_DOH
struct dohdata doh; /* DoH specific data for this request */
+#endif
bit header:1; /* incoming data has HTTP header */
bit content_range:1; /* set TRUE if Content-Range: was found */
bit upload_done:1; /* set to TRUE when doing chunked transfer-encoding
@@ -797,11 +804,10 @@ struct connectdata {
void *closesocket_client;
/* This is used by the connection cache logic. If this returns TRUE, this
- handle is being used by one or more easy handles and can only used by any
+ handle is still used by one or more easy handles and can only used by any
other easy handle without careful consideration (== only for
- pipelining/multiplexing) and it cannot be used by another multi
- handle! */
-#define CONN_INUSE(c) ((c)->send_pipe.size + (c)->recv_pipe.size)
+ multiplexing) and it cannot be used by another multi handle! */
+#define CONN_INUSE(c) ((c)->easyq.size)
/**** Fields set when inited and not modified again */
long connection_id; /* Contains a unique number to make it easier to
@@ -872,6 +878,7 @@ struct connectdata {
struct curltime now; /* "current" time */
struct curltime created; /* creation time */
+ struct curltime lastused; /* when returned to the connection cache */
curl_socket_t sock[2]; /* two sockets, the second is used for the data
transfer when doing FTP */
curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
@@ -951,16 +958,7 @@ struct connectdata {
struct kerberos5data krb5; /* variables into the structure definition, */
#endif /* however, some of them are ftp specific. */
- struct curl_llist send_pipe; /* List of handles waiting to send on this
- pipeline */
- struct curl_llist recv_pipe; /* List of handles waiting to read their
- responses on this pipeline */
- char *master_buffer; /* The master buffer allocated on-demand;
- used for pipelining. */
- size_t read_pos; /* Current read position in the master buffer */
- size_t buf_len; /* Length of the buffer?? */
-
-
+ struct curl_llist easyq; /* List of easy handles using this connection */
curl_seek_callback seek_func; /* function that seeks the input */
void *seek_client; /* pointer to pass to the seek() above */
@@ -970,6 +968,9 @@ struct connectdata {
#endif
#if defined(USE_NTLM)
+ curlntlm http_ntlm_state;
+ curlntlm proxy_ntlm_state;
+
struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
because it authenticates connections, not
single requests! */
@@ -985,6 +986,9 @@ struct connectdata {
#endif
#ifdef USE_SPNEGO
+ curlnegotiate http_negotiate_state;
+ curlnegotiate proxy_negotiate_state;
+
struct negotiatedata negotiate; /* state data for host Negotiate auth */
struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
#endif
@@ -1210,6 +1214,7 @@ typedef enum {
EXPIRE_ASYNC_NAME,
EXPIRE_CONNECTTIMEOUT,
EXPIRE_DNS_PER_NAME,
+ EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */
EXPIRE_HAPPY_EYEBALLS,
EXPIRE_MULTI_PENDING,
EXPIRE_RUN_NOW,
@@ -1288,7 +1293,6 @@ struct UrlState {
struct auth authhost; /* auth details for host */
struct auth authproxy; /* auth details for proxy */
-
void *resolver; /* resolver state, if it is used in the URL state -
ares_channel f.e. */
@@ -1372,6 +1376,7 @@ struct UrlState {
when multi_done() is called, to prevent multi_done() to get
invoked twice when the multi interface is used. */
bit stream_depends_e:1; /* set or don't set the Exclusive bit */
+ bit previouslypending:1; /* this transfer WAS in the multi->pending queue */
};
@@ -1462,7 +1467,7 @@ enum dupstring {
STRING_RTSP_SESSION_ID, /* Session ID to use */
STRING_RTSP_STREAM_URI, /* Stream URI for this request */
STRING_RTSP_TRANSPORT, /* Transport for this session */
-#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
+#ifdef USE_SSH
STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */
STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
@@ -1567,6 +1572,8 @@ struct UserDefined {
long accepttimeout; /* in milliseconds, 0 means no timeout */
long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */
long server_response_timeout; /* in milliseconds, 0 means no timeout */
+ long maxage_conn; /* in seconds, max idle time to allow a connection that
+ is to be reused */
long tftp_blksize; /* in bytes, 0 means use default */
curl_off_t filesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
@@ -1610,7 +1617,11 @@ struct UserDefined {
long ipver; /* the CURL_IPRESOLVE_* defines in the public header file
0 - whatever, 1 - v2, 2 - v6 */
curl_off_t max_filesize; /* Maximum file size to download */
+#ifndef CURL_DISABLE_FTP
curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */
+ curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
+ curl_ftpccc ftp_ccc; /* FTP CCC options */
+#endif
int ftp_create_missing_dirs; /* 1 - create directories that don't exist
2 - the same but also allow MKD to fail once
*/
@@ -1620,8 +1631,6 @@ struct UserDefined {
use_netrc; /* defined in include/gnurl.h */
curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
IMAP or POP3 or others! */
- curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
- curl_ftpccc ftp_ccc; /* FTP CCC options */
long new_file_perms; /* Permissions to use when creating remote files */
long new_directory_perms; /* Permissions to use when creating remote dirs */
long ssh_auth_types; /* allowed SSH auth types */
@@ -1682,7 +1691,14 @@ struct UserDefined {
bit prefer_ascii:1; /* ASCII rather than binary */
bit ftp_append:1; /* append, not overwrite, on upload */
bit ftp_list_only:1; /* switch FTP command for listing directories */
+#ifndef CURL_DISABLE_FTP
bit ftp_use_port:1; /* use the FTP PORT command */
+ bit ftp_use_epsv:1; /* if EPSV is to be attempted or not */
+ bit ftp_use_eprt:1; /* if EPRT is to be attempted or not */
+ bit ftp_use_pret:1; /* if PRET is to be used before PASV or not */
+ bit ftp_skip_ip:1; /* skip the IP address the FTP server passes on to
+ us */
+#endif
bit hide_progress:1; /* don't use the progress meter */
bit http_fail_on_error:1; /* fail on HTTP error codes >= 400 */
bit http_keep_sending_on_error:1; /* for HTTP status codes >= 300 */
@@ -1700,16 +1716,10 @@ struct UserDefined {
bit krb:1; /* Kerberos connection requested */
bit reuse_forbid:1; /* forbidden to be reused, close after use */
bit reuse_fresh:1; /* do not re-use an existing connection */
- bit ftp_use_epsv:1; /* if EPSV is to be attempted or not */
- bit ftp_use_eprt:1; /* if EPRT is to be attempted or not */
- bit ftp_use_pret:1; /* if PRET is to be used before PASV or not */
bit no_signal:1; /* do not use any signal/alarm handler */
- bit global_dns_cache:1; /* subject for future removal */
bit tcp_nodelay:1; /* whether to enable TCP_NODELAY or not */
bit ignorecl:1; /* ignore content length */
- bit ftp_skip_ip:1; /* skip the IP address the FTP server passes on to
- us */
bit connect_only:1; /* make connection, let application use the socket */
bit http_te_skip:1; /* pass the raw body data to the user, even when
transfer-encoded (chunked, compressed) */
@@ -1727,8 +1737,8 @@ struct UserDefined {
bit ssl_enable_npn:1; /* TLS NPN extension? */
bit ssl_enable_alpn:1;/* TLS ALPN extension? */
bit path_as_is:1; /* allow dotdots? */
- bit pipewait:1; /* wait for pipe/multiplex status before starting a
- new connection */
+ bit pipewait:1; /* wait for multiplex status before starting a new
+ connection */
bit suppress_connect_headers:1; /* suppress proxy CONNECT response headers
from user callbacks */
bit dns_shuffle_addresses:1; /* whether to shuffle addresses before use */
@@ -1746,7 +1756,6 @@ struct Names {
struct curl_hash *hostcache;
enum {
HCACHE_NONE, /* not pointing to anything */
- HCACHE_GLOBAL, /* points to the (shrug) global one */
HCACHE_MULTI, /* points to a shared one in the multi handle */
HCACHE_SHARED /* points to a shared one in a shared object */
} hostcachetype;
@@ -1769,8 +1778,8 @@ struct Curl_easy {
struct connectdata *conn;
struct curl_llist_element connect_queue;
- struct curl_llist_element pipeline_queue;
struct curl_llist_element sh_queue; /* list per Curl_sh_entry */
+ struct curl_llist_element conn_queue; /* list per connectdata */
CURLMstate mstate; /* the handle's state */
CURLcode result; /* previous result */
@@ -1810,7 +1819,9 @@ struct Curl_easy {
struct Progress progress; /* for all the progress meter data */
struct UrlState state; /* struct for fields used for state info and
other dynamic purposes */
+#ifndef CURL_DISABLE_FTP
struct WildcardData wildcard; /* wildcard download state info */
+#endif
struct PureInfo info; /* stats, reports and info data */
struct curl_tlssessioninfo tsi; /* Information about the TLS session, only
valid after a client has asked for it */
diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c
index 27acbfec9..d17ceaed3 100644
--- a/lib/vauth/cleartext.c
+++ b/lib/vauth/cleartext.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
@@ -25,6 +25,9 @@
#include "curl_setup.h"
+#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_POP3)
+
#include <gnurl/curl.h>
#include "urldata.h"
@@ -49,8 +52,9 @@
* Parameters:
*
* data [in] - The session handle.
- * userp [in] - The user name.
- * passwdp [in] - The user's password.
+ * authzid [in] - The authorization identity.
+ * authcid [in] - The authentication identity.
+ * passwd [in] - The password.
* outptr [in/out] - The address where a pointer to newly allocated memory
* holding the result will be stored upon completion.
* outlen [out] - The length of the output message.
@@ -58,36 +62,40 @@
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
- const char *userp,
- const char *passwdp,
+ const char *authzid,
+ const char *authcid,
+ const char *passwd,
char **outptr, size_t *outlen)
{
CURLcode result;
char *plainauth;
- size_t ulen;
+ size_t zlen;
+ size_t clen;
size_t plen;
size_t plainlen;
*outlen = 0;
*outptr = NULL;
- ulen = strlen(userp);
- plen = strlen(passwdp);
+ zlen = (authzid == NULL ? 0 : strlen(authzid));
+ clen = strlen(authcid);
+ plen = strlen(passwd);
/* Compute binary message length. Check for overflows. */
- if((ulen > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2)))
+ if(((zlen + clen) > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2)))
return CURLE_OUT_OF_MEMORY;
- plainlen = 2 * ulen + plen + 2;
+ plainlen = zlen + clen + plen + 2;
plainauth = malloc(plainlen);
if(!plainauth)
return CURLE_OUT_OF_MEMORY;
/* Calculate the reply */
- memcpy(plainauth, userp, ulen);
- plainauth[ulen] = '\0';
- memcpy(plainauth + ulen + 1, userp, ulen);
- plainauth[2 * ulen + 1] = '\0';
- memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
+ if(zlen != 0)
+ memcpy(plainauth, authzid, zlen);
+ plainauth[zlen] = '\0';
+ memcpy(plainauth + zlen + 1, authcid, clen);
+ plainauth[zlen + clen + 1] = '\0';
+ memcpy(plainauth + zlen + clen + 2, passwd, plen);
/* Base64 encode the reply */
result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen);
@@ -157,3 +165,5 @@ CURLcode Curl_auth_create_external_message(struct Curl_easy *data,
/* This is the same formatting as the login message */
return Curl_auth_create_login_message(data, user, outptr, outlen);
}
+
+#endif /* if no users */
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index 24de4677b..b790e5678 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.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
@@ -785,8 +785,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
return CURLE_OUT_OF_MEMORY;
if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
- /* We don't support auth-int for PUT or POST at the moment.
- TODO: replace hash of empty string with entity-body for PUT/POST */
+ /* We don't support auth-int for PUT or POST */
char hashed[65];
unsigned char *hashthis2;
diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c
index 0ffbe5f96..1e4c16f98 100644
--- a/lib/vauth/krb5_gssapi.c
+++ b/lib/vauth/krb5_gssapi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2017, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
@@ -372,7 +372,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
}
/*
- * Curl_auth_gssapi_cleanup()
+ * Curl_auth_cleanup_gssapi()
*
* This is used to clean up the GSSAPI (Kerberos V5) specific data.
*
@@ -381,7 +381,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
* krb5 [in/out] - The Kerberos 5 data struct being cleaned up.
*
*/
-void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5)
+void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5)
{
OM_uint32 minor_status;
diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c
index 8dad8b3bc..097914e82 100644
--- a/lib/vauth/krb5_sspi.c
+++ b/lib/vauth/krb5_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2017, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -474,7 +474,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
}
/*
- * Curl_auth_gssapi_cleanup()
+ * Curl_auth_cleanup_gssapi()
*
* This is used to clean up the GSSAPI (Kerberos V5) specific data.
*
@@ -483,7 +483,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
* krb5 [in/out] - The Kerberos 5 data struct being cleaned up.
*
*/
-void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5)
+void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5)
{
/* Free our security context */
if(krb5->context) {
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index 6a8fc5ab3..047c2b5a3 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -403,7 +403,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
(void)hostname,
/* Clean up any former leftovers and initialise to defaults */
- Curl_auth_ntlm_cleanup(ntlm);
+ Curl_auth_cleanup_ntlm(ntlm);
#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
@@ -844,22 +844,22 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
/* Return with binary blob encoded into base64 */
result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen);
- Curl_auth_ntlm_cleanup(ntlm);
+ Curl_auth_cleanup_ntlm(ntlm);
return result;
}
/*
-* Curl_auth_ntlm_cleanup()
-*
-* This is used to clean up the NTLM specific data.
-*
-* Parameters:
-*
-* ntlm [in/out] - The NTLM data struct being cleaned up.
-*
-*/
-void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm)
+ * Curl_auth_cleanup_ntlm()
+ *
+ * This is used to clean up the NTLM specific data.
+ *
+ * Parameters:
+ *
+ * ntlm [in/out] - The NTLM data struct being cleaned up.
+ *
+ */
+void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm)
{
/* Free the target info */
Curl_safefree(ntlm->target_info);
diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c
index 177327b7a..feebdb0e3 100644
--- a/lib/vauth/ntlm_sspi.c
+++ b/lib/vauth/ntlm_sspi.c
@@ -95,7 +95,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
/* Clean up any former leftovers and initialise to defaults */
- Curl_auth_ntlm_cleanup(ntlm);
+ Curl_auth_cleanup_ntlm(ntlm);
/* Query the security package for NTLM */
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
@@ -323,13 +323,13 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
result = Curl_base64_encode(data, (char *) ntlm->output_token,
type_3_buf.cbBuffer, outptr, outlen);
- Curl_auth_ntlm_cleanup(ntlm);
+ Curl_auth_cleanup_ntlm(ntlm);
return result;
}
/*
- * Curl_auth_ntlm_cleanup()
+ * Curl_auth_cleanup_ntlm()
*
* This is used to clean up the NTLM specific data.
*
@@ -338,7 +338,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
* ntlm [in/out] - The NTLM data struct being cleaned up.
*
*/
-void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm)
+void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm)
{
/* Free our security context */
if(ntlm->context) {
diff --git a/lib/vauth/oauth2.c b/lib/vauth/oauth2.c
index 28f64e105..6db148b62 100644
--- a/lib/vauth/oauth2.c
+++ b/lib/vauth/oauth2.c
@@ -5,7 +5,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
@@ -24,6 +24,9 @@
#include "curl_setup.h"
+#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_POP3)
+
#include <gnurl/curl.h>
#include "urldata.h"
@@ -46,8 +49,8 @@
*
* data[in] - The session handle.
* user[in] - The user name.
- * host[in] - The host name(for OAUTHBEARER).
- * port[in] - The port(for OAUTHBEARER when not Port 80).
+ * host[in] - The host name.
+ * port[in] - The port(when not Port 80).
* bearer[in] - The bearer token.
* outptr[in / out] - The address where a pointer to newly allocated memory
* holding the result will be stored upon completion.
@@ -66,13 +69,11 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
char *oauth = NULL;
/* Generate the message */
- if(host == NULL && (port == 0 || port == 80))
- oauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
- else if(port == 0 || port == 80)
- oauth = aprintf("user=%s\1host=%s\1auth=Bearer %s\1\1", user, host,
+ if(port == 0 || port == 80)
+ oauth = aprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host,
bearer);
else
- oauth = aprintf("user=%s\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user,
+ oauth = aprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user,
host, port, bearer);
if(!oauth)
return CURLE_OUT_OF_MEMORY;
@@ -84,3 +85,42 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
return result;
}
+
+/*
+ * Curl_auth_create_xoauth_bearer_message()
+ *
+ * This is used to generate an already encoded XOAuth 2.0 message ready for
+ * sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data[in] - The session handle.
+ * user[in] - The user name.
+ * bearer[in] - The bearer token.
+ * outptr[in / out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen[out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data,
+ const char *user,
+ const char *bearer,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Generate the message */
+ char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
+ if(!xoauth)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Base64 encode the reply */
+ result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
+
+ free(xoauth);
+
+ return result;
+}
+#endif /* disabled, no users */
+
diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c
index 7d2b9ac31..9c3faa4a9 100644
--- a/lib/vauth/spnego_gssapi.c
+++ b/lib/vauth/spnego_gssapi.c
@@ -97,7 +97,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
/* We finished successfully our part of authentication, but server
* rejected it (since we're again here). Exit with an error since we
* can't invent anything better */
- Curl_auth_spnego_cleanup(nego);
+ Curl_auth_cleanup_spnego(nego);
return CURLE_LOGIN_DENIED;
}
@@ -170,7 +170,7 @@ 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_OUT_OF_MEMORY;
+ return CURLE_LOGIN_DENIED;
}
if(!output_token.value || !output_token.length) {
@@ -238,7 +238,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
}
/*
- * Curl_auth_spnego_cleanup()
+ * Curl_auth_cleanup_spnego()
*
* This is used to clean up the SPNEGO (Negotiate) specific data.
*
@@ -247,7 +247,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
* nego [in/out] - The Negotiate data struct being cleaned up.
*
*/
-void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
+void Curl_auth_cleanup_spnego(struct negotiatedata *nego)
{
OM_uint32 minor_status;
@@ -273,7 +273,6 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
/* Reset any variables */
nego->status = 0;
- nego->state = GSS_AUTHNONE;
nego->noauthpersist = FALSE;
nego->havenoauthpersist = FALSE;
nego->havenegdata = FALSE;
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index ddd983cf2..735988480 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -107,7 +107,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
/* We finished successfully our part of authentication, but server
* rejected it (since we're again here). Exit with an error since we
* can't invent anything better */
- Curl_auth_spnego_cleanup(nego);
+ Curl_auth_cleanup_spnego(nego);
return CURLE_LOGIN_DENIED;
}
@@ -307,7 +307,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
}
/*
- * Curl_auth_spnego_cleanup()
+ * Curl_auth_cleanup_spnego()
*
* This is used to clean up the SPNEGO (Negotiate) specific data.
*
@@ -316,7 +316,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
* nego [in/out] - The Negotiate data struct being cleaned up.
*
*/
-void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
+void Curl_auth_cleanup_spnego(struct negotiatedata *nego)
{
/* Free our security context */
if(nego->context) {
@@ -343,7 +343,6 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
/* Reset any variables */
nego->status = 0;
nego->token_max = 0;
- nego->state = GSS_AUTHNONE;
nego->noauthpersist = FALSE;
nego->havenoauthpersist = FALSE;
nego->havenegdata = FALSE;
diff --git a/lib/vauth/vauth.c b/lib/vauth/vauth.c
index 612b7c3e8..54b34861b 100644
--- a/lib/vauth/vauth.c
+++ b/lib/vauth/vauth.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -105,26 +105,26 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
#endif /* USE_WINDOWS_SSPI */
/*
-* Curl_auth_user_contains_domain()
-*
-* This is used to test if the specified user contains a Windows domain name as
-* follows:
-*
-* User\Domain (Down-level Logon Name)
-* User/Domain (curl Down-level format - for compatibility with existing code)
-* User@Domain (User Principal Name)
-*
-* Note: The user name may be empty when using a GSS-API library or Windows SSPI
-* as the user and domain are either obtained from the credentials cache when
-* using GSS-API or via the currently logged in user's credentials when using
-* Windows SSPI.
-*
-* Parameters:
-*
-* user [in] - The user name.
-*
-* Returns TRUE on success; otherwise FALSE.
-*/
+ * Curl_auth_user_contains_domain()
+ *
+ * This is used to test if the specified user contains a Windows domain name as
+ * follows:
+ *
+ * Domain\User (Down-level Logon Name)
+ * Domain/User (curl Down-level format - for compatibility with existing code)
+ * User@Domain (User Principal Name)
+ *
+ * Note: The user name may be empty when using a GSS-API library or Windows
+ * SSPI as the user and domain are either obtained from the credentials cache
+ * when using GSS-API or via the currently logged in user's credentials when
+ * using Windows SSPI.
+ *
+ * Parameters:
+ *
+ * user [in] - The user name.
+ *
+ * Returns TRUE on success; otherwise FALSE.
+ */
bool Curl_auth_user_contains_domain(const char *user)
{
bool valid = FALSE;
diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h
index d0ca53ad9..8838d9ee4 100644
--- a/lib/vauth/vauth.h
+++ b/lib/vauth/vauth.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2017, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -60,8 +60,9 @@ bool Curl_auth_user_contains_domain(const char *user);
/* This is used to generate a base64 encoded PLAIN cleartext message */
CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
- const char *userp,
- const char *passwdp,
+ const char *authzid,
+ const char *authcid,
+ const char *passwd,
char **outptr, size_t *outlen);
/* This is used to generate a base64 encoded LOGIN cleartext message */
@@ -141,7 +142,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
char **outptr, size_t *outlen);
/* This is used to clean up the NTLM specific data */
-void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm);
+void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm);
#endif /* USE_NTLM */
/* This is used to generate a base64 encoded OAuth 2.0 message */
@@ -151,6 +152,13 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
const long port,
const char *bearer,
char **outptr, size_t *outlen);
+
+/* This is used to generate a base64 encoded XOAuth 2.0 message */
+CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data,
+ const char *user,
+ const char *bearer,
+ char **outptr, size_t *outlen);
+
#if defined(USE_KERBEROS5)
/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */
bool Curl_auth_is_gssapi_supported(void);
@@ -176,7 +184,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
size_t *outlen);
/* This is used to clean up the GSSAPI specific data */
-void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5);
+void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5);
#endif /* USE_KERBEROS5 */
#if defined(USE_SPNEGO)
@@ -200,7 +208,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
char **outptr, size_t *outlen);
/* This is used to clean up the SPNEGO specifiec data */
-void Curl_auth_spnego_cleanup(struct negotiatedata *nego);
+void Curl_auth_cleanup_spnego(struct negotiatedata *nego);
#endif /* USE_SPNEGO */
diff --git a/lib/version.c b/lib/version.c
index 020b2b018..d938730a1 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -31,7 +31,7 @@
#ifdef USE_ARES
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
- (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+ (defined(WIN32) || defined(__SYMBIAN32__))
# define CARES_STATICLIB
# endif
# include <ares.h>
@@ -274,7 +274,7 @@ static const char * const protocols[] = {
#ifndef CURL_DISABLE_RTSP
"rtsp",
#endif
-#if defined(USE_LIBSSH) || defined(USE_LIBSSH2)
+#if defined(USE_SSH)
"scp",
"sftp",
#endif
@@ -390,12 +390,16 @@ static curl_version_info_data version_info = {
curl_version_info_data *curl_version_info(CURLversion stamp)
{
static bool initialized;
-#if defined(USE_LIBSSH) || defined(USE_LIBSSH2)
+#if defined(USE_SSH)
static char ssh_buffer[80];
#endif
#ifdef USE_SSL
+#ifdef CURL_WITH_MULTI_SSL
+ static char ssl_buffer[200];
+#else
static char ssl_buffer[80];
#endif
+#endif
#ifdef HAVE_BROTLI
static char brotli_buffer[80];
#endif
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index c7a3268ef..44a2bdda6 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -79,6 +79,7 @@ and that's a problem since options.h hasn't been included yet. */
#include "strcase.h"
#include "x509asn1.h"
#include "curl_printf.h"
+#include "multiif.h"
#include <cyassl/openssl/ssl.h>
#include <cyassl/ssl.h>
@@ -142,7 +143,6 @@ static CURLcode
cyassl_connect_step1(struct connectdata *conn,
int sockindex)
{
- char error_buffer[CYASSL_MAX_ERROR_SZ];
char *ciphers;
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
@@ -419,6 +419,7 @@ cyassl_connect_step1(struct connectdata *conn,
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
/* we got a session id, use it! */
if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+ char error_buffer[CYASSL_MAX_ERROR_SZ];
Curl_ssl_sessionid_unlock(conn);
failf(data, "SSL: SSL_set_session failed: %s",
ERR_error_string(SSL_get_error(BACKEND->handle, 0),
@@ -599,6 +600,8 @@ cyassl_connect_step2(struct connectdata *conn,
else
infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
protocol);
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else if(rc == SSL_ALPN_NOT_FOUND)
infof(data, "ALPN, server did not agree to a protocol\n");
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index 519fbfb02..40cd9e1de 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -734,12 +734,11 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
{
struct ssl_connect_data *connssl = &conn->ssl[num];
struct Curl_easy *data = conn->data;
- int buffsize;
int nread;
CURLcode cc = CURLE_RECV_ERROR;
if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
- buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
+ int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
buf, buffsize, &nread),
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
@@ -806,7 +805,6 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
conn->host.name;
const char *sni;
unsigned int protoflags = 0;
- long timeout;
Qso_OverlappedIO_t commarea;
int sockpair[2];
static const int sobufsize = CURL_MAX_WRITE_SIZE;
@@ -914,7 +912,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
if(!result) {
/* Compute the handshake timeout. Since GSKit granularity is 1 second,
we round up the required value. */
- timeout = Curl_timeleft(data, NULL, TRUE);
+ long timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0)
result = CURLE_OPERATION_TIMEDOUT;
else
@@ -1021,14 +1019,13 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
- long timeout_ms;
struct timeval stmv;
CURLcode result;
/* Poll or wait for end of SSL asynchronous handshake. */
for(;;) {
- timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+ long timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0)
timeout_ms = 0;
stmv.tv_sec = timeout_ms / 1000;
@@ -1077,7 +1074,6 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
const char *cert = (const char *) NULL;
const char *certend;
const char *ptr;
- int i;
CURLcode result;
/* SSL handshake done: gather certificate info and verify host. */
@@ -1087,6 +1083,8 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
&cdev, &cdec),
"gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
CURLE_OK) {
+ int i;
+
infof(data, "Server certificate:\n");
p = cdev;
for(i = 0; i++ < cdec; p++)
@@ -1160,7 +1158,6 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
long timeout_ms;
- Qso_OverlappedIO_t cstat;
CURLcode result = CURLE_OK;
*done = connssl->state == ssl_connection_complete;
@@ -1262,7 +1259,6 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
- ssize_t nread;
int what;
int rc;
char buf[120];
@@ -1270,8 +1266,10 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
if(!BACKEND->handle)
return 0;
+#ifndef CURL_DISABLE_FTP
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
+#endif
close_one(connssl, conn, sockindex);
rc = 0;
@@ -1279,6 +1277,8 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
SSL_SHUTDOWN_TIMEOUT);
for(;;) {
+ ssize_t nread;
+
if(what < 0) {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index e224861c4..8693cdce3 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -55,6 +55,7 @@
#include "strcase.h"
#include "warnless.h"
#include "x509asn1.h"
+#include "multiif.h"
#include "curl_printf.h"
#include "curl_memory.h"
/* The last #include file should be: */
@@ -285,11 +286,11 @@ static CURLcode handshake(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
gnutls_session_t session = BACKEND->session;
curl_socket_t sockfd = conn->sock[sockindex];
- time_t timeout_ms;
- int rc;
- int what;
for(;;) {
+ time_t timeout_ms;
+ int rc;
+
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, duringconnect);
@@ -302,7 +303,7 @@ static CURLcode handshake(struct connectdata *conn,
/* if ssl is expecting something, check if it's available. */
if(connssl->connecting_state == ssl_connect_2_reading
|| connssl->connecting_state == ssl_connect_2_writing) {
-
+ int what;
curl_socket_t writefd = ssl_connect_2_writing ==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
curl_socket_t readfd = ssl_connect_2_reading ==
@@ -956,7 +957,6 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
gnutls_pubkey_t key = NULL;
/* Result is returned to caller */
- int ret = 0;
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
/* if a path wasn't specified, don't pin */
@@ -967,6 +967,8 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
return result;
do {
+ int ret;
+
/* Begin Gyrations to get the public key */
gnutls_pubkey_init(&key);
@@ -1278,10 +1280,7 @@ gtls_connect_step3(struct connectdata *conn,
#define use_addr in_addr
#endif
unsigned char addrbuf[sizeof(struct use_addr)];
- unsigned char certaddr[sizeof(struct use_addr)];
- size_t addrlen = 0, certaddrlen;
- int i;
- int ret = 0;
+ size_t addrlen = 0;
if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0)
addrlen = 4;
@@ -1291,10 +1290,13 @@ gtls_connect_step3(struct connectdata *conn,
#endif
if(addrlen) {
+ unsigned char certaddr[sizeof(struct use_addr)];
+ int i;
+
for(i = 0; ; i++) {
- certaddrlen = sizeof(certaddr);
- ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
- &certaddrlen, NULL);
+ size_t certaddrlen = sizeof(certaddr);
+ int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
+ &certaddrlen, NULL);
/* If this happens, it wasn't an IP address. */
if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
continue;
@@ -1449,6 +1451,9 @@ gtls_connect_step3(struct connectdata *conn,
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
+
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -1461,8 +1466,6 @@ gtls_connect_step3(struct connectdata *conn,
already got it from the cache and asked to use it in the connection, it
might've been rejected and then a new one is in use now and we need to
detect that. */
- bool incache;
- void *ssl_sessionid;
void *connect_sessionid;
size_t connect_idsize = 0;
@@ -1471,6 +1474,9 @@ gtls_connect_step3(struct connectdata *conn,
connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
if(connect_sessionid) {
+ bool incache;
+ void *ssl_sessionid;
+
/* extract session ID to the allocated buffer */
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
@@ -1631,12 +1637,10 @@ static void Curl_gtls_close(struct connectdata *conn, int sockindex)
static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- ssize_t result;
int retval = 0;
struct Curl_easy *data = conn->data;
- bool done = FALSE;
- char buf[120];
+#ifndef CURL_DISABLE_FTP
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
response. Thus we wait for a close notify alert from the server, but
@@ -1644,8 +1648,13 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
+#endif
if(BACKEND->session) {
+ ssize_t result;
+ bool done = FALSE;
+ char buf[120];
+
while(!done) {
int what = SOCKET_READABLE(conn->sock[sockindex],
SSL_SHUTDOWN_TIMEOUT);
@@ -1758,12 +1767,6 @@ static int Curl_gtls_seed(struct Curl_easy *data)
if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
data->set.str[STRING_SSL_EGDSOCKET]) {
-
- /* TODO: to a good job seeding the RNG
- This may involve the gcry_control function and these options:
- GCRYCTL_SET_RANDOM_SEED_FILE
- GCRYCTL_SET_RNDEGD_SOCKET
- */
ssl_seeded = TRUE;
}
return 0;
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index 27a9402cb..63d1f4c81 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -54,6 +54,7 @@
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
+#include "multiif.h"
#include "polarssl_threadlock.h"
/* The last 3 #include files should be in this order */
@@ -342,7 +343,8 @@ mbed_connect_step1(struct connectdata *conn,
if(SSL_SET_OPTION(key)) {
ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key),
SSL_SET_OPTION(key_passwd));
- if(ret == 0 && !mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA))
+ if(ret == 0 && !(mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA) ||
+ mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_ECKEY)))
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
if(ret) {
@@ -539,13 +541,6 @@ mbed_connect_step2(struct connectdata *conn,
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-#ifdef HAS_ALPN
- const char *next_protocol;
-#endif
-
- char errorbuf[128];
- errorbuf[0] = 0;
-
conn->recv[sockindex] = mbed_recv;
conn->send[sockindex] = mbed_send;
@@ -560,6 +555,8 @@ mbed_connect_step2(struct connectdata *conn,
return CURLE_OK;
}
else if(ret) {
+ char errorbuf[128];
+ errorbuf[0] = 0;
#ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
@@ -664,7 +661,7 @@ mbed_connect_step2(struct connectdata *conn,
#ifdef HAS_ALPN
if(conn->bits.tls_enable_alpn) {
- next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl);
+ const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl);
if(next_protocol) {
infof(data, "ALPN, server accepted to use %s\n", next_protocol);
@@ -684,6 +681,8 @@ mbed_connect_step2(struct connectdata *conn,
else {
infof(data, "ALPN, server did not agree to a protocol\n");
}
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c
index db1411559..718c282ee 100644
--- a/lib/vtls/mesalink.c
+++ b/lib/vtls/mesalink.c
@@ -268,7 +268,7 @@ mesalink_connect_step2(struct connectdata *conn, int sockindex)
char error_buffer[MESALINK_MAX_ERROR_SZ];
int detail = SSL_get_error(BACKEND->handle, ret);
- if(SSL_ERROR_WANT_CONNECT == detail) {
+ if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) {
connssl->connecting_state = ssl_connect_2_reading;
return CURLE_OK;
}
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 08ee1aaaf..491def106 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.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
@@ -38,6 +38,7 @@
#include "select.h"
#include "vtls.h"
#include "llist.h"
+#include "multiif.h"
#include "curl_printf.h"
#include "nssg.h"
#include <nspr.h>
@@ -377,7 +378,7 @@ static int is_file(const char *filename)
return 0;
if(stat(filename, &st) == 0)
- if(S_ISREG(st.st_mode))
+ if(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISCHR(st.st_mode))
return 1;
return 0;
@@ -843,6 +844,8 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
!memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
conn->negnpn = CURL_HTTP_VERSION_1_1;
}
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
}
@@ -1305,6 +1308,8 @@ static void nss_unload_module(SECMODModule **pmod)
static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
{
NSSInitParameters initparams;
+ PRErrorCode err;
+ const char *err_name;
if(nss_context != NULL)
return CURLE_OK;
@@ -1325,7 +1330,9 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
if(nss_context != NULL)
return CURLE_OK;
- infof(data, "Unable to initialize NSS database\n");
+ err = PR_GetError();
+ err_name = nss_error_to_name(err);
+ infof(data, "Unable to initialize NSS database: %d (%s)\n", err, err_name);
}
infof(data, "Initializing NSS with certpath: none\n");
@@ -1335,7 +1342,9 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
if(nss_context != NULL)
return CURLE_OK;
- infof(data, "Unable to initialize NSS\n");
+ err = PR_GetError();
+ err_name = nss_error_to_name(err);
+ failf(data, "Unable to initialize NSS: %d (%s)", err, err_name);
return CURLE_SSL_CACERT_BADFILE;
}
@@ -1822,7 +1831,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
/* list of all NSS objects we need to destroy in Curl_nss_close() */
Curl_llist_init(&BACKEND->obj_list, nss_destroy_object);
- /* FIXME. NSS doesn't support multiple databases open at the same time. */
PR_Lock(nss_initlock);
result = nss_init(conn->data);
if(result) {
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index eff5c2106..85e9be616 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -48,6 +48,7 @@
#include "vtls.h"
#include "strcase.h"
#include "hostcheck.h"
+#include "multiif.h"
#include "curl_printf.h"
#include <openssl/ssl.h>
#include <openssl/rand.h>
@@ -1307,6 +1308,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
int err;
bool done = FALSE;
+#ifndef CURL_DISABLE_FTP
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
response. Thus we wait for a close notify alert from the server, but
@@ -1314,6 +1316,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
(void)SSL_shutdown(BACKEND->handle);
+#endif
if(BACKEND->handle) {
buffsize = (int)sizeof(buf);
@@ -2917,6 +2920,9 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
+
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -3223,11 +3229,6 @@ static CURLcode get_cert_chain(struct connectdata *conn,
#endif
break;
}
-#if 0
- case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
- /* left TODO */
- break;
-#endif
}
EVP_PKEY_free(pubkey);
}
@@ -3756,7 +3757,10 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
switch(err) {
case SSL_ERROR_NONE: /* this is not an error */
+ break;
case SSL_ERROR_ZERO_RETURN: /* no more data */
+ /* close_notify alert */
+ connclose(conn, "TLS close_notify");
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
@@ -3819,7 +3823,11 @@ static size_t Curl_ossl_version(char *buffer, size_t size)
sub[0]='\0';
}
- return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s",
+ return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s"
+#ifdef OPENSSL_FIPS
+ "-fips"
+#endif
+ ,
OSSL_PACKAGE,
(ssleay_value>>28)&0xf,
(ssleay_value>>20)&0xff,
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index 6ecabe94b..7ea26b442 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -55,6 +55,7 @@
#include "select.h"
#include "strcase.h"
#include "polarssl_threadlock.h"
+#include "multiif.h"
#include "curl_printf.h"
#include "curl_memory.h"
/* The last #include file should be: */
@@ -593,6 +594,8 @@ polarssl_connect_step2(struct connectdata *conn,
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -908,9 +911,7 @@ const struct Curl_ssl Curl_ssl_polarssl = {
Curl_none_check_cxn, /* check_cxn */
Curl_none_shutdown, /* shutdown */
Curl_polarssl_data_pending, /* data_pending */
- /* This might cause libcurl to use a weeker random!
- * TODO: use Polarssl's CTR-DRBG or HMAC-DRBG
- */
+ /* This might cause libcurl to use a weeker random! */
Curl_none_random, /* random */
Curl_none_cert_status_request, /* cert_status_request */
Curl_polarssl_connect, /* connect */
diff --git a/lib/vtls/polarssl_threadlock.c b/lib/vtls/polarssl_threadlock.c
index dd5fbd7ec..27c94b11e 100644
--- a/lib/vtls/polarssl_threadlock.c
+++ b/lib/vtls/polarssl_threadlock.c
@@ -23,16 +23,15 @@
#include "curl_setup.h"
#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \
- (defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32))
-
-#if defined(USE_THREADS_POSIX)
-# ifdef HAVE_PTHREAD_H
-# include <pthread.h>
-# endif
-#elif defined(USE_THREADS_WIN32)
-# ifdef HAVE_PROCESS_H
-# include <process.h>
-# endif
+ ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
+ (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)))
+
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+# include <pthread.h>
+# define POLARSSL_MUTEX_T pthread_mutex_t
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+# include <process.h>
+# define POLARSSL_MUTEX_T HANDLE
#endif
#include "polarssl_threadlock.h"
@@ -50,25 +49,23 @@ static POLARSSL_MUTEX_T *mutex_buf = NULL;
int Curl_polarsslthreadlock_thread_setup(void)
{
int i;
- int ret;
mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1);
if(!mutex_buf)
return 0; /* error, no number of threads defined */
-#ifdef HAVE_PTHREAD_H
for(i = 0; i < NUMT; i++) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
ret = pthread_mutex_init(&mutex_buf[i], NULL);
if(ret)
return 0; /* pthread_mutex_init failed */
- }
-#elif defined(HAVE_PROCESS_H)
- for(i = 0; i < NUMT; i++) {
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
mutex_buf[i] = CreateMutex(0, FALSE, 0);
if(mutex_buf[i] == 0)
return 0; /* CreateMutex failed */
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
}
-#endif /* HAVE_PTHREAD_H */
return 1; /* OK */
}
@@ -76,24 +73,22 @@ int Curl_polarsslthreadlock_thread_setup(void)
int Curl_polarsslthreadlock_thread_cleanup(void)
{
int i;
- int ret;
if(!mutex_buf)
return 0; /* error, no threads locks defined */
-#ifdef HAVE_PTHREAD_H
for(i = 0; i < NUMT; i++) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
ret = pthread_mutex_destroy(&mutex_buf[i]);
if(ret)
return 0; /* pthread_mutex_destroy failed */
- }
-#elif defined(HAVE_PROCESS_H)
- for(i = 0; i < NUMT; i++) {
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
ret = CloseHandle(mutex_buf[i]);
if(!ret)
return 0; /* CloseHandle failed */
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
}
-#endif /* HAVE_PTHREAD_H */
free(mutex_buf);
mutex_buf = NULL;
@@ -102,51 +97,47 @@ int Curl_polarsslthreadlock_thread_cleanup(void)
int Curl_polarsslthreadlock_lock_function(int n)
{
- int ret;
-#ifdef HAVE_PTHREAD_H
if(n < NUMT) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
ret = pthread_mutex_lock(&mutex_buf[n]);
if(ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_lock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
- }
-#elif defined(HAVE_PROCESS_H)
- if(n < NUMT) {
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
if(ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_lock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
}
-#endif /* HAVE_PTHREAD_H */
return 1; /* OK */
}
int Curl_polarsslthreadlock_unlock_function(int n)
{
- int ret;
-#ifdef HAVE_PTHREAD_H
if(n < NUMT) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
ret = pthread_mutex_unlock(&mutex_buf[n]);
if(ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_unlock_function failed\n"));
return 0; /* pthread_mutex_unlock failed */
}
- }
-#elif defined(HAVE_PROCESS_H)
- if(n < NUMT) {
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
ret = ReleaseMutex(mutex_buf[n]);
if(!ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_unlock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
}
-#endif /* HAVE_PTHREAD_H */
return 1; /* OK */
}
diff --git a/lib/vtls/polarssl_threadlock.h b/lib/vtls/polarssl_threadlock.h
index dda5359b8..122647528 100644
--- a/lib/vtls/polarssl_threadlock.h
+++ b/lib/vtls/polarssl_threadlock.h
@@ -26,13 +26,8 @@
#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
-#if defined(USE_THREADS_POSIX)
-# define POLARSSL_MUTEX_T pthread_mutex_t
-#elif defined(USE_THREADS_WIN32)
-# define POLARSSL_MUTEX_T HANDLE
-#endif
-
-#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
+ (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))
int Curl_polarsslthreadlock_thread_setup(void);
int Curl_polarsslthreadlock_thread_cleanup(void);
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 39ac080e8..0f6f734fd 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -58,6 +58,7 @@
#include "warnless.h"
#include "x509asn1.h"
#include "curl_printf.h"
+#include "multiif.h"
#include "system_win32.h"
/* The last #include file should be: */
@@ -522,7 +523,6 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
#endif
schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
- /* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */
if(data->set.ssl.no_revoke) {
schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
@@ -868,13 +868,11 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
unsigned char *reallocated_buffer;
- size_t reallocated_length;
SecBuffer outbuf[3];
SecBufferDesc outbuf_desc;
SecBuffer inbuf[2];
SecBufferDesc inbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
- TCHAR *host_name;
CURLcode result;
bool doread;
char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
@@ -917,7 +915,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
if(BACKEND->encdata_length - BACKEND->encdata_offset <
CURL_SCHANNEL_BUFFER_FREE_SIZE) {
/* increase internal encrypted data buffer */
- reallocated_length = BACKEND->encdata_offset +
+ size_t reallocated_length = BACKEND->encdata_offset +
CURL_SCHANNEL_BUFFER_FREE_SIZE;
reallocated_buffer = realloc(BACKEND->encdata_buffer,
reallocated_length);
@@ -933,6 +931,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
}
for(;;) {
+ TCHAR *host_name;
if(doread) {
/* read encrypted handshake data from socket */
result = Curl_read_plain(conn->sock[sockindex],
@@ -1269,6 +1268,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -2129,14 +2130,9 @@ static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM,
static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
const char *pinnedpubkey)
{
- SECURITY_STATUS sspi_status;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CERT_CONTEXT *pCertContextServer = NULL;
- const char *x509_der;
- DWORD x509_der_len;
- curl_X509certificate x509_parsed;
- curl_asn1Element *pubkey;
/* Result is returned to caller */
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
@@ -2146,6 +2142,12 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
return CURLE_OK;
do {
+ SECURITY_STATUS sspi_status;
+ const char *x509_der;
+ DWORD x509_der_len;
+ curl_X509certificate x509_parsed;
+ curl_asn1Element *pubkey;
+
sspi_status =
s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c
index 971dd78e6..2fdf662a1 100644
--- a/lib/vtls/sectransp.c
+++ b/lib/vtls/sectransp.c
@@ -31,6 +31,7 @@
#include "urldata.h" /* for the Curl_easy definition */
#include "curl_base64.h"
#include "strtok.h"
+#include "multiif.h"
#ifdef USE_SECTRANSP
@@ -1902,7 +1903,6 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
/* We want to enable 1/n-1 when using a CBC cipher unless the user
specifically doesn't want us doing that: */
if(SSLSetSessionOption != NULL) {
- /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
!data->set.ssl.enable_beast);
SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
@@ -2651,6 +2651,9 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex)
else
infof(data, "ALPN, server did not agree to a protocol\n");
+ Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
+
/* chosenProtocol is a reference to the string within alpnArr
and doesn't need to be freed separately */
if(alpnArr)
@@ -2960,8 +2963,10 @@ static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex)
if(!BACKEND->ssl_ctx)
return 0;
+#ifndef CURL_DISABLE_FTP
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
+#endif
Curl_sectransp_close(conn, sockindex);
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 8a405c05c..a7452dcd5 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -498,9 +498,9 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
void Curl_ssl_close_all(struct Curl_easy *data)
{
- size_t i;
/* kill the session ID cache if not shared */
if(data->state.session && !SSLSESSION_SHARED(data)) {
+ size_t i;
for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++)
/* the single-killer function handles empty table slots */
Curl_ssl_kill_session(&data->state.session[i]);
@@ -644,11 +644,11 @@ bool Curl_ssl_data_pending(const struct connectdata *conn,
void Curl_ssl_free_certinfo(struct Curl_easy *data)
{
- int i;
struct curl_certinfo *ci = &data->info.certs;
if(ci->num_of_certs) {
/* free all individual lists used */
+ int i;
for(i = 0; i<ci->num_of_certs; i++) {
curl_slist_free_all(ci->certinfo[i]);
ci->certinfo[i] = NULL;
@@ -808,14 +808,7 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
{
FILE *fp;
unsigned char *buf = NULL, *pem_ptr = NULL;
- long filesize;
- size_t size, pem_len;
- CURLcode pem_read;
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- CURLcode encode;
- size_t encodedlen, pinkeylen;
- char *encoded, *pinkeycopy, *begin_pos, *end_pos;
- unsigned char *sha256sumdigest = NULL;
/* if a path wasn't specified, don't pin */
if(!pinnedpubkey)
@@ -825,6 +818,11 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
/* only do this if pinnedpubkey starts with "sha256//", length 8 */
if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
+ CURLcode encode;
+ size_t encodedlen, pinkeylen;
+ char *encoded, *pinkeycopy, *begin_pos, *end_pos;
+ unsigned char *sha256sumdigest;
+
if(!Curl_ssl->sha256sum) {
/* without sha256 support, this cannot match */
return result;
@@ -895,6 +893,10 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
return result;
do {
+ long filesize;
+ size_t size, pem_len;
+ CURLcode pem_read;
+
/* Determine the file's size */
if(fseek(fp, 0, SEEK_END))
break;
@@ -1239,16 +1241,17 @@ static size_t Curl_multissl_version(char *buffer, size_t size)
if(current != selected) {
char *p = backends;
+ char *end = backends + sizeof(backends);
int i;
selected = current;
- for(i = 0; available_backends[i]; i++) {
+ for(i = 0; available_backends[i] && p < (end - 4); i++) {
if(i)
*(p++) = ' ';
if(selected != available_backends[i])
*(p++) = '(';
- p += available_backends[i]->version(p, backends + sizeof(backends) - p);
+ p += available_backends[i]->version(p, end - p - 2);
if(selected != available_backends[i])
*(p++) = ')';
}
@@ -1256,21 +1259,20 @@ static size_t Curl_multissl_version(char *buffer, size_t size)
total = p - backends;
}
- if(size < total)
+ if(size > total)
memcpy(buffer, backends, total + 1);
else {
memcpy(buffer, backends, size - 1);
buffer[size - 1] = '\0';
}
- return total;
+ return CURLMIN(size - 1, total);
}
static int multissl_init(const struct Curl_ssl *backend)
{
const char *env;
char *env_tmp;
- int i;
if(Curl_ssl != &Curl_ssl_multi)
return 1;
@@ -1289,6 +1291,7 @@ static int multissl_init(const struct Curl_ssl *backend)
env = CURL_DEFAULT_SSL_BACKEND;
#endif
if(env) {
+ int i;
for(i = 0; available_backends[i]; i++) {
if(strcasecompare(env, available_backends[i]->info.name)) {
Curl_ssl = available_backends[i];
diff --git a/lib/wildcard.c b/lib/wildcard.c
index 8ba0989b4..e94d3c544 100644
--- a/lib/wildcard.c
+++ b/lib/wildcard.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
@@ -22,6 +22,8 @@
#include "curl_setup.h"
+#ifndef CURL_DISABLE_FTP
+
#include "wildcard.h"
#include "llist.h"
#include "fileinfo.h"
@@ -67,3 +69,5 @@ void Curl_wildcard_dtor(struct WildcardData *wc)
wc->customptr = NULL;
wc->state = CURLWC_INIT;
}
+
+#endif /* if disabled */
diff --git a/lib/wildcard.h b/lib/wildcard.h
index 9e7035097..306c8c99f 100644
--- a/lib/wildcard.h
+++ b/lib/wildcard.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 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
@@ -22,8 +22,9 @@
*
***************************************************************************/
-#include <gnurl/curl.h>
+#include "curl_setup.h"
+#ifndef CURL_DISABLE_FTP
#include "llist.h"
/* list of wildcard process states */
@@ -58,4 +59,9 @@ void Curl_wildcard_dtor(struct WildcardData *wc);
struct Curl_easy;
+#else
+/* FTP is disabled */
+#define Curl_wildcard_dtor(x)
+#endif
+
#endif /* HEADER_CURL_WILDCARD_H */
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index ceab1bcf9..1af312ec6 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -266,8 +266,6 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
size_t inlength = end - from;
int size = 1;
size_t outlength;
- int charsize;
- unsigned int wc;
char *buf;
*to = NULL;
@@ -305,6 +303,9 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
}
else {
for(outlength = 0; from < end;) {
+ int charsize;
+ unsigned int wc;
+
wc = 0;
switch(size) {
case 4:
@@ -877,9 +878,6 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
curl_asn1Element elem;
curl_asn1Element pk;
const char *p;
- const char *q;
- unsigned long len;
- unsigned int i;
/* Generate all information records for the public key. */
@@ -888,6 +886,9 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
return;
if(strcasecompare(algo, "rsaEncryption")) {
+ const char *q;
+ unsigned long len;
+
p = getASN1Element(&elem, pk.beg, pk.end);
if(!p)
return;
@@ -896,9 +897,11 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
for(q = elem.beg; !*q && q < elem.end; q++)
;
len = (unsigned long)((elem.end - q) * 8);
- if(len)
+ if(len) {
+ unsigned int i;
for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1)
len--;
+ }
if(len > 32)
elem.beg = q; /* Strip leading zero bytes. */
if(!certnum)
@@ -1056,8 +1059,6 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
free((char *) ccp);
-/* TODO: extensions. */
-
/* Signature. */
ccp = ASN1tostr(&cert.signature, 0);
if(!ccp)