Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Utilities / cmcurl / lib / url.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24
25 #include "curl_setup.h"
26
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
29 #endif
30 #ifdef HAVE_NETDB_H
31 #include <netdb.h>
32 #endif
33 #ifdef HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
36 #ifdef HAVE_NET_IF_H
37 #include <net/if.h>
38 #endif
39 #ifdef HAVE_IPHLPAPI_H
40 #include <Iphlpapi.h>
41 #endif
42 #ifdef HAVE_SYS_IOCTL_H
43 #include <sys/ioctl.h>
44 #endif
45 #ifdef HAVE_SYS_PARAM_H
46 #include <sys/param.h>
47 #endif
48
49 #ifdef __VMS
50 #include <in.h>
51 #include <inet.h>
52 #endif
53
54 #ifdef HAVE_SYS_UN_H
55 #include <sys/un.h>
56 #endif
57
58 #ifndef HAVE_SOCKET
59 #error "We can't compile without socket() support!"
60 #endif
61
62 #include <limits.h>
63
64 #ifdef USE_LIBIDN2
65 #include <idn2.h>
66
67 #if defined(WIN32) && defined(UNICODE)
68 #define IDN2_LOOKUP(name, host, flags) \
69   idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags)
70 #else
71 #define IDN2_LOOKUP(name, host, flags) \
72   idn2_lookup_ul((const char *)name, (char **)host, flags)
73 #endif
74
75 #elif defined(USE_WIN32_IDN)
76 /* prototype for Curl_win32_idn_to_ascii() */
77 bool Curl_win32_idn_to_ascii(const char *in, char **out);
78 #endif  /* USE_LIBIDN2 */
79
80 #include "doh.h"
81 #include "urldata.h"
82 #include "netrc.h"
83
84 #include "formdata.h"
85 #include "mime.h"
86 #include "vtls/vtls.h"
87 #include "hostip.h"
88 #include "transfer.h"
89 #include "sendf.h"
90 #include "progress.h"
91 #include "cookie.h"
92 #include "strcase.h"
93 #include "strerror.h"
94 #include "escape.h"
95 #include "strtok.h"
96 #include "share.h"
97 #include "content_encoding.h"
98 #include "http_digest.h"
99 #include "http_negotiate.h"
100 #include "select.h"
101 #include "multiif.h"
102 #include "easyif.h"
103 #include "speedcheck.h"
104 #include "warnless.h"
105 #include "getinfo.h"
106 #include "urlapi-int.h"
107 #include "system_win32.h"
108 #include "hsts.h"
109 #include "noproxy.h"
110
111 /* And now for the protocols */
112 #include "ftp.h"
113 #include "dict.h"
114 #include "telnet.h"
115 #include "tftp.h"
116 #include "http.h"
117 #include "http2.h"
118 #include "file.h"
119 #include "curl_ldap.h"
120 #include "vssh/ssh.h"
121 #include "imap.h"
122 #include "url.h"
123 #include "connect.h"
124 #include "inet_ntop.h"
125 #include "http_ntlm.h"
126 #include "curl_rtmp.h"
127 #include "gopher.h"
128 #include "mqtt.h"
129 #include "http_proxy.h"
130 #include "conncache.h"
131 #include "multihandle.h"
132 #include "strdup.h"
133 #include "setopt.h"
134 #include "altsvc.h"
135 #include "dynbuf.h"
136 #include "headers.h"
137
138 /* The last 3 #include files should be in this order */
139 #include "curl_printf.h"
140 #include "curl_memory.h"
141 #include "memdebug.h"
142
143 static void conn_free(struct connectdata *conn);
144
145 /* Some parts of the code (e.g. chunked encoding) assume this buffer has at
146  * more than just a few bytes to play with. Don't let it become too small or
147  * bad things will happen.
148  */
149 #if READBUFFER_SIZE < READBUFFER_MIN
150 # error READBUFFER_SIZE is too small
151 #endif
152
153 #ifdef USE_UNIX_SOCKETS
154 #define UNIX_SOCKET_PREFIX "localhost"
155 #endif
156
157 /* Reject URLs exceeding this length */
158 #define MAX_URL_LEN 0xffff
159
160 /*
161 * get_protocol_family()
162 *
163 * This is used to return the protocol family for a given protocol.
164 *
165 * Parameters:
166 *
167 * 'h'  [in]  - struct Curl_handler pointer.
168 *
169 * Returns the family as a single bit protocol identifier.
170 */
171 static curl_prot_t get_protocol_family(const struct Curl_handler *h)
172 {
173   DEBUGASSERT(h);
174   DEBUGASSERT(h->family);
175   return h->family;
176 }
177
178
179 /*
180  * Protocol table. Schemes (roughly) in 2019 popularity order:
181  *
182  * HTTPS, HTTP, FTP, FTPS, SFTP, FILE, SCP, SMTP, LDAP, IMAPS, TELNET, IMAP,
183  * LDAPS, SMTPS, TFTP, SMB, POP3, GOPHER POP3S, RTSP, RTMP, SMBS, DICT
184  */
185 static const struct Curl_handler * const protocols[] = {
186
187 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
188   &Curl_handler_https,
189 #endif
190
191 #ifndef CURL_DISABLE_HTTP
192   &Curl_handler_http,
193 #endif
194
195 #ifdef USE_WEBSOCKETS
196 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
197   &Curl_handler_wss,
198 #endif
199
200 #ifndef CURL_DISABLE_HTTP
201   &Curl_handler_ws,
202 #endif
203 #endif
204
205 #ifndef CURL_DISABLE_FTP
206   &Curl_handler_ftp,
207 #endif
208
209 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
210   &Curl_handler_ftps,
211 #endif
212
213 #if defined(USE_SSH)
214   &Curl_handler_sftp,
215 #endif
216
217 #ifndef CURL_DISABLE_FILE
218   &Curl_handler_file,
219 #endif
220
221 #if defined(USE_SSH) && !defined(USE_WOLFSSH)
222   &Curl_handler_scp,
223 #endif
224
225 #ifndef CURL_DISABLE_SMTP
226   &Curl_handler_smtp,
227 #ifdef USE_SSL
228   &Curl_handler_smtps,
229 #endif
230 #endif
231
232 #ifndef CURL_DISABLE_LDAP
233   &Curl_handler_ldap,
234 #if !defined(CURL_DISABLE_LDAPS) && \
235     ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
236      (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
237   &Curl_handler_ldaps,
238 #endif
239 #endif
240
241 #ifndef CURL_DISABLE_IMAP
242   &Curl_handler_imap,
243 #ifdef USE_SSL
244   &Curl_handler_imaps,
245 #endif
246 #endif
247
248 #ifndef CURL_DISABLE_TELNET
249   &Curl_handler_telnet,
250 #endif
251
252 #ifndef CURL_DISABLE_TFTP
253   &Curl_handler_tftp,
254 #endif
255
256 #ifndef CURL_DISABLE_POP3
257   &Curl_handler_pop3,
258 #ifdef USE_SSL
259   &Curl_handler_pop3s,
260 #endif
261 #endif
262
263 #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
264    (SIZEOF_CURL_OFF_T > 4)
265   &Curl_handler_smb,
266 #ifdef USE_SSL
267   &Curl_handler_smbs,
268 #endif
269 #endif
270
271 #ifndef CURL_DISABLE_RTSP
272   &Curl_handler_rtsp,
273 #endif
274
275 #ifndef CURL_DISABLE_MQTT
276   &Curl_handler_mqtt,
277 #endif
278
279 #ifndef CURL_DISABLE_GOPHER
280   &Curl_handler_gopher,
281 #ifdef USE_SSL
282   &Curl_handler_gophers,
283 #endif
284 #endif
285
286 #ifdef USE_LIBRTMP
287   &Curl_handler_rtmp,
288   &Curl_handler_rtmpt,
289   &Curl_handler_rtmpe,
290   &Curl_handler_rtmpte,
291   &Curl_handler_rtmps,
292   &Curl_handler_rtmpts,
293 #endif
294
295 #ifndef CURL_DISABLE_DICT
296   &Curl_handler_dict,
297 #endif
298
299   (struct Curl_handler *) NULL
300 };
301
302 /*
303  * Dummy handler for undefined protocol schemes.
304  */
305
306 static const struct Curl_handler Curl_handler_dummy = {
307   "<no protocol>",                      /* scheme */
308   ZERO_NULL,                            /* setup_connection */
309   ZERO_NULL,                            /* do_it */
310   ZERO_NULL,                            /* done */
311   ZERO_NULL,                            /* do_more */
312   ZERO_NULL,                            /* connect_it */
313   ZERO_NULL,                            /* connecting */
314   ZERO_NULL,                            /* doing */
315   ZERO_NULL,                            /* proto_getsock */
316   ZERO_NULL,                            /* doing_getsock */
317   ZERO_NULL,                            /* domore_getsock */
318   ZERO_NULL,                            /* perform_getsock */
319   ZERO_NULL,                            /* disconnect */
320   ZERO_NULL,                            /* readwrite */
321   ZERO_NULL,                            /* connection_check */
322   ZERO_NULL,                            /* attach connection */
323   0,                                    /* defport */
324   0,                                    /* protocol */
325   0,                                    /* family */
326   PROTOPT_NONE                          /* flags */
327 };
328
329 void Curl_freeset(struct Curl_easy *data)
330 {
331   /* Free all dynamic strings stored in the data->set substructure. */
332   enum dupstring i;
333   enum dupblob j;
334
335   for(i = (enum dupstring)0; i < STRING_LAST; i++) {
336     Curl_safefree(data->set.str[i]);
337   }
338
339   for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
340     Curl_safefree(data->set.blobs[j]);
341   }
342
343   if(data->state.referer_alloc) {
344     Curl_safefree(data->state.referer);
345     data->state.referer_alloc = FALSE;
346   }
347   data->state.referer = NULL;
348   if(data->state.url_alloc) {
349     Curl_safefree(data->state.url);
350     data->state.url_alloc = FALSE;
351   }
352   data->state.url = NULL;
353
354   Curl_mime_cleanpart(&data->set.mimepost);
355 }
356
357 /* free the URL pieces */
358 static void up_free(struct Curl_easy *data)
359 {
360   struct urlpieces *up = &data->state.up;
361   Curl_safefree(up->scheme);
362   Curl_safefree(up->hostname);
363   Curl_safefree(up->port);
364   Curl_safefree(up->user);
365   Curl_safefree(up->password);
366   Curl_safefree(up->options);
367   Curl_safefree(up->path);
368   Curl_safefree(up->query);
369   curl_url_cleanup(data->state.uh);
370   data->state.uh = NULL;
371 }
372
373 /*
374  * This is the internal function curl_easy_cleanup() calls. This should
375  * cleanup and free all resources associated with this sessionhandle.
376  *
377  * We ignore SIGPIPE when this is called from curl_easy_cleanup.
378  */
379
380 CURLcode Curl_close(struct Curl_easy **datap)
381 {
382   struct Curl_multi *m;
383   struct Curl_easy *data;
384
385   if(!datap || !*datap)
386     return CURLE_OK;
387
388   data = *datap;
389   *datap = NULL;
390
391   Curl_expire_clear(data); /* shut off timers */
392
393   /* Detach connection if any is left. This should not be normal, but can be
394      the case for example with CONNECT_ONLY + recv/send (test 556) */
395   Curl_detach_connection(data);
396   m = data->multi;
397   if(m)
398     /* This handle is still part of a multi handle, take care of this first
399        and detach this handle from there. */
400     curl_multi_remove_handle(data->multi, data);
401
402   if(data->multi_easy) {
403     /* when curl_easy_perform() is used, it creates its own multi handle to
404        use and this is the one */
405     curl_multi_cleanup(data->multi_easy);
406     data->multi_easy = NULL;
407   }
408
409   /* Destroy the timeout list that is held in the easy handle. It is
410      /normally/ done by curl_multi_remove_handle() but this is "just in
411      case" */
412   Curl_llist_destroy(&data->state.timeoutlist, NULL);
413
414   data->magic = 0; /* force a clear AFTER the possibly enforced removal from
415                       the multi handle, since that function uses the magic
416                       field! */
417
418   if(data->state.rangestringalloc)
419     free(data->state.range);
420
421   /* freed here just in case DONE wasn't called */
422   Curl_free_request_state(data);
423
424   /* Close down all open SSL info and sessions */
425   Curl_ssl_close_all(data);
426   Curl_safefree(data->state.first_host);
427   Curl_safefree(data->state.scratch);
428   Curl_ssl_free_certinfo(data);
429
430   /* Cleanup possible redirect junk */
431   free(data->req.newurl);
432   data->req.newurl = NULL;
433
434   if(data->state.referer_alloc) {
435     Curl_safefree(data->state.referer);
436     data->state.referer_alloc = FALSE;
437   }
438   data->state.referer = NULL;
439
440   up_free(data);
441   Curl_safefree(data->state.buffer);
442   Curl_dyn_free(&data->state.headerb);
443   Curl_safefree(data->state.ulbuf);
444   Curl_flush_cookies(data, TRUE);
445   Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
446   Curl_altsvc_cleanup(&data->asi);
447   Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]);
448   Curl_hsts_cleanup(&data->hsts);
449 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
450   Curl_http_auth_cleanup_digest(data);
451 #endif
452   Curl_safefree(data->info.contenttype);
453   Curl_safefree(data->info.wouldredirect);
454
455   /* this destroys the channel and we cannot use it anymore after this */
456   Curl_resolver_cancel(data);
457   Curl_resolver_cleanup(data->state.async.resolver);
458
459   Curl_http2_cleanup_dependencies(data);
460
461   /* No longer a dirty share, if it exists */
462   if(data->share) {
463     Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
464     data->share->dirty--;
465     Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
466   }
467
468   Curl_safefree(data->state.aptr.proxyuserpwd);
469   Curl_safefree(data->state.aptr.uagent);
470   Curl_safefree(data->state.aptr.userpwd);
471   Curl_safefree(data->state.aptr.accept_encoding);
472   Curl_safefree(data->state.aptr.te);
473   Curl_safefree(data->state.aptr.rangeline);
474   Curl_safefree(data->state.aptr.ref);
475   Curl_safefree(data->state.aptr.host);
476   Curl_safefree(data->state.aptr.cookiehost);
477   Curl_safefree(data->state.aptr.rtsp_transport);
478   Curl_safefree(data->state.aptr.user);
479   Curl_safefree(data->state.aptr.passwd);
480   Curl_safefree(data->state.aptr.proxyuser);
481   Curl_safefree(data->state.aptr.proxypasswd);
482
483 #ifndef CURL_DISABLE_DOH
484   if(data->req.doh) {
485     Curl_dyn_free(&data->req.doh->probe[0].serverdoh);
486     Curl_dyn_free(&data->req.doh->probe[1].serverdoh);
487     curl_slist_free_all(data->req.doh->headers);
488     Curl_safefree(data->req.doh);
489   }
490 #endif
491
492   /* destruct wildcard structures if it is needed */
493   Curl_wildcard_dtor(&data->wildcard);
494   Curl_freeset(data);
495   Curl_headers_cleanup(data);
496   free(data);
497   return CURLE_OK;
498 }
499
500 /*
501  * Initialize the UserDefined fields within a Curl_easy.
502  * This may be safely called on a new or existing Curl_easy.
503  */
504 CURLcode Curl_init_userdefined(struct Curl_easy *data)
505 {
506   struct UserDefined *set = &data->set;
507   CURLcode result = CURLE_OK;
508
509   set->out = stdout; /* default output to stdout */
510   set->in_set = stdin;  /* default input from stdin */
511   set->err  = stderr;  /* default stderr to stderr */
512
513   /* use fwrite as default function to store output */
514   set->fwrite_func = (curl_write_callback)fwrite;
515
516   /* use fread as default function to read input */
517   set->fread_func_set = (curl_read_callback)fread;
518   set->is_fread_set = 0;
519
520   set->seek_func = ZERO_NULL;
521   set->seek_client = ZERO_NULL;
522
523   set->filesize = -1;        /* we don't know the size */
524   set->postfieldsize = -1;   /* unknown size */
525   set->maxredirs = -1;       /* allow any amount by default */
526
527   set->method = HTTPREQ_GET; /* Default HTTP request */
528 #ifndef CURL_DISABLE_RTSP
529   set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
530 #endif
531 #ifndef CURL_DISABLE_FTP
532   set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
533   set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
534   set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
535   set->ftp_filemethod = FTPFILE_MULTICWD;
536   set->ftp_skip_ip = TRUE;    /* skip PASV IP by default */
537 #endif
538   set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
539
540   /* Set the default size of the SSL session ID cache */
541   set->general_ssl.max_ssl_sessions = 5;
542
543   set->proxyport = 0;
544   set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
545   set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
546
547 #ifndef CURL_DISABLE_PROXY
548   set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
549   /* SOCKS5 proxy auth defaults to username/password + GSS-API */
550   set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI;
551 #endif
552
553   /* make libcurl quiet by default: */
554   set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
555
556   Curl_mime_initpart(&set->mimepost, data);
557
558   /*
559    * libcurl 7.10 introduced SSL verification *by default*! This needs to be
560    * switched off unless wanted.
561    */
562 #ifndef CURL_DISABLE_DOH
563   set->doh_verifyhost = TRUE;
564   set->doh_verifypeer = TRUE;
565 #endif
566   set->ssl.primary.verifypeer = TRUE;
567   set->ssl.primary.verifyhost = TRUE;
568 #ifdef USE_TLS_SRP
569   set->ssl.primary.authtype = CURL_TLSAUTH_NONE;
570 #endif
571    /* defaults to any auth type */
572   set->ssh_auth_types = CURLSSH_AUTH_DEFAULT;
573   set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
574                                         default */
575 #ifndef CURL_DISABLE_PROXY
576   set->proxy_ssl = set->ssl;
577 #endif
578
579   set->new_file_perms = 0644;    /* Default permissions */
580   set->new_directory_perms = 0755; /* Default permissions */
581   set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL;
582   set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP |
583                          CURLPROTO_FTPS;
584
585 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
586   /*
587    * disallow unprotected protection negotiation NEC reference implementation
588    * seem not to follow rfc1961 section 4.3/4.4
589    */
590   set->socks5_gssapi_nec = FALSE;
591 #endif
592
593   /* Set the default CA cert bundle/path detected/specified at build time.
594    *
595    * If Schannel is the selected SSL backend then these locations are
596    * ignored. We allow setting CA location for schannel only when explicitly
597    * specified by the user via CURLOPT_CAINFO / --cacert.
598    */
599   if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) {
600 #if defined(CURL_CA_BUNDLE)
601     result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE);
602     if(result)
603       return result;
604
605     result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY],
606                             CURL_CA_BUNDLE);
607     if(result)
608       return result;
609 #endif
610 #if defined(CURL_CA_PATH)
611     result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH);
612     if(result)
613       return result;
614
615     result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH);
616     if(result)
617       return result;
618 #endif
619   }
620
621 #ifndef CURL_DISABLE_FTP
622   set->wildcard_enabled = FALSE;
623   set->chunk_bgn      = ZERO_NULL;
624   set->chunk_end      = ZERO_NULL;
625   set->fnmatch = ZERO_NULL;
626 #endif
627   set->tcp_keepalive = FALSE;
628   set->tcp_keepintvl = 60;
629   set->tcp_keepidle = 60;
630   set->tcp_fastopen = FALSE;
631   set->tcp_nodelay = TRUE;
632   set->ssl_enable_alpn = TRUE;
633   set->expect_100_timeout = 1000L; /* Wait for a second by default. */
634   set->sep_headers = TRUE; /* separated header lists by default */
635   set->buffer_size = READBUFFER_SIZE;
636   set->upload_buffer_size = UPLOADBUFFER_DEFAULT;
637   set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
638   set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
639   set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
640   set->maxage_conn = 118;
641   set->maxlifetime_conn = 0;
642   set->http09_allowed = FALSE;
643   set->httpwant =
644 #ifdef USE_HTTP2
645     CURL_HTTP_VERSION_2TLS
646 #else
647     CURL_HTTP_VERSION_1_1
648 #endif
649     ;
650   Curl_http2_init_userset(set);
651   return result;
652 }
653
654 /**
655  * Curl_open()
656  *
657  * @param curl is a pointer to a sessionhandle pointer that gets set by this
658  * function.
659  * @return CURLcode
660  */
661
662 CURLcode Curl_open(struct Curl_easy **curl)
663 {
664   CURLcode result;
665   struct Curl_easy *data;
666
667   /* Very simple start-up: alloc the struct, init it with zeroes and return */
668   data = calloc(1, sizeof(struct Curl_easy));
669   if(!data) {
670     /* this is a very serious error */
671     DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n"));
672     return CURLE_OUT_OF_MEMORY;
673   }
674
675   data->magic = CURLEASY_MAGIC_NUMBER;
676
677   result = Curl_resolver_init(data, &data->state.async.resolver);
678   if(result) {
679     DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
680     free(data);
681     return result;
682   }
683
684   result = Curl_init_userdefined(data);
685   if(!result) {
686     Curl_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER);
687     Curl_initinfo(data);
688
689     /* most recent connection is not yet defined */
690     data->state.lastconnect_id = -1;
691
692     data->progress.flags |= PGRS_HIDE;
693     data->state.current_speed = -1; /* init to negative == impossible */
694   }
695
696   if(result) {
697     Curl_resolver_cleanup(data->state.async.resolver);
698     Curl_dyn_free(&data->state.headerb);
699     Curl_freeset(data);
700     free(data);
701     data = NULL;
702   }
703   else
704     *curl = data;
705
706   return result;
707 }
708
709 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
710 static void conn_reset_postponed_data(struct connectdata *conn, int num)
711 {
712   struct postponed_data * const psnd = &(conn->postponed[num]);
713   if(psnd->buffer) {
714     DEBUGASSERT(psnd->allocated_size > 0);
715     DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
716     DEBUGASSERT(psnd->recv_size ?
717                 (psnd->recv_processed < psnd->recv_size) :
718                 (psnd->recv_processed == 0));
719     DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD);
720     free(psnd->buffer);
721     psnd->buffer = NULL;
722     psnd->allocated_size = 0;
723     psnd->recv_size = 0;
724     psnd->recv_processed = 0;
725 #ifdef DEBUGBUILD
726     psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */
727 #endif /* DEBUGBUILD */
728   }
729   else {
730     DEBUGASSERT(psnd->allocated_size == 0);
731     DEBUGASSERT(psnd->recv_size == 0);
732     DEBUGASSERT(psnd->recv_processed == 0);
733     DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD);
734   }
735 }
736
737 static void conn_reset_all_postponed_data(struct connectdata *conn)
738 {
739   conn_reset_postponed_data(conn, 0);
740   conn_reset_postponed_data(conn, 1);
741 }
742 #else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
743 /* Use "do-nothing" macro instead of function when workaround not used */
744 #define conn_reset_all_postponed_data(c) do {} while(0)
745 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
746
747
748 static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
749 {
750   DEBUGASSERT(conn);
751   DEBUGASSERT(data);
752   infof(data, "Closing connection %ld", conn->connection_id);
753
754   /* possible left-overs from the async name resolvers */
755   Curl_resolver_cancel(data);
756
757   /* close the SSL stuff before we close any sockets since they will/may
758      write to the sockets */
759   Curl_ssl_close(data, conn, FIRSTSOCKET);
760 #ifndef CURL_DISABLE_FTP
761   Curl_ssl_close(data, conn, SECONDARYSOCKET);
762 #endif
763
764   /* close possibly still open sockets */
765   if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
766     Curl_closesocket(data, conn, conn->sock[SECONDARYSOCKET]);
767   if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
768     Curl_closesocket(data, conn, conn->sock[FIRSTSOCKET]);
769   if(CURL_SOCKET_BAD != conn->tempsock[0])
770     Curl_closesocket(data, conn, conn->tempsock[0]);
771   if(CURL_SOCKET_BAD != conn->tempsock[1])
772     Curl_closesocket(data, conn, conn->tempsock[1]);
773 }
774
775 static void conn_free(struct connectdata *conn)
776 {
777   DEBUGASSERT(conn);
778
779   Curl_free_idnconverted_hostname(&conn->host);
780   Curl_free_idnconverted_hostname(&conn->conn_to_host);
781 #ifndef CURL_DISABLE_PROXY
782   Curl_free_idnconverted_hostname(&conn->http_proxy.host);
783   Curl_free_idnconverted_hostname(&conn->socks_proxy.host);
784   Curl_safefree(conn->http_proxy.user);
785   Curl_safefree(conn->socks_proxy.user);
786   Curl_safefree(conn->http_proxy.passwd);
787   Curl_safefree(conn->socks_proxy.passwd);
788   Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
789   Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
790   Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
791 #endif
792   Curl_safefree(conn->user);
793   Curl_safefree(conn->passwd);
794   Curl_safefree(conn->sasl_authzid);
795   Curl_safefree(conn->options);
796   Curl_safefree(conn->oauth_bearer);
797   Curl_dyn_free(&conn->trailer);
798   Curl_safefree(conn->host.rawalloc); /* host name buffer */
799   Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
800   Curl_safefree(conn->hostname_resolve);
801   Curl_safefree(conn->secondaryhostname);
802   Curl_safefree(conn->connect_state);
803
804   conn_reset_all_postponed_data(conn);
805   Curl_llist_destroy(&conn->easyq, NULL);
806   Curl_safefree(conn->localdev);
807   Curl_free_primary_ssl_config(&conn->ssl_config);
808
809 #ifdef USE_UNIX_SOCKETS
810   Curl_safefree(conn->unix_domain_socket);
811 #endif
812
813 #ifdef USE_SSL
814   Curl_safefree(conn->ssl_extra);
815 #endif
816   free(conn); /* free all the connection oriented data */
817 }
818
819 /*
820  * Disconnects the given connection. Note the connection may not be the
821  * primary connection, like when freeing room in the connection cache or
822  * killing of a dead old connection.
823  *
824  * A connection needs an easy handle when closing down. We support this passed
825  * in separately since the connection to get closed here is often already
826  * disassociated from an easy handle.
827  *
828  * This function MUST NOT reset state in the Curl_easy struct if that
829  * isn't strictly bound to the life-time of *this* particular connection.
830  *
831  */
832
833 void Curl_disconnect(struct Curl_easy *data,
834                      struct connectdata *conn, bool dead_connection)
835 {
836   /* there must be a connection to close */
837   DEBUGASSERT(conn);
838
839   /* it must be removed from the connection cache */
840   DEBUGASSERT(!conn->bundle);
841
842   /* there must be an associated transfer */
843   DEBUGASSERT(data);
844
845   /* the transfer must be detached from the connection */
846   DEBUGASSERT(!data->conn);
847
848   /*
849    * If this connection isn't marked to force-close, leave it open if there
850    * are other users of it
851    */
852   if(CONN_INUSE(conn) && !dead_connection) {
853     DEBUGF(infof(data, "Curl_disconnect when inuse: %zu", CONN_INUSE(conn)));
854     return;
855   }
856
857   if(conn->dns_entry) {
858     Curl_resolv_unlock(data, conn->dns_entry);
859     conn->dns_entry = NULL;
860   }
861
862   /* Cleanup NTLM connection-related data */
863   Curl_http_auth_cleanup_ntlm(conn);
864
865   /* Cleanup NEGOTIATE connection-related data */
866   Curl_http_auth_cleanup_negotiate(conn);
867
868   if(conn->connect_only)
869     /* treat the connection as dead in CONNECT_ONLY situations */
870     dead_connection = TRUE;
871
872   /* temporarily attach the connection to this transfer handle for the
873      disconnect and shutdown */
874   Curl_attach_connection(data, conn);
875
876   if(conn->handler->disconnect)
877     /* This is set if protocol-specific cleanups should be made */
878     conn->handler->disconnect(data, conn, dead_connection);
879
880   conn_shutdown(data, conn);
881
882   /* detach it again */
883   Curl_detach_connection(data);
884
885   conn_free(conn);
886 }
887
888 /*
889  * This function should return TRUE if the socket is to be assumed to
890  * be dead. Most commonly this happens when the server has closed the
891  * connection due to inactivity.
892  */
893 static bool SocketIsDead(curl_socket_t sock)
894 {
895   int sval;
896   bool ret_val = TRUE;
897
898   sval = SOCKET_READABLE(sock, 0);
899   if(sval == 0)
900     /* timeout */
901     ret_val = FALSE;
902
903   return ret_val;
904 }
905
906 /*
907  * IsMultiplexingPossible()
908  *
909  * Return a bitmask with the available multiplexing options for the given
910  * requested connection.
911  */
912 static int IsMultiplexingPossible(const struct Curl_easy *handle,
913                                   const struct connectdata *conn)
914 {
915   int avail = 0;
916
917   /* If a HTTP protocol and multiplexing is enabled */
918   if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
919      (!conn->bits.protoconnstart || !conn->bits.close)) {
920
921     if(Curl_multiplex_wanted(handle->multi) &&
922        (handle->state.httpwant >= CURL_HTTP_VERSION_2))
923       /* allows HTTP/2 */
924       avail |= CURLPIPE_MULTIPLEX;
925   }
926   return avail;
927 }
928
929 #ifndef CURL_DISABLE_PROXY
930 static bool
931 proxy_info_matches(const struct proxy_info *data,
932                    const struct proxy_info *needle)
933 {
934   if((data->proxytype == needle->proxytype) &&
935      (data->port == needle->port) &&
936      Curl_safe_strcasecompare(data->host.name, needle->host.name))
937     return TRUE;
938
939   return FALSE;
940 }
941
942 static bool
943 socks_proxy_info_matches(const struct proxy_info *data,
944                          const struct proxy_info *needle)
945 {
946   if(!proxy_info_matches(data, needle))
947     return FALSE;
948
949   /* the user information is case-sensitive
950      or at least it is not defined as case-insensitive
951      see https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 */
952
953   /* curl_strequal does a case insensitive comparison,
954      so do not use it here! */
955   if(Curl_timestrcmp(data->user, needle->user) ||
956      Curl_timestrcmp(data->passwd, needle->passwd))
957     return FALSE;
958   return TRUE;
959 }
960 #else
961 /* disabled, won't get called */
962 #define proxy_info_matches(x,y) FALSE
963 #define socks_proxy_info_matches(x,y) FALSE
964 #endif
965
966 /* A connection has to have been idle for a shorter time than 'maxage_conn'
967    (the success rate is just too low after this), or created less than
968    'maxlifetime_conn' ago, to be subject for reuse. */
969
970 static bool conn_maxage(struct Curl_easy *data,
971                         struct connectdata *conn,
972                         struct curltime now)
973 {
974   timediff_t idletime, lifetime;
975
976   idletime = Curl_timediff(now, conn->lastused);
977   idletime /= 1000; /* integer seconds is fine */
978
979   if(idletime > data->set.maxage_conn) {
980     infof(data, "Too old connection (%ld seconds idle), disconnect it",
981           idletime);
982     return TRUE;
983   }
984
985   lifetime = Curl_timediff(now, conn->created);
986   lifetime /= 1000; /* integer seconds is fine */
987
988   if(data->set.maxlifetime_conn && lifetime > data->set.maxlifetime_conn) {
989     infof(data,
990           "Too old connection (%ld seconds since creation), disconnect it",
991           lifetime);
992     return TRUE;
993   }
994
995
996   return FALSE;
997 }
998
999 /*
1000  * This function checks if the given connection is dead and extracts it from
1001  * the connection cache if so.
1002  *
1003  * When this is called as a Curl_conncache_foreach() callback, the connection
1004  * cache lock is held!
1005  *
1006  * Returns TRUE if the connection was dead and extracted.
1007  */
1008 static bool extract_if_dead(struct connectdata *conn,
1009                             struct Curl_easy *data)
1010 {
1011   if(!CONN_INUSE(conn)) {
1012     /* The check for a dead socket makes sense only if the connection isn't in
1013        use */
1014     bool dead;
1015     struct curltime now = Curl_now();
1016     if(conn_maxage(data, conn, now)) {
1017       /* avoid check if already too old */
1018       dead = TRUE;
1019     }
1020     else if(conn->handler->connection_check) {
1021       /* The protocol has a special method for checking the state of the
1022          connection. Use it to check if the connection is dead. */
1023       unsigned int state;
1024
1025       /* briefly attach the connection to this transfer for the purpose of
1026          checking it */
1027       Curl_attach_connection(data, conn);
1028
1029       state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD);
1030       dead = (state & CONNRESULT_DEAD);
1031       /* detach the connection again */
1032       Curl_detach_connection(data);
1033
1034     }
1035     else {
1036       /* Use the general method for determining the death of a connection */
1037       dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
1038     }
1039
1040     if(dead) {
1041       infof(data, "Connection %ld seems to be dead", conn->connection_id);
1042       Curl_conncache_remove_conn(data, conn, FALSE);
1043       return TRUE;
1044     }
1045   }
1046   return FALSE;
1047 }
1048
1049 struct prunedead {
1050   struct Curl_easy *data;
1051   struct connectdata *extracted;
1052 };
1053
1054 /*
1055  * Wrapper to use extract_if_dead() function in Curl_conncache_foreach()
1056  *
1057  */
1058 static int call_extract_if_dead(struct Curl_easy *data,
1059                                 struct connectdata *conn, void *param)
1060 {
1061   struct prunedead *p = (struct prunedead *)param;
1062   if(extract_if_dead(conn, data)) {
1063     /* stop the iteration here, pass back the connection that was extracted */
1064     p->extracted = conn;
1065     return 1;
1066   }
1067   return 0; /* continue iteration */
1068 }
1069
1070 /*
1071  * This function scans the connection cache for half-open/dead connections,
1072  * closes and removes them. The cleanup is done at most once per second.
1073  *
1074  * When called, this transfer has no connection attached.
1075  */
1076 static void prune_dead_connections(struct Curl_easy *data)
1077 {
1078   struct curltime now = Curl_now();
1079   timediff_t elapsed;
1080
1081   DEBUGASSERT(!data->conn); /* no connection */
1082   CONNCACHE_LOCK(data);
1083   elapsed =
1084     Curl_timediff(now, data->state.conn_cache->last_cleanup);
1085   CONNCACHE_UNLOCK(data);
1086
1087   if(elapsed >= 1000L) {
1088     struct prunedead prune;
1089     prune.data = data;
1090     prune.extracted = NULL;
1091     while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
1092                                  call_extract_if_dead)) {
1093       /* unlocked */
1094
1095       /* remove connection from cache */
1096       Curl_conncache_remove_conn(data, prune.extracted, TRUE);
1097
1098       /* disconnect it */
1099       Curl_disconnect(data, prune.extracted, TRUE);
1100     }
1101     CONNCACHE_LOCK(data);
1102     data->state.conn_cache->last_cleanup = now;
1103     CONNCACHE_UNLOCK(data);
1104   }
1105 }
1106
1107 #ifdef USE_SSH
1108 static bool ssh_config_matches(struct connectdata *one,
1109                                struct connectdata *two)
1110 {
1111   return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) &&
1112           Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub));
1113 }
1114 #else
1115 #define ssh_config_matches(x,y) FALSE
1116 #endif
1117
1118 /*
1119  * Given one filled in connection struct (named needle), this function should
1120  * detect if there already is one that has all the significant details
1121  * exactly the same and thus should be used instead.
1122  *
1123  * If there is a match, this function returns TRUE - and has marked the
1124  * connection as 'in-use'. It must later be called with ConnectionDone() to
1125  * return back to 'idle' (unused) state.
1126  *
1127  * The force_reuse flag is set if the connection must be used.
1128  */
1129 static bool
1130 ConnectionExists(struct Curl_easy *data,
1131                  struct connectdata *needle,
1132                  struct connectdata **usethis,
1133                  bool *force_reuse,
1134                  bool *waitpipe)
1135 {
1136   struct connectdata *check;
1137   struct connectdata *chosen = 0;
1138   bool foundPendingCandidate = FALSE;
1139   bool canmultiplex = IsMultiplexingPossible(data, needle);
1140   struct connectbundle *bundle;
1141
1142 #ifdef USE_NTLM
1143   bool wantNTLMhttp = ((data->state.authhost.want &
1144                         (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
1145                        (needle->handler->protocol & PROTO_FAMILY_HTTP));
1146 #ifndef CURL_DISABLE_PROXY
1147   bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
1148                             ((data->state.authproxy.want &
1149                               (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
1150                              (needle->handler->protocol & PROTO_FAMILY_HTTP)));
1151 #else
1152   bool wantProxyNTLMhttp = FALSE;
1153 #endif
1154 #endif
1155
1156   *force_reuse = FALSE;
1157   *waitpipe = FALSE;
1158
1159   /* Look up the bundle with all the connections to this particular host.
1160      Locks the connection cache, beware of early returns! */
1161   bundle = Curl_conncache_find_bundle(data, needle, data->state.conn_cache);
1162   if(bundle) {
1163     /* Max pipe length is zero (unlimited) for multiplexed connections */
1164     struct Curl_llist_element *curr;
1165
1166     infof(data, "Found bundle for host: %p [%s]",
1167           (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
1168                            "can multiplex" : "serially"));
1169
1170     /* We can't multiplex if we don't know anything about the server */
1171     if(canmultiplex) {
1172       if(bundle->multiuse == BUNDLE_UNKNOWN) {
1173         if(data->set.pipewait) {
1174           infof(data, "Server doesn't support multiplex yet, wait");
1175           *waitpipe = TRUE;
1176           CONNCACHE_UNLOCK(data);
1177           return FALSE; /* no re-use */
1178         }
1179
1180         infof(data, "Server doesn't support multiplex (yet)");
1181         canmultiplex = FALSE;
1182       }
1183       if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
1184          !Curl_multiplex_wanted(data->multi)) {
1185         infof(data, "Could multiplex, but not asked to");
1186         canmultiplex = FALSE;
1187       }
1188       if(bundle->multiuse == BUNDLE_NO_MULTIUSE) {
1189         infof(data, "Can not multiplex, even if we wanted to");
1190         canmultiplex = FALSE;
1191       }
1192     }
1193
1194     curr = bundle->conn_list.head;
1195     while(curr) {
1196       bool match = FALSE;
1197       size_t multiplexed = 0;
1198
1199       /*
1200        * Note that if we use a HTTP proxy in normal mode (no tunneling), we
1201        * check connections to that proxy and not to the actual remote server.
1202        */
1203       check = curr->ptr;
1204       curr = curr->next;
1205
1206       if(check->connect_only || check->bits.close)
1207         /* connect-only or to-be-closed connections will not be reused */
1208         continue;
1209
1210       if(extract_if_dead(check, data)) {
1211         /* disconnect it */
1212         Curl_disconnect(data, check, TRUE);
1213         continue;
1214       }
1215
1216       if(data->set.ipver != CURL_IPRESOLVE_WHATEVER
1217           && data->set.ipver != check->ip_version) {
1218         /* skip because the connection is not via the requested IP version */
1219         continue;
1220       }
1221
1222       if(bundle->multiuse == BUNDLE_MULTIPLEX)
1223         multiplexed = CONN_INUSE(check);
1224
1225       if(!canmultiplex) {
1226         if(multiplexed) {
1227           /* can only happen within multi handles, and means that another easy
1228              handle is using this connection */
1229           continue;
1230         }
1231
1232         if(Curl_resolver_asynch()) {
1233           /* primary_ip[0] is NUL only if the resolving of the name hasn't
1234              completed yet and until then we don't re-use this connection */
1235           if(!check->primary_ip[0]) {
1236             infof(data,
1237                   "Connection #%ld is still name resolving, can't reuse",
1238                   check->connection_id);
1239             continue;
1240           }
1241         }
1242
1243         if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
1244           foundPendingCandidate = TRUE;
1245           /* Don't pick a connection that hasn't connected yet */
1246           infof(data, "Connection #%ld isn't open enough, can't reuse",
1247                 check->connection_id);
1248           continue;
1249         }
1250       }
1251
1252 #ifdef USE_UNIX_SOCKETS
1253       if(needle->unix_domain_socket) {
1254         if(!check->unix_domain_socket)
1255           continue;
1256         if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
1257           continue;
1258         if(needle->bits.abstract_unix_socket !=
1259            check->bits.abstract_unix_socket)
1260           continue;
1261       }
1262       else if(check->unix_domain_socket)
1263         continue;
1264 #endif
1265
1266       if((needle->handler->flags&PROTOPT_SSL) !=
1267          (check->handler->flags&PROTOPT_SSL))
1268         /* don't do mixed SSL and non-SSL connections */
1269         if(get_protocol_family(check->handler) !=
1270            needle->handler->protocol || !check->bits.tls_upgraded)
1271           /* except protocols that have been upgraded via TLS */
1272           continue;
1273
1274 #ifndef CURL_DISABLE_PROXY
1275       if(needle->bits.httpproxy != check->bits.httpproxy ||
1276          needle->bits.socksproxy != check->bits.socksproxy)
1277         continue;
1278
1279       if(needle->bits.socksproxy &&
1280         !socks_proxy_info_matches(&needle->socks_proxy,
1281                                   &check->socks_proxy))
1282         continue;
1283 #endif
1284       if(needle->bits.conn_to_host != check->bits.conn_to_host)
1285         /* don't mix connections that use the "connect to host" feature and
1286          * connections that don't use this feature */
1287         continue;
1288
1289       if(needle->bits.conn_to_port != check->bits.conn_to_port)
1290         /* don't mix connections that use the "connect to port" feature and
1291          * connections that don't use this feature */
1292         continue;
1293
1294 #ifndef CURL_DISABLE_PROXY
1295       if(needle->bits.httpproxy) {
1296         if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
1297           continue;
1298
1299         if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
1300           continue;
1301
1302         if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
1303           /* use https proxy */
1304           if(needle->handler->flags&PROTOPT_SSL) {
1305             /* use double layer ssl */
1306             if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
1307                                         &check->proxy_ssl_config))
1308               continue;
1309             if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
1310               continue;
1311           }
1312
1313           if(!Curl_ssl_config_matches(&needle->ssl_config,
1314                                       &check->ssl_config))
1315             continue;
1316           if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
1317             continue;
1318         }
1319       }
1320 #endif
1321
1322       if(!canmultiplex && CONN_INUSE(check))
1323         /* this request can't be multiplexed but the checked connection is
1324            already in use so we skip it */
1325         continue;
1326
1327       if(CONN_INUSE(check)) {
1328         /* Subject for multiplex use if 'checks' belongs to the same multi
1329            handle as 'data' is. */
1330         struct Curl_llist_element *e = check->easyq.head;
1331         struct Curl_easy *entry = e->ptr;
1332         if(entry->multi != data->multi)
1333           continue;
1334       }
1335
1336       if(needle->localdev || needle->localport) {
1337         /* If we are bound to a specific local end (IP+port), we must not
1338            re-use a random other one, although if we didn't ask for a
1339            particular one we can reuse one that was bound.
1340
1341            This comparison is a bit rough and too strict. Since the input
1342            parameters can be specified in numerous ways and still end up the
1343            same it would take a lot of processing to make it really accurate.
1344            Instead, this matching will assume that re-uses of bound connections
1345            will most likely also re-use the exact same binding parameters and
1346            missing out a few edge cases shouldn't hurt anyone very much.
1347         */
1348         if((check->localport != needle->localport) ||
1349            (check->localportrange != needle->localportrange) ||
1350            (needle->localdev &&
1351             (!check->localdev || strcmp(check->localdev, needle->localdev))))
1352           continue;
1353       }
1354
1355       if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
1356         /* This protocol requires credentials per connection,
1357            so verify that we're using the same name and password as well */
1358         if(Curl_timestrcmp(needle->user, check->user) ||
1359            Curl_timestrcmp(needle->passwd, check->passwd) ||
1360            Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) ||
1361            Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) {
1362           /* one of them was different */
1363           continue;
1364         }
1365       }
1366
1367       /* If multiplexing isn't enabled on the h2 connection and h1 is
1368          explicitly requested, handle it: */
1369       if((needle->handler->protocol & PROTO_FAMILY_HTTP) &&
1370          (check->httpversion >= 20) &&
1371          (data->state.httpwant < CURL_HTTP_VERSION_2_0))
1372         continue;
1373
1374       if(get_protocol_family(needle->handler) == PROTO_FAMILY_SSH) {
1375         if(!ssh_config_matches(needle, check))
1376           continue;
1377       }
1378
1379       if((needle->handler->flags&PROTOPT_SSL)
1380 #ifndef CURL_DISABLE_PROXY
1381          || !needle->bits.httpproxy || needle->bits.tunnel_proxy
1382 #endif
1383         ) {
1384         /* The requested connection does not use a HTTP proxy or it uses SSL or
1385            it is a non-SSL protocol tunneled or it is a non-SSL protocol which
1386            is allowed to be upgraded via TLS */
1387
1388         if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
1389             (get_protocol_family(check->handler) ==
1390              needle->handler->protocol && check->bits.tls_upgraded)) &&
1391            (!needle->bits.conn_to_host || strcasecompare(
1392             needle->conn_to_host.name, check->conn_to_host.name)) &&
1393            (!needle->bits.conn_to_port ||
1394              needle->conn_to_port == check->conn_to_port) &&
1395            strcasecompare(needle->host.name, check->host.name) &&
1396            needle->remote_port == check->remote_port) {
1397           /* The schemes match or the protocol family is the same and the
1398              previous connection was TLS upgraded, and the hostname and host
1399              port match */
1400           if(needle->handler->flags & PROTOPT_SSL) {
1401             /* This is a SSL connection so verify that we're using the same
1402                SSL options as well */
1403             if(!Curl_ssl_config_matches(&needle->ssl_config,
1404                                         &check->ssl_config)) {
1405               DEBUGF(infof(data,
1406                            "Connection #%ld has different SSL parameters, "
1407                            "can't reuse",
1408                            check->connection_id));
1409               continue;
1410             }
1411             if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
1412               foundPendingCandidate = TRUE;
1413               DEBUGF(infof(data,
1414                            "Connection #%ld has not started SSL connect, "
1415                            "can't reuse",
1416                            check->connection_id));
1417               continue;
1418             }
1419           }
1420           match = TRUE;
1421         }
1422       }
1423       else {
1424         /* The requested connection is using the same HTTP proxy in normal
1425            mode (no tunneling) */
1426         match = TRUE;
1427       }
1428
1429       if(match) {
1430 #if defined(USE_NTLM)
1431         /* If we are looking for an HTTP+NTLM connection, check if this is
1432            already authenticating with the right credentials. If not, keep
1433            looking so that we can reuse NTLM connections if
1434            possible. (Especially we must not reuse the same connection if
1435            partway through a handshake!) */
1436         if(wantNTLMhttp) {
1437           if(Curl_timestrcmp(needle->user, check->user) ||
1438              Curl_timestrcmp(needle->passwd, check->passwd)) {
1439
1440             /* we prefer a credential match, but this is at least a connection
1441                that can be reused and "upgraded" to NTLM */
1442             if(check->http_ntlm_state == NTLMSTATE_NONE)
1443               chosen = check;
1444             continue;
1445           }
1446         }
1447         else if(check->http_ntlm_state != NTLMSTATE_NONE) {
1448           /* Connection is using NTLM auth but we don't want NTLM */
1449           continue;
1450         }
1451
1452 #ifndef CURL_DISABLE_PROXY
1453         /* Same for Proxy NTLM authentication */
1454         if(wantProxyNTLMhttp) {
1455           /* Both check->http_proxy.user and check->http_proxy.passwd can be
1456            * NULL */
1457           if(!check->http_proxy.user || !check->http_proxy.passwd)
1458             continue;
1459
1460           if(Curl_timestrcmp(needle->http_proxy.user,
1461                              check->http_proxy.user) ||
1462              Curl_timestrcmp(needle->http_proxy.passwd,
1463                              check->http_proxy.passwd))
1464             continue;
1465         }
1466         else if(check->proxy_ntlm_state != NTLMSTATE_NONE) {
1467           /* Proxy connection is using NTLM auth but we don't want NTLM */
1468           continue;
1469         }
1470 #endif
1471         if(wantNTLMhttp || wantProxyNTLMhttp) {
1472           /* Credentials are already checked, we can use this connection */
1473           chosen = check;
1474
1475           if((wantNTLMhttp &&
1476              (check->http_ntlm_state != NTLMSTATE_NONE)) ||
1477               (wantProxyNTLMhttp &&
1478                (check->proxy_ntlm_state != NTLMSTATE_NONE))) {
1479             /* We must use this connection, no other */
1480             *force_reuse = TRUE;
1481             break;
1482           }
1483
1484           /* Continue look up for a better connection */
1485           continue;
1486         }
1487 #endif
1488         if(canmultiplex) {
1489           /* We can multiplex if we want to. Let's continue looking for
1490              the optimal connection to use. */
1491
1492           if(!multiplexed) {
1493             /* We have the optimal connection. Let's stop looking. */
1494             chosen = check;
1495             break;
1496           }
1497
1498 #ifdef USE_NGHTTP2
1499           /* If multiplexed, make sure we don't go over concurrency limit */
1500           if(check->bits.multiplex) {
1501             /* Multiplexed connections can only be HTTP/2 for now */
1502             struct http_conn *httpc = &check->proto.httpc;
1503             if(multiplexed >= httpc->settings.max_concurrent_streams) {
1504               infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)",
1505                     multiplexed);
1506               continue;
1507             }
1508             else if(multiplexed >=
1509                     Curl_multi_max_concurrent_streams(data->multi)) {
1510               infof(data, "client side MAX_CONCURRENT_STREAMS reached"
1511                     ", skip (%zu)",
1512                     multiplexed);
1513               continue;
1514             }
1515           }
1516 #endif
1517           /* When not multiplexed, we have a match here! */
1518           chosen = check;
1519           infof(data, "Multiplexed connection found");
1520           break;
1521         }
1522         else {
1523           /* We have found a connection. Let's stop searching. */
1524           chosen = check;
1525           break;
1526         }
1527       }
1528     }
1529   }
1530
1531   if(chosen) {
1532     /* mark it as used before releasing the lock */
1533     Curl_attach_connection(data, chosen);
1534     CONNCACHE_UNLOCK(data);
1535     *usethis = chosen;
1536     return TRUE; /* yes, we found one to use! */
1537   }
1538   CONNCACHE_UNLOCK(data);
1539
1540   if(foundPendingCandidate && data->set.pipewait) {
1541     infof(data,
1542           "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set");
1543     *waitpipe = TRUE;
1544   }
1545
1546   return FALSE; /* no matching connecting exists */
1547 }
1548
1549 /*
1550  * verboseconnect() displays verbose information after a connect
1551  */
1552 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1553 void Curl_verboseconnect(struct Curl_easy *data,
1554                          struct connectdata *conn)
1555 {
1556   if(data->set.verbose)
1557     infof(data, "Connected to %s (%s) port %u (#%ld)",
1558 #ifndef CURL_DISABLE_PROXY
1559           conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
1560           conn->bits.httpproxy ? conn->http_proxy.host.dispname :
1561 #endif
1562           conn->bits.conn_to_host ? conn->conn_to_host.dispname :
1563           conn->host.dispname,
1564           conn->primary_ip, conn->port, conn->connection_id);
1565 }
1566 #endif
1567
1568 /*
1569  * Helpers for IDNA conversions.
1570  */
1571 bool Curl_is_ASCII_name(const char *hostname)
1572 {
1573   /* get an UNSIGNED local version of the pointer */
1574   const unsigned char *ch = (const unsigned char *)hostname;
1575
1576   if(!hostname) /* bad input, consider it ASCII! */
1577     return TRUE;
1578
1579   while(*ch) {
1580     if(*ch++ & 0x80)
1581       return FALSE;
1582   }
1583   return TRUE;
1584 }
1585
1586 /*
1587  * Perform any necessary IDN conversion of hostname
1588  */
1589 CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
1590                                   struct hostname *host)
1591 {
1592 #ifndef USE_LIBIDN2
1593   (void)data;
1594   (void)data;
1595 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
1596   (void)data;
1597 #endif
1598
1599   /* set the name we use to display the host name */
1600   host->dispname = host->name;
1601
1602   /* Check name for non-ASCII and convert hostname to ACE form if we can */
1603   if(!Curl_is_ASCII_name(host->name)) {
1604 #ifdef USE_LIBIDN2
1605     if(idn2_check_version(IDN2_VERSION)) {
1606       char *ace_hostname = NULL;
1607 #if IDN2_VERSION_NUMBER >= 0x00140000
1608       /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
1609          IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
1610          processing. */
1611       int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
1612 #else
1613       int flags = IDN2_NFC_INPUT;
1614 #endif
1615       int rc = IDN2_LOOKUP(host->name, &ace_hostname, flags);
1616       if(rc != IDN2_OK)
1617         /* fallback to TR46 Transitional mode for better IDNA2003
1618            compatibility */
1619         rc = IDN2_LOOKUP(host->name, &ace_hostname,
1620                          IDN2_TRANSITIONAL);
1621       if(rc == IDN2_OK) {
1622         host->encalloc = (char *)ace_hostname;
1623         /* change the name pointer to point to the encoded hostname */
1624         host->name = host->encalloc;
1625       }
1626       else {
1627         failf(data, "Failed to convert %s to ACE; %s", host->name,
1628               idn2_strerror(rc));
1629         return CURLE_URL_MALFORMAT;
1630       }
1631     }
1632 #elif defined(USE_WIN32_IDN)
1633     char *ace_hostname = NULL;
1634
1635     if(Curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
1636       host->encalloc = ace_hostname;
1637       /* change the name pointer to point to the encoded hostname */
1638       host->name = host->encalloc;
1639     }
1640     else {
1641       char buffer[STRERROR_LEN];
1642       failf(data, "Failed to convert %s to ACE; %s", host->name,
1643             Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
1644       return CURLE_URL_MALFORMAT;
1645     }
1646 #else
1647     infof(data, "IDN support not present, can't parse Unicode domains");
1648 #endif
1649   }
1650   return CURLE_OK;
1651 }
1652
1653 /*
1654  * Frees data allocated by idnconvert_hostname()
1655  */
1656 void Curl_free_idnconverted_hostname(struct hostname *host)
1657 {
1658 #if defined(USE_LIBIDN2)
1659   if(host->encalloc) {
1660     idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
1661                                  allocated by libidn */
1662     host->encalloc = NULL;
1663   }
1664 #elif defined(USE_WIN32_IDN)
1665   free(host->encalloc); /* must be freed with free() since this was
1666                            allocated by Curl_win32_idn_to_ascii */
1667   host->encalloc = NULL;
1668 #else
1669   (void)host;
1670 #endif
1671 }
1672
1673 /*
1674  * Allocate and initialize a new connectdata object.
1675  */
1676 static struct connectdata *allocate_conn(struct Curl_easy *data)
1677 {
1678   struct connectdata *conn = calloc(1, sizeof(struct connectdata));
1679   if(!conn)
1680     return NULL;
1681
1682 #ifdef USE_SSL
1683   /* The SSL backend-specific data (ssl_backend_data) objects are allocated as
1684      a separate array to ensure suitable alignment.
1685      Note that these backend pointers can be swapped by vtls (eg ssl backend
1686      data becomes proxy backend data). */
1687   {
1688     size_t onesize = Curl_ssl->sizeof_ssl_backend_data;
1689     size_t totalsize = onesize;
1690     char *ssl;
1691
1692 #ifndef CURL_DISABLE_FTP
1693     totalsize *= 2;
1694 #endif
1695 #ifndef CURL_DISABLE_PROXY
1696     totalsize *= 2;
1697 #endif
1698
1699     ssl = calloc(1, totalsize);
1700     if(!ssl) {
1701       free(conn);
1702       return NULL;
1703     }
1704     conn->ssl_extra = ssl;
1705     conn->ssl[FIRSTSOCKET].backend = (void *)ssl;
1706 #ifndef CURL_DISABLE_FTP
1707     ssl += onesize;
1708     conn->ssl[SECONDARYSOCKET].backend = (void *)ssl;
1709 #endif
1710 #ifndef CURL_DISABLE_PROXY
1711     ssl += onesize;
1712     conn->proxy_ssl[FIRSTSOCKET].backend = (void *)ssl;
1713 #ifndef CURL_DISABLE_FTP
1714     ssl += onesize;
1715     conn->proxy_ssl[SECONDARYSOCKET].backend = (void *)ssl;
1716 #endif
1717 #endif
1718   }
1719 #endif
1720
1721   conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
1722                                            already from start to avoid NULL
1723                                            situations and checks */
1724
1725   /* and we setup a few fields in case we end up actually using this struct */
1726
1727   conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
1728   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
1729   conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
1730   conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
1731   conn->connection_id = -1;    /* no ID */
1732   conn->port = -1; /* unknown at this point */
1733   conn->remote_port = -1; /* unknown at this point */
1734 #if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
1735   conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
1736   conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
1737 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */
1738
1739   /* Default protocol-independent behavior doesn't support persistent
1740      connections, so we set this to force-close. Protocols that support
1741      this need to set this to FALSE in their "curl_do" functions. */
1742   connclose(conn, "Default to force-close");
1743
1744   /* Store creation time to help future close decision making */
1745   conn->created = Curl_now();
1746
1747   /* Store current time to give a baseline to keepalive connection times. */
1748   conn->keepalive = Curl_now();
1749
1750 #ifndef CURL_DISABLE_PROXY
1751   conn->http_proxy.proxytype = data->set.proxytype;
1752   conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
1753
1754   /* note that these two proxy bits are now just on what looks to be
1755      requested, they may be altered down the road */
1756   conn->bits.proxy = (data->set.str[STRING_PROXY] &&
1757                       *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
1758   conn->bits.httpproxy = (conn->bits.proxy &&
1759                           (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
1760                            conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
1761                            conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
1762                            TRUE : FALSE;
1763   conn->bits.socksproxy = (conn->bits.proxy &&
1764                            !conn->bits.httpproxy) ? TRUE : FALSE;
1765
1766   if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) {
1767     conn->bits.proxy = TRUE;
1768     conn->bits.socksproxy = TRUE;
1769   }
1770
1771   conn->bits.proxy_user_passwd =
1772     (data->state.aptr.proxyuser) ? TRUE : FALSE;
1773   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
1774 #endif /* CURL_DISABLE_PROXY */
1775
1776 #ifndef CURL_DISABLE_FTP
1777   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
1778   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
1779 #endif
1780   conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
1781   conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
1782   conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
1783   conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options;
1784 #ifndef CURL_DISABLE_PROXY
1785   conn->proxy_ssl_config.verifystatus =
1786     data->set.proxy_ssl.primary.verifystatus;
1787   conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
1788   conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
1789   conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options;
1790 #endif
1791   conn->ip_version = data->set.ipver;
1792   conn->connect_only = data->set.connect_only;
1793   conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
1794
1795 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
1796     defined(NTLM_WB_ENABLED)
1797   conn->ntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
1798   conn->proxyntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
1799 #endif
1800
1801   /* Initialize the easy handle list */
1802   Curl_llist_init(&conn->easyq, NULL);
1803
1804 #ifdef HAVE_GSSAPI
1805   conn->data_prot = PROT_CLEAR;
1806 #endif
1807
1808   /* Store the local bind parameters that will be used for this connection */
1809   if(data->set.str[STRING_DEVICE]) {
1810     conn->localdev = strdup(data->set.str[STRING_DEVICE]);
1811     if(!conn->localdev)
1812       goto error;
1813   }
1814   conn->localportrange = data->set.localportrange;
1815   conn->localport = data->set.localport;
1816
1817   /* the close socket stuff needs to be copied to the connection struct as
1818      it may live on without (this specific) Curl_easy */
1819   conn->fclosesocket = data->set.fclosesocket;
1820   conn->closesocket_client = data->set.closesocket_client;
1821   conn->lastused = Curl_now(); /* used now */
1822
1823   return conn;
1824   error:
1825
1826   Curl_llist_destroy(&conn->easyq, NULL);
1827   free(conn->localdev);
1828 #ifdef USE_SSL
1829   free(conn->ssl_extra);
1830 #endif
1831   free(conn);
1832   return NULL;
1833 }
1834
1835 /* returns the handler if the given scheme is built-in */
1836 const struct Curl_handler *Curl_builtin_scheme(const char *scheme,
1837                                                size_t schemelen)
1838 {
1839   const struct Curl_handler * const *pp;
1840   const struct Curl_handler *p;
1841   /* Scan protocol handler table and match against 'scheme'. The handler may
1842      be changed later when the protocol specific setup function is called. */
1843   if(schemelen == CURL_ZERO_TERMINATED)
1844     schemelen = strlen(scheme);
1845   for(pp = protocols; (p = *pp) != NULL; pp++)
1846     if(strncasecompare(p->scheme, scheme, schemelen) && !p->scheme[schemelen])
1847       /* Protocol found in table. */
1848       return p;
1849   return NULL; /* not found */
1850 }
1851
1852
1853 static CURLcode findprotocol(struct Curl_easy *data,
1854                              struct connectdata *conn,
1855                              const char *protostr)
1856 {
1857   const struct Curl_handler *p = Curl_builtin_scheme(protostr,
1858                                                      CURL_ZERO_TERMINATED);
1859
1860   if(p && /* Protocol found in table. Check if allowed */
1861      (data->set.allowed_protocols & p->protocol)) {
1862
1863     /* it is allowed for "normal" request, now do an extra check if this is
1864        the result of a redirect */
1865     if(data->state.this_is_a_follow &&
1866        !(data->set.redir_protocols & p->protocol))
1867       /* nope, get out */
1868       ;
1869     else {
1870       /* Perform setup complement if some. */
1871       conn->handler = conn->given = p;
1872
1873       /* 'port' and 'remote_port' are set in setup_connection_internals() */
1874       return CURLE_OK;
1875     }
1876   }
1877
1878   /* The protocol was not found in the table, but we don't have to assign it
1879      to anything since it is already assigned to a dummy-struct in the
1880      create_conn() function when the connectdata struct is allocated. */
1881   failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
1882         protostr);
1883
1884   return CURLE_UNSUPPORTED_PROTOCOL;
1885 }
1886
1887
1888 CURLcode Curl_uc_to_curlcode(CURLUcode uc)
1889 {
1890   switch(uc) {
1891   default:
1892     return CURLE_URL_MALFORMAT;
1893   case CURLUE_UNSUPPORTED_SCHEME:
1894     return CURLE_UNSUPPORTED_PROTOCOL;
1895   case CURLUE_OUT_OF_MEMORY:
1896     return CURLE_OUT_OF_MEMORY;
1897   case CURLUE_USER_NOT_ALLOWED:
1898     return CURLE_LOGIN_DENIED;
1899   }
1900 }
1901
1902 #ifdef ENABLE_IPV6
1903 /*
1904  * If the URL was set with an IPv6 numerical address with a zone id part, set
1905  * the scope_id based on that!
1906  */
1907
1908 static void zonefrom_url(CURLU *uh, struct Curl_easy *data,
1909                          struct connectdata *conn)
1910 {
1911   char *zoneid;
1912   CURLUcode uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
1913 #ifdef CURL_DISABLE_VERBOSE_STRINGS
1914   (void)data;
1915 #endif
1916
1917   if(!uc && zoneid) {
1918     char *endp;
1919     unsigned long scope = strtoul(zoneid, &endp, 10);
1920     if(!*endp && (scope < UINT_MAX))
1921       /* A plain number, use it directly as a scope id. */
1922       conn->scope_id = (unsigned int)scope;
1923 #if defined(HAVE_IF_NAMETOINDEX)
1924     else {
1925 #elif defined(WIN32)
1926     else if(Curl_if_nametoindex) {
1927 #endif
1928
1929 #if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32)
1930       /* Zone identifier is not numeric */
1931       unsigned int scopeidx = 0;
1932 #if defined(WIN32)
1933       scopeidx = Curl_if_nametoindex(zoneid);
1934 #else
1935       scopeidx = if_nametoindex(zoneid);
1936 #endif
1937       if(!scopeidx) {
1938 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1939         char buffer[STRERROR_LEN];
1940         infof(data, "Invalid zoneid: %s; %s", zoneid,
1941               Curl_strerror(errno, buffer, sizeof(buffer)));
1942 #endif
1943       }
1944       else
1945         conn->scope_id = scopeidx;
1946     }
1947 #endif /* HAVE_IF_NAMETOINDEX || WIN32 */
1948
1949     free(zoneid);
1950   }
1951 }
1952 #else
1953 #define zonefrom_url(a,b,c) Curl_nop_stmt
1954 #endif
1955
1956 /*
1957  * Parse URL and fill in the relevant members of the connection struct.
1958  */
1959 static CURLcode parseurlandfillconn(struct Curl_easy *data,
1960                                     struct connectdata *conn)
1961 {
1962   CURLcode result;
1963   CURLU *uh;
1964   CURLUcode uc;
1965   char *hostname;
1966   bool use_set_uh = (data->set.uh && !data->state.this_is_a_follow);
1967
1968   up_free(data); /* cleanup previous leftovers first */
1969
1970   /* parse the URL */
1971   if(use_set_uh) {
1972     uh = data->state.uh = curl_url_dup(data->set.uh);
1973   }
1974   else {
1975     uh = data->state.uh = curl_url();
1976   }
1977
1978   if(!uh)
1979     return CURLE_OUT_OF_MEMORY;
1980
1981   if(data->set.str[STRING_DEFAULT_PROTOCOL] &&
1982      !Curl_is_absolute_url(data->state.url, NULL, 0, TRUE)) {
1983     char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL],
1984                         data->state.url);
1985     if(!url)
1986       return CURLE_OUT_OF_MEMORY;
1987     if(data->state.url_alloc)
1988       free(data->state.url);
1989     data->state.url = url;
1990     data->state.url_alloc = TRUE;
1991   }
1992
1993   if(!use_set_uh) {
1994     char *newurl;
1995     uc = curl_url_set(uh, CURLUPART_URL, data->state.url,
1996                     CURLU_GUESS_SCHEME |
1997                     CURLU_NON_SUPPORT_SCHEME |
1998                     (data->set.disallow_username_in_url ?
1999                      CURLU_DISALLOW_USER : 0) |
2000                     (data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
2001     if(uc) {
2002       DEBUGF(infof(data, "curl_url_set rejected %s: %s", data->state.url,
2003                    curl_url_strerror(uc)));
2004       return Curl_uc_to_curlcode(uc);
2005     }
2006
2007     /* after it was parsed, get the generated normalized version */
2008     uc = curl_url_get(uh, CURLUPART_URL, &newurl, 0);
2009     if(uc)
2010       return Curl_uc_to_curlcode(uc);
2011     if(data->state.url_alloc)
2012       free(data->state.url);
2013     data->state.url = newurl;
2014     data->state.url_alloc = TRUE;
2015   }
2016
2017   uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
2018   if(uc)
2019     return Curl_uc_to_curlcode(uc);
2020
2021   uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0);
2022   if(uc) {
2023     if(!strcasecompare("file", data->state.up.scheme))
2024       return CURLE_OUT_OF_MEMORY;
2025   }
2026   else if(strlen(data->state.up.hostname) > MAX_URL_LEN) {
2027     failf(data, "Too long host name (maximum is %d)", MAX_URL_LEN);
2028     return CURLE_URL_MALFORMAT;
2029   }
2030   hostname = data->state.up.hostname;
2031
2032   if(hostname && hostname[0] == '[') {
2033     /* This looks like an IPv6 address literal. See if there is an address
2034        scope. */
2035     size_t hlen;
2036     conn->bits.ipv6_ip = TRUE;
2037     /* cut off the brackets! */
2038     hostname++;
2039     hlen = strlen(hostname);
2040     hostname[hlen - 1] = 0;
2041
2042     zonefrom_url(uh, data, conn);
2043   }
2044
2045   /* make sure the connect struct gets its own copy of the host name */
2046   conn->host.rawalloc = strdup(hostname ? hostname : "");
2047   if(!conn->host.rawalloc)
2048     return CURLE_OUT_OF_MEMORY;
2049   conn->host.name = conn->host.rawalloc;
2050
2051   /*************************************************************
2052    * IDN-convert the hostnames
2053    *************************************************************/
2054   result = Curl_idnconvert_hostname(data, &conn->host);
2055   if(result)
2056     return result;
2057   if(conn->bits.conn_to_host) {
2058     result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
2059     if(result)
2060       return result;
2061   }
2062 #ifndef CURL_DISABLE_PROXY
2063   if(conn->bits.httpproxy) {
2064     result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
2065     if(result)
2066       return result;
2067   }
2068   if(conn->bits.socksproxy) {
2069     result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
2070     if(result)
2071       return result;
2072   }
2073 #endif
2074
2075 #ifndef CURL_DISABLE_HSTS
2076   /* HSTS upgrade */
2077   if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
2078     /* This MUST use the IDN decoded name */
2079     if(Curl_hsts(data->hsts, conn->host.name, TRUE)) {
2080       char *url;
2081       Curl_safefree(data->state.up.scheme);
2082       uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
2083       if(uc)
2084         return Curl_uc_to_curlcode(uc);
2085       if(data->state.url_alloc)
2086         Curl_safefree(data->state.url);
2087       /* after update, get the updated version */
2088       uc = curl_url_get(uh, CURLUPART_URL, &url, 0);
2089       if(uc)
2090         return Curl_uc_to_curlcode(uc);
2091       uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
2092       if(uc) {
2093         free(url);
2094         return Curl_uc_to_curlcode(uc);
2095       }
2096       data->state.url = url;
2097       data->state.url_alloc = TRUE;
2098       infof(data, "Switched from HTTP to HTTPS due to HSTS => %s",
2099             data->state.url);
2100     }
2101   }
2102 #endif
2103
2104   result = findprotocol(data, conn, data->state.up.scheme);
2105   if(result)
2106     return result;
2107
2108   /*
2109    * User name and password set with their own options override the
2110    * credentials possibly set in the URL.
2111    */
2112   if(!data->state.aptr.passwd) {
2113     uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
2114     if(!uc) {
2115       char *decoded;
2116       result = Curl_urldecode(data->state.up.password, 0, &decoded, NULL,
2117                               conn->handler->flags&PROTOPT_USERPWDCTRL ?
2118                               REJECT_ZERO : REJECT_CTRL);
2119       if(result)
2120         return result;
2121       conn->passwd = decoded;
2122       result = Curl_setstropt(&data->state.aptr.passwd, decoded);
2123       if(result)
2124         return result;
2125     }
2126     else if(uc != CURLUE_NO_PASSWORD)
2127       return Curl_uc_to_curlcode(uc);
2128   }
2129
2130   if(!data->set.str[STRING_USERNAME]) {
2131     /* we don't use the URL API's URL decoder option here since it rejects
2132        control codes and we want to allow them for some schemes in the user
2133        and password fields */
2134     uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
2135     if(!uc) {
2136       char *decoded;
2137       result = Curl_urldecode(data->state.up.user, 0, &decoded, NULL,
2138                               conn->handler->flags&PROTOPT_USERPWDCTRL ?
2139                               REJECT_ZERO : REJECT_CTRL);
2140       if(result)
2141         return result;
2142       conn->user = decoded;
2143       result = Curl_setstropt(&data->state.aptr.user, decoded);
2144     }
2145     else if(uc != CURLUE_NO_USER)
2146       return Curl_uc_to_curlcode(uc);
2147     else if(data->state.aptr.passwd) {
2148       /* no user was set but a password, set a blank user */
2149       result = Curl_setstropt(&data->state.aptr.user, "");
2150     }
2151     if(result)
2152       return result;
2153   }
2154
2155   uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options,
2156                     CURLU_URLDECODE);
2157   if(!uc) {
2158     conn->options = strdup(data->state.up.options);
2159     if(!conn->options)
2160       return CURLE_OUT_OF_MEMORY;
2161   }
2162   else if(uc != CURLUE_NO_OPTIONS)
2163     return Curl_uc_to_curlcode(uc);
2164
2165   uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path,
2166                     CURLU_URLENCODE);
2167   if(uc)
2168     return Curl_uc_to_curlcode(uc);
2169
2170   uc = curl_url_get(uh, CURLUPART_PORT, &data->state.up.port,
2171                     CURLU_DEFAULT_PORT);
2172   if(uc) {
2173     if(!strcasecompare("file", data->state.up.scheme))
2174       return CURLE_OUT_OF_MEMORY;
2175   }
2176   else {
2177     unsigned long port = strtoul(data->state.up.port, NULL, 10);
2178     conn->port = conn->remote_port =
2179       (data->set.use_port && data->state.allow_port) ?
2180       data->set.use_port : curlx_ultous(port);
2181   }
2182
2183   (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
2184
2185 #ifdef ENABLE_IPV6
2186   if(data->set.scope_id)
2187     /* Override any scope that was set above.  */
2188     conn->scope_id = data->set.scope_id;
2189 #endif
2190
2191   return CURLE_OK;
2192 }
2193
2194
2195 /*
2196  * If we're doing a resumed transfer, we need to setup our stuff
2197  * properly.
2198  */
2199 static CURLcode setup_range(struct Curl_easy *data)
2200 {
2201   struct UrlState *s = &data->state;
2202   s->resume_from = data->set.set_resume_from;
2203   if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
2204     if(s->rangestringalloc)
2205       free(s->range);
2206
2207     if(s->resume_from)
2208       s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from);
2209     else
2210       s->range = strdup(data->set.str[STRING_SET_RANGE]);
2211
2212     s->rangestringalloc = (s->range) ? TRUE : FALSE;
2213
2214     if(!s->range)
2215       return CURLE_OUT_OF_MEMORY;
2216
2217     /* tell ourselves to fetch this range */
2218     s->use_range = TRUE;        /* enable range download */
2219   }
2220   else
2221     s->use_range = FALSE; /* disable range download */
2222
2223   return CURLE_OK;
2224 }
2225
2226
2227 /*
2228  * setup_connection_internals() -
2229  *
2230  * Setup connection internals specific to the requested protocol in the
2231  * Curl_easy. This is inited and setup before the connection is made but
2232  * is about the particular protocol that is to be used.
2233  *
2234  * This MUST get called after proxy magic has been figured out.
2235  */
2236 static CURLcode setup_connection_internals(struct Curl_easy *data,
2237                                            struct connectdata *conn)
2238 {
2239   const struct Curl_handler *p;
2240   CURLcode result;
2241
2242   /* Perform setup complement if some. */
2243   p = conn->handler;
2244
2245   if(p->setup_connection) {
2246     result = (*p->setup_connection)(data, conn);
2247
2248     if(result)
2249       return result;
2250
2251     p = conn->handler;              /* May have changed. */
2252   }
2253
2254   if(conn->port < 0)
2255     /* we check for -1 here since if proxy was detected already, this
2256        was very likely already set to the proxy port */
2257     conn->port = p->defport;
2258
2259   return CURLE_OK;
2260 }
2261
2262 /*
2263  * Curl_free_request_state() should free temp data that was allocated in the
2264  * Curl_easy for this single request.
2265  */
2266
2267 void Curl_free_request_state(struct Curl_easy *data)
2268 {
2269   Curl_safefree(data->req.p.http);
2270   Curl_safefree(data->req.newurl);
2271
2272 #ifndef CURL_DISABLE_DOH
2273   if(data->req.doh) {
2274     Curl_close(&data->req.doh->probe[0].easy);
2275     Curl_close(&data->req.doh->probe[1].easy);
2276   }
2277 #endif
2278 }
2279
2280
2281 #ifndef CURL_DISABLE_PROXY
2282
2283 #ifndef CURL_DISABLE_HTTP
2284 /****************************************************************
2285 * Detect what (if any) proxy to use. Remember that this selects a host
2286 * name and is not limited to HTTP proxies only.
2287 * The returned pointer must be freed by the caller (unless NULL)
2288 ****************************************************************/
2289 static char *detect_proxy(struct Curl_easy *data,
2290                           struct connectdata *conn)
2291 {
2292   char *proxy = NULL;
2293
2294   /* If proxy was not specified, we check for default proxy environment
2295    * variables, to enable i.e Lynx compliance:
2296    *
2297    * http_proxy=http://some.server.dom:port/
2298    * https_proxy=http://some.server.dom:port/
2299    * ftp_proxy=http://some.server.dom:port/
2300    * no_proxy=domain1.dom,host.domain2.dom
2301    *   (a comma-separated list of hosts which should
2302    *   not be proxied, or an asterisk to override
2303    *   all proxy variables)
2304    * all_proxy=http://some.server.dom:port/
2305    *   (seems to exist for the CERN www lib. Probably
2306    *   the first to check for.)
2307    *
2308    * For compatibility, the all-uppercase versions of these variables are
2309    * checked if the lowercase versions don't exist.
2310    */
2311   char proxy_env[128];
2312   const char *protop = conn->handler->scheme;
2313   char *envp = proxy_env;
2314   char *prox;
2315 #ifdef CURL_DISABLE_VERBOSE_STRINGS
2316   (void)data;
2317 #endif
2318
2319   /* Now, build <protocol>_proxy and check for such a one to use */
2320   while(*protop)
2321     *envp++ = Curl_raw_tolower(*protop++);
2322
2323   /* append _proxy */
2324   strcpy(envp, "_proxy");
2325
2326   /* read the protocol proxy: */
2327   prox = curl_getenv(proxy_env);
2328
2329   /*
2330    * We don't try the uppercase version of HTTP_PROXY because of
2331    * security reasons:
2332    *
2333    * When curl is used in a webserver application
2334    * environment (cgi or php), this environment variable can
2335    * be controlled by the web server user by setting the
2336    * http header 'Proxy:' to some value.
2337    *
2338    * This can cause 'internal' http/ftp requests to be
2339    * arbitrarily redirected by any external attacker.
2340    */
2341   if(!prox && !strcasecompare("http_proxy", proxy_env)) {
2342     /* There was no lowercase variable, try the uppercase version: */
2343     Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
2344     prox = curl_getenv(proxy_env);
2345   }
2346
2347   envp = proxy_env;
2348   if(prox) {
2349     proxy = prox; /* use this */
2350   }
2351   else {
2352     envp = (char *)"all_proxy";
2353     proxy = curl_getenv(envp); /* default proxy to use */
2354     if(!proxy) {
2355       envp = (char *)"ALL_PROXY";
2356       proxy = curl_getenv(envp);
2357     }
2358   }
2359   if(proxy)
2360     infof(data, "Uses proxy env variable %s == '%s'", envp, proxy);
2361
2362   return proxy;
2363 }
2364 #endif /* CURL_DISABLE_HTTP */
2365
2366 /*
2367  * If this is supposed to use a proxy, we need to figure out the proxy
2368  * host name, so that we can re-use an existing connection
2369  * that may exist registered to the same proxy host.
2370  */
2371 static CURLcode parse_proxy(struct Curl_easy *data,
2372                             struct connectdata *conn, char *proxy,
2373                             curl_proxytype proxytype)
2374 {
2375   char *portptr = NULL;
2376   int port = -1;
2377   char *proxyuser = NULL;
2378   char *proxypasswd = NULL;
2379   char *host = NULL;
2380   bool sockstype;
2381   CURLUcode uc;
2382   struct proxy_info *proxyinfo;
2383   CURLU *uhp = curl_url();
2384   CURLcode result = CURLE_OK;
2385   char *scheme = NULL;
2386 #ifdef USE_UNIX_SOCKETS
2387   char *path = NULL;
2388   bool is_unix_proxy = FALSE;
2389 #endif
2390
2391
2392   if(!uhp) {
2393     result = CURLE_OUT_OF_MEMORY;
2394     goto error;
2395   }
2396
2397   /* When parsing the proxy, allowing non-supported schemes since we have
2398      these made up ones for proxies. Guess scheme for URLs without it. */
2399   uc = curl_url_set(uhp, CURLUPART_URL, proxy,
2400                     CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME);
2401   if(!uc) {
2402     /* parsed okay as a URL */
2403     uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0);
2404     if(uc) {
2405       result = CURLE_OUT_OF_MEMORY;
2406       goto error;
2407     }
2408
2409     if(strcasecompare("https", scheme))
2410       proxytype = CURLPROXY_HTTPS;
2411     else if(strcasecompare("socks5h", scheme))
2412       proxytype = CURLPROXY_SOCKS5_HOSTNAME;
2413     else if(strcasecompare("socks5", scheme))
2414       proxytype = CURLPROXY_SOCKS5;
2415     else if(strcasecompare("socks4a", scheme))
2416       proxytype = CURLPROXY_SOCKS4A;
2417     else if(strcasecompare("socks4", scheme) ||
2418             strcasecompare("socks", scheme))
2419       proxytype = CURLPROXY_SOCKS4;
2420     else if(strcasecompare("http", scheme))
2421       ; /* leave it as HTTP or HTTP/1.0 */
2422     else {
2423       /* Any other xxx:// reject! */
2424       failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
2425       result = CURLE_COULDNT_CONNECT;
2426       goto error;
2427     }
2428   }
2429   else {
2430     failf(data, "Unsupported proxy syntax in \'%s\'", proxy);
2431     result = CURLE_COULDNT_RESOLVE_PROXY;
2432     goto error;
2433   }
2434
2435 #ifdef USE_SSL
2436   if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY))
2437 #endif
2438     if(proxytype == CURLPROXY_HTTPS) {
2439       failf(data, "Unsupported proxy \'%s\', libcurl is built without the "
2440                   "HTTPS-proxy support.", proxy);
2441       result = CURLE_NOT_BUILT_IN;
2442       goto error;
2443     }
2444
2445   sockstype =
2446     proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
2447     proxytype == CURLPROXY_SOCKS5 ||
2448     proxytype == CURLPROXY_SOCKS4A ||
2449     proxytype == CURLPROXY_SOCKS4;
2450
2451   proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy;
2452   proxyinfo->proxytype = proxytype;
2453
2454   /* Is there a username and password given in this proxy url? */
2455   uc = curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE);
2456   if(uc && (uc != CURLUE_NO_USER))
2457     goto error;
2458   uc = curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE);
2459   if(uc && (uc != CURLUE_NO_PASSWORD))
2460     goto error;
2461
2462   if(proxyuser || proxypasswd) {
2463     Curl_safefree(proxyinfo->user);
2464     proxyinfo->user = proxyuser;
2465     result = Curl_setstropt(&data->state.aptr.proxyuser, proxyuser);
2466     proxyuser = NULL;
2467     if(result)
2468       goto error;
2469     Curl_safefree(proxyinfo->passwd);
2470     if(!proxypasswd) {
2471       proxypasswd = strdup("");
2472       if(!proxypasswd) {
2473         result = CURLE_OUT_OF_MEMORY;
2474         goto error;
2475       }
2476     }
2477     proxyinfo->passwd = proxypasswd;
2478     result = Curl_setstropt(&data->state.aptr.proxypasswd, proxypasswd);
2479     proxypasswd = NULL;
2480     if(result)
2481       goto error;
2482     conn->bits.proxy_user_passwd = TRUE; /* enable it */
2483   }
2484
2485   (void)curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
2486
2487   if(portptr) {
2488     port = (int)strtol(portptr, NULL, 10);
2489     free(portptr);
2490   }
2491   else {
2492     if(data->set.proxyport)
2493       /* None given in the proxy string, then get the default one if it is
2494          given */
2495       port = (int)data->set.proxyport;
2496     else {
2497       if(proxytype == CURLPROXY_HTTPS)
2498         port = CURL_DEFAULT_HTTPS_PROXY_PORT;
2499       else
2500         port = CURL_DEFAULT_PROXY_PORT;
2501     }
2502   }
2503   if(port >= 0) {
2504     proxyinfo->port = port;
2505     if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
2506       conn->port = port;
2507   }
2508
2509   /* now, clone the proxy host name */
2510   uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE);
2511   if(uc) {
2512     result = CURLE_OUT_OF_MEMORY;
2513     goto error;
2514   }
2515 #ifdef USE_UNIX_SOCKETS
2516   if(sockstype && strcasecompare(UNIX_SOCKET_PREFIX, host)) {
2517     uc = curl_url_get(uhp, CURLUPART_PATH, &path, CURLU_URLDECODE);
2518     if(uc) {
2519       result = CURLE_OUT_OF_MEMORY;
2520       goto error;
2521     }
2522     /* path will be "/", if no path was was found */
2523     if(strcmp("/", path)) {
2524       is_unix_proxy = TRUE;
2525       free(host);
2526       host = aprintf(UNIX_SOCKET_PREFIX"%s", path);
2527       if(!host) {
2528         result = CURLE_OUT_OF_MEMORY;
2529         goto error;
2530       }
2531       Curl_safefree(proxyinfo->host.rawalloc);
2532       proxyinfo->host.rawalloc = host;
2533       proxyinfo->host.name = host;
2534       host = NULL;
2535     }
2536   }
2537
2538   if(!is_unix_proxy) {
2539 #endif
2540     Curl_safefree(proxyinfo->host.rawalloc);
2541     proxyinfo->host.rawalloc = host;
2542     if(host[0] == '[') {
2543       /* this is a numerical IPv6, strip off the brackets */
2544       size_t len = strlen(host);
2545       host[len-1] = 0; /* clear the trailing bracket */
2546       host++;
2547       zonefrom_url(uhp, data, conn);
2548     }
2549     proxyinfo->host.name = host;
2550     host = NULL;
2551 #ifdef USE_UNIX_SOCKETS
2552   }
2553 #endif
2554
2555   error:
2556   free(proxyuser);
2557   free(proxypasswd);
2558   free(host);
2559   free(scheme);
2560 #ifdef USE_UNIX_SOCKETS
2561   free(path);
2562 #endif
2563   curl_url_cleanup(uhp);
2564   return result;
2565 }
2566
2567 /*
2568  * Extract the user and password from the authentication string
2569  */
2570 static CURLcode parse_proxy_auth(struct Curl_easy *data,
2571                                  struct connectdata *conn)
2572 {
2573   const char *proxyuser = data->state.aptr.proxyuser ?
2574     data->state.aptr.proxyuser : "";
2575   const char *proxypasswd = data->state.aptr.proxypasswd ?
2576     data->state.aptr.proxypasswd : "";
2577   CURLcode result = CURLE_OK;
2578
2579   if(proxyuser) {
2580     result = Curl_urldecode(proxyuser, 0, &conn->http_proxy.user, NULL,
2581                             REJECT_ZERO);
2582     if(!result)
2583       result = Curl_setstropt(&data->state.aptr.proxyuser,
2584                               conn->http_proxy.user);
2585   }
2586   if(!result && proxypasswd) {
2587     result = Curl_urldecode(proxypasswd, 0, &conn->http_proxy.passwd,
2588                             NULL, REJECT_ZERO);
2589     if(!result)
2590       result = Curl_setstropt(&data->state.aptr.proxypasswd,
2591                               conn->http_proxy.passwd);
2592   }
2593   return result;
2594 }
2595
2596 /* create_conn helper to parse and init proxy values. to be called after unix
2597    socket init but before any proxy vars are evaluated. */
2598 static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
2599                                               struct connectdata *conn)
2600 {
2601   char *proxy = NULL;
2602   char *socksproxy = NULL;
2603   char *no_proxy = NULL;
2604   CURLcode result = CURLE_OK;
2605
2606   /*************************************************************
2607    * Extract the user and password from the authentication string
2608    *************************************************************/
2609   if(conn->bits.proxy_user_passwd) {
2610     result = parse_proxy_auth(data, conn);
2611     if(result)
2612       goto out;
2613   }
2614
2615   /*************************************************************
2616    * Detect what (if any) proxy to use
2617    *************************************************************/
2618   if(data->set.str[STRING_PROXY]) {
2619     proxy = strdup(data->set.str[STRING_PROXY]);
2620     /* if global proxy is set, this is it */
2621     if(!proxy) {
2622       failf(data, "memory shortage");
2623       result = CURLE_OUT_OF_MEMORY;
2624       goto out;
2625     }
2626   }
2627
2628   if(data->set.str[STRING_PRE_PROXY]) {
2629     socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
2630     /* if global socks proxy is set, this is it */
2631     if(!socksproxy) {
2632       failf(data, "memory shortage");
2633       result = CURLE_OUT_OF_MEMORY;
2634       goto out;
2635     }
2636   }
2637
2638   if(!data->set.str[STRING_NOPROXY]) {
2639     const char *p = "no_proxy";
2640     no_proxy = curl_getenv(p);
2641     if(!no_proxy) {
2642       p = "NO_PROXY";
2643       no_proxy = curl_getenv(p);
2644     }
2645     if(no_proxy) {
2646       infof(data, "Uses proxy env variable %s == '%s'", p, no_proxy);
2647     }
2648   }
2649
2650   if(Curl_check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ?
2651                         data->set.str[STRING_NOPROXY] : no_proxy)) {
2652     Curl_safefree(proxy);
2653     Curl_safefree(socksproxy);
2654   }
2655 #ifndef CURL_DISABLE_HTTP
2656   else if(!proxy && !socksproxy)
2657     /* if the host is not in the noproxy list, detect proxy. */
2658     proxy = detect_proxy(data, conn);
2659 #endif /* CURL_DISABLE_HTTP */
2660
2661   Curl_safefree(no_proxy);
2662
2663 #ifdef USE_UNIX_SOCKETS
2664   /* For the time being do not mix proxy and unix domain sockets. See #1274 */
2665   if(proxy && conn->unix_domain_socket) {
2666     free(proxy);
2667     proxy = NULL;
2668   }
2669 #endif
2670
2671   if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
2672     free(proxy);  /* Don't bother with an empty proxy string or if the
2673                      protocol doesn't work with network */
2674     proxy = NULL;
2675   }
2676   if(socksproxy && (!*socksproxy ||
2677                     (conn->handler->flags & PROTOPT_NONETWORK))) {
2678     free(socksproxy);  /* Don't bother with an empty socks proxy string or if
2679                           the protocol doesn't work with network */
2680     socksproxy = NULL;
2681   }
2682
2683   /***********************************************************************
2684    * If this is supposed to use a proxy, we need to figure out the proxy host
2685    * name, proxy type and port number, so that we can re-use an existing
2686    * connection that may exist registered to the same proxy host.
2687    ***********************************************************************/
2688   if(proxy || socksproxy) {
2689     curl_proxytype ptype = (curl_proxytype)conn->http_proxy.proxytype;
2690     if(proxy) {
2691       result = parse_proxy(data, conn, proxy, ptype);
2692       Curl_safefree(proxy); /* parse_proxy copies the proxy string */
2693       if(result)
2694         goto out;
2695     }
2696
2697     if(socksproxy) {
2698       result = parse_proxy(data, conn, socksproxy, ptype);
2699       /* parse_proxy copies the socks proxy string */
2700       Curl_safefree(socksproxy);
2701       if(result)
2702         goto out;
2703     }
2704
2705     if(conn->http_proxy.host.rawalloc) {
2706 #ifdef CURL_DISABLE_HTTP
2707       /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
2708       result = CURLE_UNSUPPORTED_PROTOCOL;
2709       goto out;
2710 #else
2711       /* force this connection's protocol to become HTTP if compatible */
2712       if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) {
2713         if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) &&
2714            !conn->bits.tunnel_proxy)
2715           conn->handler = &Curl_handler_http;
2716         else
2717           /* if not converting to HTTP over the proxy, enforce tunneling */
2718           conn->bits.tunnel_proxy = TRUE;
2719       }
2720       conn->bits.httpproxy = TRUE;
2721 #endif
2722     }
2723     else {
2724       conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
2725       conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
2726     }
2727
2728     if(conn->socks_proxy.host.rawalloc) {
2729       if(!conn->http_proxy.host.rawalloc) {
2730         /* once a socks proxy */
2731         if(!conn->socks_proxy.user) {
2732           conn->socks_proxy.user = conn->http_proxy.user;
2733           conn->http_proxy.user = NULL;
2734           Curl_safefree(conn->socks_proxy.passwd);
2735           conn->socks_proxy.passwd = conn->http_proxy.passwd;
2736           conn->http_proxy.passwd = NULL;
2737         }
2738       }
2739       conn->bits.socksproxy = TRUE;
2740     }
2741     else
2742       conn->bits.socksproxy = FALSE; /* not a socks proxy */
2743   }
2744   else {
2745     conn->bits.socksproxy = FALSE;
2746     conn->bits.httpproxy = FALSE;
2747   }
2748   conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
2749
2750   if(!conn->bits.proxy) {
2751     /* we aren't using the proxy after all... */
2752     conn->bits.proxy = FALSE;
2753     conn->bits.httpproxy = FALSE;
2754     conn->bits.socksproxy = FALSE;
2755     conn->bits.proxy_user_passwd = FALSE;
2756     conn->bits.tunnel_proxy = FALSE;
2757     /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need
2758        to signal that CURLPROXY_HTTPS is not used for this connection */
2759     conn->http_proxy.proxytype = CURLPROXY_HTTP;
2760   }
2761
2762 out:
2763
2764   free(socksproxy);
2765   free(proxy);
2766   return result;
2767 }
2768 #endif /* CURL_DISABLE_PROXY */
2769
2770 /*
2771  * Curl_parse_login_details()
2772  *
2773  * This is used to parse a login string for user name, password and options in
2774  * the following formats:
2775  *
2776  *   user
2777  *   user:password
2778  *   user:password;options
2779  *   user;options
2780  *   user;options:password
2781  *   :password
2782  *   :password;options
2783  *   ;options
2784  *   ;options:password
2785  *
2786  * Parameters:
2787  *
2788  * login    [in]     - The login string.
2789  * len      [in]     - The length of the login string.
2790  * userp    [in/out] - The address where a pointer to newly allocated memory
2791  *                     holding the user will be stored upon completion.
2792  * passwdp  [in/out] - The address where a pointer to newly allocated memory
2793  *                     holding the password will be stored upon completion.
2794  * optionsp [in/out] - The address where a pointer to newly allocated memory
2795  *                     holding the options will be stored upon completion.
2796  *
2797  * Returns CURLE_OK on success.
2798  */
2799 CURLcode Curl_parse_login_details(const char *login, const size_t len,
2800                                   char **userp, char **passwdp,
2801                                   char **optionsp)
2802 {
2803   CURLcode result = CURLE_OK;
2804   char *ubuf = NULL;
2805   char *pbuf = NULL;
2806   char *obuf = NULL;
2807   const char *psep = NULL;
2808   const char *osep = NULL;
2809   size_t ulen;
2810   size_t plen;
2811   size_t olen;
2812
2813   /* the input length check is because this is called directly from setopt
2814      and isn't going through the regular string length check */
2815   size_t llen = strlen(login);
2816   if(llen > CURL_MAX_INPUT_LENGTH)
2817     return CURLE_BAD_FUNCTION_ARGUMENT;
2818
2819   /* Attempt to find the password separator */
2820   if(passwdp) {
2821     psep = strchr(login, ':');
2822
2823     /* Within the constraint of the login string */
2824     if(psep >= login + len)
2825       psep = NULL;
2826   }
2827
2828   /* Attempt to find the options separator */
2829   if(optionsp) {
2830     osep = strchr(login, ';');
2831
2832     /* Within the constraint of the login string */
2833     if(osep >= login + len)
2834       osep = NULL;
2835   }
2836
2837   /* Calculate the portion lengths */
2838   ulen = (psep ?
2839           (size_t)(osep && psep > osep ? osep - login : psep - login) :
2840           (osep ? (size_t)(osep - login) : len));
2841   plen = (psep ?
2842           (osep && osep > psep ? (size_t)(osep - psep) :
2843                                  (size_t)(login + len - psep)) - 1 : 0);
2844   olen = (osep ?
2845           (psep && psep > osep ? (size_t)(psep - osep) :
2846                                  (size_t)(login + len - osep)) - 1 : 0);
2847
2848   /* Allocate the user portion buffer, which can be zero length */
2849   if(userp) {
2850     ubuf = malloc(ulen + 1);
2851     if(!ubuf)
2852       result = CURLE_OUT_OF_MEMORY;
2853   }
2854
2855   /* Allocate the password portion buffer */
2856   if(!result && passwdp && psep) {
2857     pbuf = malloc(plen + 1);
2858     if(!pbuf) {
2859       free(ubuf);
2860       result = CURLE_OUT_OF_MEMORY;
2861     }
2862   }
2863
2864   /* Allocate the options portion buffer */
2865   if(!result && optionsp && olen) {
2866     obuf = malloc(olen + 1);
2867     if(!obuf) {
2868       free(pbuf);
2869       free(ubuf);
2870       result = CURLE_OUT_OF_MEMORY;
2871     }
2872   }
2873
2874   if(!result) {
2875     /* Store the user portion if necessary */
2876     if(ubuf) {
2877       memcpy(ubuf, login, ulen);
2878       ubuf[ulen] = '\0';
2879       Curl_safefree(*userp);
2880       *userp = ubuf;
2881     }
2882
2883     /* Store the password portion if necessary */
2884     if(pbuf) {
2885       memcpy(pbuf, psep + 1, plen);
2886       pbuf[plen] = '\0';
2887       Curl_safefree(*passwdp);
2888       *passwdp = pbuf;
2889     }
2890
2891     /* Store the options portion if necessary */
2892     if(obuf) {
2893       memcpy(obuf, osep + 1, olen);
2894       obuf[olen] = '\0';
2895       Curl_safefree(*optionsp);
2896       *optionsp = obuf;
2897     }
2898   }
2899
2900   return result;
2901 }
2902
2903 /*************************************************************
2904  * Figure out the remote port number and fix it in the URL
2905  *
2906  * No matter if we use a proxy or not, we have to figure out the remote
2907  * port number of various reasons.
2908  *
2909  * The port number embedded in the URL is replaced, if necessary.
2910  *************************************************************/
2911 static CURLcode parse_remote_port(struct Curl_easy *data,
2912                                   struct connectdata *conn)
2913 {
2914
2915   if(data->set.use_port && data->state.allow_port) {
2916     /* if set, we use this instead of the port possibly given in the URL */
2917     char portbuf[16];
2918     CURLUcode uc;
2919     conn->remote_port = data->set.use_port;
2920     msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port);
2921     uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0);
2922     if(uc)
2923       return CURLE_OUT_OF_MEMORY;
2924   }
2925
2926   return CURLE_OK;
2927 }
2928
2929 /*
2930  * Override the login details from the URL with that in the CURLOPT_USERPWD
2931  * option or a .netrc file, if applicable.
2932  */
2933 static CURLcode override_login(struct Curl_easy *data,
2934                                struct connectdata *conn)
2935 {
2936   CURLUcode uc;
2937   char **userp = &conn->user;
2938   char **passwdp = &conn->passwd;
2939   char **optionsp = &conn->options;
2940
2941   if(data->set.str[STRING_OPTIONS]) {
2942     free(*optionsp);
2943     *optionsp = strdup(data->set.str[STRING_OPTIONS]);
2944     if(!*optionsp)
2945       return CURLE_OUT_OF_MEMORY;
2946   }
2947
2948 #ifndef CURL_DISABLE_NETRC
2949   if(data->set.use_netrc == CURL_NETRC_REQUIRED) {
2950     Curl_safefree(*userp);
2951     Curl_safefree(*passwdp);
2952   }
2953   conn->bits.netrc = FALSE;
2954   if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
2955     int ret;
2956     bool url_provided = FALSE;
2957
2958     if(data->state.aptr.user) {
2959       /* there was a user name in the URL. Use the URL decoded version */
2960       userp = &data->state.aptr.user;
2961       url_provided = TRUE;
2962     }
2963
2964     ret = Curl_parsenetrc(conn->host.name,
2965                           userp, passwdp,
2966                           data->set.str[STRING_NETRC_FILE]);
2967     if(ret > 0) {
2968       infof(data, "Couldn't find host %s in the %s file; using defaults",
2969             conn->host.name, data->set.str[STRING_NETRC_FILE]);
2970     }
2971     else if(ret < 0) {
2972       failf(data, ".netrc parser error");
2973       return CURLE_READ_ERROR;
2974     }
2975     else {
2976       /* set bits.netrc TRUE to remember that we got the name from a .netrc
2977          file, so that it is safe to use even if we followed a Location: to a
2978          different host or similar. */
2979       conn->bits.netrc = TRUE;
2980     }
2981     if(url_provided) {
2982       Curl_safefree(conn->user);
2983       conn->user = strdup(*userp);
2984       if(!conn->user)
2985         return CURLE_OUT_OF_MEMORY;
2986     }
2987     /* no user was set but a password, set a blank user */
2988     if(userp && !*userp && *passwdp) {
2989       *userp = strdup("");
2990       if(!*userp)
2991         return CURLE_OUT_OF_MEMORY;
2992     }
2993   }
2994 #endif
2995
2996   /* for updated strings, we update them in the URL */
2997   if(*userp) {
2998     CURLcode result;
2999     if(data->state.aptr.user != *userp) {
3000       /* nothing to do then */
3001       result = Curl_setstropt(&data->state.aptr.user, *userp);
3002       if(result)
3003         return result;
3004     }
3005   }
3006   if(data->state.aptr.user) {
3007     uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
3008                       CURLU_URLENCODE);
3009     if(uc)
3010       return Curl_uc_to_curlcode(uc);
3011     if(!*userp) {
3012       *userp = strdup(data->state.aptr.user);
3013       if(!*userp)
3014         return CURLE_OUT_OF_MEMORY;
3015     }
3016   }
3017   if(*passwdp) {
3018     CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
3019     if(result)
3020       return result;
3021   }
3022   if(data->state.aptr.passwd) {
3023     uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD,
3024                       data->state.aptr.passwd, CURLU_URLENCODE);
3025     if(uc)
3026       return Curl_uc_to_curlcode(uc);
3027     if(!*passwdp) {
3028       *passwdp = strdup(data->state.aptr.passwd);
3029       if(!*passwdp)
3030         return CURLE_OUT_OF_MEMORY;
3031     }
3032   }
3033
3034   return CURLE_OK;
3035 }
3036
3037 /*
3038  * Set the login details so they're available in the connection
3039  */
3040 static CURLcode set_login(struct Curl_easy *data,
3041                           struct connectdata *conn)
3042 {
3043   CURLcode result = CURLE_OK;
3044   const char *setuser = CURL_DEFAULT_USER;
3045   const char *setpasswd = CURL_DEFAULT_PASSWORD;
3046
3047   /* If our protocol needs a password and we have none, use the defaults */
3048   if((conn->handler->flags & PROTOPT_NEEDSPWD) && !data->state.aptr.user)
3049     ;
3050   else {
3051     setuser = "";
3052     setpasswd = "";
3053   }
3054   /* Store the default user */
3055   if(!conn->user) {
3056     conn->user = strdup(setuser);
3057     if(!conn->user)
3058       return CURLE_OUT_OF_MEMORY;
3059   }
3060
3061   /* Store the default password */
3062   if(!conn->passwd) {
3063     conn->passwd = strdup(setpasswd);
3064     if(!conn->passwd)
3065       result = CURLE_OUT_OF_MEMORY;
3066   }
3067
3068   return result;
3069 }
3070
3071 /*
3072  * Parses a "host:port" string to connect to.
3073  * The hostname and the port may be empty; in this case, NULL is returned for
3074  * the hostname and -1 for the port.
3075  */
3076 static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
3077                                            const char *host,
3078                                            char **hostname_result,
3079                                            int *port_result)
3080 {
3081   char *host_dup;
3082   char *hostptr;
3083   char *host_portno;
3084   char *portptr;
3085   int port = -1;
3086   CURLcode result = CURLE_OK;
3087
3088 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
3089   (void) data;
3090 #endif
3091
3092   *hostname_result = NULL;
3093   *port_result = -1;
3094
3095   if(!host || !*host)
3096     return CURLE_OK;
3097
3098   host_dup = strdup(host);
3099   if(!host_dup)
3100     return CURLE_OUT_OF_MEMORY;
3101
3102   hostptr = host_dup;
3103
3104   /* start scanning for port number at this point */
3105   portptr = hostptr;
3106
3107   /* detect and extract RFC6874-style IPv6-addresses */
3108   if(*hostptr == '[') {
3109 #ifdef ENABLE_IPV6
3110     char *ptr = ++hostptr; /* advance beyond the initial bracket */
3111     while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
3112       ptr++;
3113     if(*ptr == '%') {
3114       /* There might be a zone identifier */
3115       if(strncmp("%25", ptr, 3))
3116         infof(data, "Please URL encode %% as %%25, see RFC 6874.");
3117       ptr++;
3118       /* Allow unreserved characters as defined in RFC 3986 */
3119       while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
3120                      (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
3121         ptr++;
3122     }
3123     if(*ptr == ']')
3124       /* yeps, it ended nicely with a bracket as well */
3125       *ptr++ = '\0';
3126     else
3127       infof(data, "Invalid IPv6 address format");
3128     portptr = ptr;
3129     /* Note that if this didn't end with a bracket, we still advanced the
3130      * hostptr first, but I can't see anything wrong with that as no host
3131      * name nor a numeric can legally start with a bracket.
3132      */
3133 #else
3134     failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in");
3135     result = CURLE_NOT_BUILT_IN;
3136     goto error;
3137 #endif
3138   }
3139
3140   /* Get port number off server.com:1080 */
3141   host_portno = strchr(portptr, ':');
3142   if(host_portno) {
3143     char *endp = NULL;
3144     *host_portno = '\0'; /* cut off number from host name */
3145     host_portno++;
3146     if(*host_portno) {
3147       long portparse = strtol(host_portno, &endp, 10);
3148       if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
3149         failf(data, "No valid port number in connect to host string (%s)",
3150               host_portno);
3151         result = CURLE_SETOPT_OPTION_SYNTAX;
3152         goto error;
3153       }
3154       else
3155         port = (int)portparse; /* we know it will fit */
3156     }
3157   }
3158
3159   /* now, clone the cleaned host name */
3160   if(hostptr) {
3161     *hostname_result = strdup(hostptr);
3162     if(!*hostname_result) {
3163       result = CURLE_OUT_OF_MEMORY;
3164       goto error;
3165     }
3166   }
3167
3168   *port_result = port;
3169
3170   error:
3171   free(host_dup);
3172   return result;
3173 }
3174
3175 /*
3176  * Parses one "connect to" string in the form:
3177  * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT".
3178  */
3179 static CURLcode parse_connect_to_string(struct Curl_easy *data,
3180                                         struct connectdata *conn,
3181                                         const char *conn_to_host,
3182                                         char **host_result,
3183                                         int *port_result)
3184 {
3185   CURLcode result = CURLE_OK;
3186   const char *ptr = conn_to_host;
3187   int host_match = FALSE;
3188   int port_match = FALSE;
3189
3190   *host_result = NULL;
3191   *port_result = -1;
3192
3193   if(*ptr == ':') {
3194     /* an empty hostname always matches */
3195     host_match = TRUE;
3196     ptr++;
3197   }
3198   else {
3199     /* check whether the URL's hostname matches */
3200     size_t hostname_to_match_len;
3201     char *hostname_to_match = aprintf("%s%s%s",
3202                                       conn->bits.ipv6_ip ? "[" : "",
3203                                       conn->host.name,
3204                                       conn->bits.ipv6_ip ? "]" : "");
3205     if(!hostname_to_match)
3206       return CURLE_OUT_OF_MEMORY;
3207     hostname_to_match_len = strlen(hostname_to_match);
3208     host_match = strncasecompare(ptr, hostname_to_match,
3209                                  hostname_to_match_len);
3210     free(hostname_to_match);
3211     ptr += hostname_to_match_len;
3212
3213     host_match = host_match && *ptr == ':';
3214     ptr++;
3215   }
3216
3217   if(host_match) {
3218     if(*ptr == ':') {
3219       /* an empty port always matches */
3220       port_match = TRUE;
3221       ptr++;
3222     }
3223     else {
3224       /* check whether the URL's port matches */
3225       char *ptr_next = strchr(ptr, ':');
3226       if(ptr_next) {
3227         char *endp = NULL;
3228         long port_to_match = strtol(ptr, &endp, 10);
3229         if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
3230           port_match = TRUE;
3231           ptr = ptr_next + 1;
3232         }
3233       }
3234     }
3235   }
3236
3237   if(host_match && port_match) {
3238     /* parse the hostname and port to connect to */
3239     result = parse_connect_to_host_port(data, ptr, host_result, port_result);
3240   }
3241
3242   return result;
3243 }
3244
3245 /*
3246  * Processes all strings in the "connect to" slist, and uses the "connect
3247  * to host" and "connect to port" of the first string that matches.
3248  */
3249 static CURLcode parse_connect_to_slist(struct Curl_easy *data,
3250                                        struct connectdata *conn,
3251                                        struct curl_slist *conn_to_host)
3252 {
3253   CURLcode result = CURLE_OK;
3254   char *host = NULL;
3255   int port = -1;
3256
3257   while(conn_to_host && !host && port == -1) {
3258     result = parse_connect_to_string(data, conn, conn_to_host->data,
3259                                      &host, &port);
3260     if(result)
3261       return result;
3262
3263     if(host && *host) {
3264       conn->conn_to_host.rawalloc = host;
3265       conn->conn_to_host.name = host;
3266       conn->bits.conn_to_host = TRUE;
3267
3268       infof(data, "Connecting to hostname: %s", host);
3269     }
3270     else {
3271       /* no "connect to host" */
3272       conn->bits.conn_to_host = FALSE;
3273       Curl_safefree(host);
3274     }
3275
3276     if(port >= 0) {
3277       conn->conn_to_port = port;
3278       conn->bits.conn_to_port = TRUE;
3279       infof(data, "Connecting to port: %d", port);
3280     }
3281     else {
3282       /* no "connect to port" */
3283       conn->bits.conn_to_port = FALSE;
3284       port = -1;
3285     }
3286
3287     conn_to_host = conn_to_host->next;
3288   }
3289
3290 #ifndef CURL_DISABLE_ALTSVC
3291   if(data->asi && !host && (port == -1) &&
3292      ((conn->handler->protocol == CURLPROTO_HTTPS) ||
3293 #ifdef CURLDEBUG
3294       /* allow debug builds to circumvent the HTTPS restriction */
3295       getenv("CURL_ALTSVC_HTTP")
3296 #else
3297       0
3298 #endif
3299        )) {
3300     /* no connect_to match, try alt-svc! */
3301     enum alpnid srcalpnid;
3302     bool hit;
3303     struct altsvc *as;
3304     const int allowed_versions = ( ALPN_h1
3305 #ifdef USE_HTTP2
3306                                    | ALPN_h2
3307 #endif
3308 #ifdef ENABLE_QUIC
3309                                    | ALPN_h3
3310 #endif
3311       ) & data->asi->flags;
3312
3313     host = conn->host.rawalloc;
3314 #ifdef USE_HTTP2
3315     /* with h2 support, check that first */
3316     srcalpnid = ALPN_h2;
3317     hit = Curl_altsvc_lookup(data->asi,
3318                              srcalpnid, host, conn->remote_port, /* from */
3319                              &as /* to */,
3320                              allowed_versions);
3321     if(!hit)
3322 #endif
3323     {
3324       srcalpnid = ALPN_h1;
3325       hit = Curl_altsvc_lookup(data->asi,
3326                                srcalpnid, host, conn->remote_port, /* from */
3327                                &as /* to */,
3328                                allowed_versions);
3329     }
3330     if(hit) {
3331       char *hostd = strdup((char *)as->dst.host);
3332       if(!hostd)
3333         return CURLE_OUT_OF_MEMORY;
3334       conn->conn_to_host.rawalloc = hostd;
3335       conn->conn_to_host.name = hostd;
3336       conn->bits.conn_to_host = TRUE;
3337       conn->conn_to_port = as->dst.port;
3338       conn->bits.conn_to_port = TRUE;
3339       conn->bits.altused = TRUE;
3340       infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d",
3341             Curl_alpnid2str(srcalpnid), host, conn->remote_port,
3342             Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port);
3343       if(srcalpnid != as->dst.alpnid) {
3344         /* protocol version switch */
3345         switch(as->dst.alpnid) {
3346         case ALPN_h1:
3347           conn->httpversion = 11;
3348           break;
3349         case ALPN_h2:
3350           conn->httpversion = 20;
3351           break;
3352         case ALPN_h3:
3353           conn->transport = TRNSPRT_QUIC;
3354           conn->httpversion = 30;
3355           break;
3356         default: /* shouldn't be possible */
3357           break;
3358         }
3359       }
3360     }
3361   }
3362 #endif
3363
3364   return result;
3365 }
3366
3367 #ifdef USE_UNIX_SOCKETS
3368 static CURLcode resolve_unix(struct Curl_easy *data,
3369                              struct connectdata *conn,
3370                              char *unix_path)
3371 {
3372   struct Curl_dns_entry *hostaddr = NULL;
3373   bool longpath = FALSE;
3374
3375   DEBUGASSERT(unix_path);
3376   DEBUGASSERT(conn->dns_entry == NULL);
3377
3378   /* Unix domain sockets are local. The host gets ignored, just use the
3379    * specified domain socket address. Do not cache "DNS entries". There is
3380    * no DNS involved and we already have the filesystem path available. */
3381   hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
3382   if(!hostaddr)
3383     return CURLE_OUT_OF_MEMORY;
3384
3385   hostaddr->addr = Curl_unix2addr(unix_path, &longpath,
3386                                   conn->bits.abstract_unix_socket);
3387   if(!hostaddr->addr) {
3388     if(longpath)
3389       /* Long paths are not supported for now */
3390       failf(data, "Unix socket path too long: '%s'", unix_path);
3391     free(hostaddr);
3392     return longpath ? CURLE_COULDNT_RESOLVE_HOST : CURLE_OUT_OF_MEMORY;
3393   }
3394
3395   hostaddr->inuse++;
3396   conn->dns_entry = hostaddr;
3397   return CURLE_OK;
3398 }
3399 #endif
3400
3401 #ifndef CURL_DISABLE_PROXY
3402 static CURLcode resolve_proxy(struct Curl_easy *data,
3403                               struct connectdata *conn,
3404                               bool *async)
3405 {
3406   struct Curl_dns_entry *hostaddr = NULL;
3407   struct hostname *host;
3408   timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3409   int rc;
3410
3411   DEBUGASSERT(conn->dns_entry == NULL);
3412
3413   host = conn->bits.socksproxy ? &conn->socks_proxy.host :
3414     &conn->http_proxy.host;
3415
3416   conn->hostname_resolve = strdup(host->name);
3417   if(!conn->hostname_resolve)
3418     return CURLE_OUT_OF_MEMORY;
3419
3420   rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
3421                            &hostaddr, timeout_ms);
3422   conn->dns_entry = hostaddr;
3423   if(rc == CURLRESOLV_PENDING)
3424     *async = TRUE;
3425   else if(rc == CURLRESOLV_TIMEDOUT)
3426     return CURLE_OPERATION_TIMEDOUT;
3427   else if(!hostaddr) {
3428     failf(data, "Couldn't resolve proxy '%s'", host->dispname);
3429     return CURLE_COULDNT_RESOLVE_PROXY;
3430   }
3431
3432   return CURLE_OK;
3433 }
3434 #endif
3435
3436 static CURLcode resolve_host(struct Curl_easy *data,
3437                              struct connectdata *conn,
3438                              bool *async)
3439 {
3440   struct Curl_dns_entry *hostaddr = NULL;
3441   struct hostname *connhost;
3442   timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3443   int rc;
3444
3445   DEBUGASSERT(conn->dns_entry == NULL);
3446
3447   connhost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host;
3448
3449   /* If not connecting via a proxy, extract the port from the URL, if it is
3450    * there, thus overriding any defaults that might have been set above. */
3451   conn->port = conn->bits.conn_to_port ? conn->conn_to_port :
3452     conn->remote_port;
3453
3454   /* Resolve target host right on */
3455   conn->hostname_resolve = strdup(connhost->name);
3456   if(!conn->hostname_resolve)
3457     return CURLE_OUT_OF_MEMORY;
3458
3459   rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
3460                            &hostaddr, timeout_ms);
3461   conn->dns_entry = hostaddr;
3462   if(rc == CURLRESOLV_PENDING)
3463     *async = TRUE;
3464   else if(rc == CURLRESOLV_TIMEDOUT) {
3465     failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
3466           connhost->dispname,
3467           Curl_timediff(Curl_now(), data->progress.t_startsingle));
3468     return CURLE_OPERATION_TIMEDOUT;
3469   }
3470   else if(!hostaddr) {
3471     failf(data, "Could not resolve host: %s", connhost->dispname);
3472     return CURLE_COULDNT_RESOLVE_HOST;
3473   }
3474
3475   return CURLE_OK;
3476 }
3477
3478 /* Perform a fresh resolve */
3479 static CURLcode resolve_fresh(struct Curl_easy *data,
3480                               struct connectdata *conn,
3481                               bool *async)
3482 {
3483 #ifdef USE_UNIX_SOCKETS
3484   char *unix_path = conn->unix_domain_socket;
3485
3486 #ifndef CURL_DISABLE_PROXY
3487   if(!unix_path && conn->socks_proxy.host.name &&
3488      !strncmp(UNIX_SOCKET_PREFIX"/",
3489               conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX)))
3490     unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1;
3491 #endif
3492
3493   if(unix_path) {
3494     conn->transport = TRNSPRT_UNIX;
3495     return resolve_unix(data, conn, unix_path);
3496   }
3497 #endif
3498
3499 #ifndef CURL_DISABLE_PROXY
3500   if(CONN_IS_PROXIED(conn))
3501     return resolve_proxy(data, conn, async);
3502 #endif
3503
3504   return resolve_host(data, conn, async);
3505 }
3506
3507 /*************************************************************
3508  * Resolve the address of the server or proxy
3509  *************************************************************/
3510 static CURLcode resolve_server(struct Curl_easy *data,
3511                                struct connectdata *conn,
3512                                bool *async)
3513 {
3514   DEBUGASSERT(conn);
3515   DEBUGASSERT(data);
3516
3517   /* Resolve the name of the server or proxy */
3518   if(conn->bits.reuse) {
3519     /* We're reusing the connection - no need to resolve anything, and
3520        idnconvert_hostname() was called already in create_conn() for the re-use
3521        case. */
3522     *async = FALSE;
3523     return CURLE_OK;
3524   }
3525
3526   return resolve_fresh(data, conn, async);
3527 }
3528
3529 /*
3530  * Cleanup the connection just allocated before we can move along and use the
3531  * previously existing one.  All relevant data is copied over and old_conn is
3532  * ready for freeing once this function returns.
3533  */
3534 static void reuse_conn(struct Curl_easy *data,
3535                        struct connectdata *old_conn,
3536                        struct connectdata *conn)
3537 {
3538   /* 'local_ip' and 'local_port' get filled with local's numerical
3539      ip address and port number whenever an outgoing connection is
3540      **established** from the primary socket to a remote address. */
3541   char local_ip[MAX_IPADR_LEN] = "";
3542   int local_port = -1;
3543
3544   /* get the user+password information from the old_conn struct since it may
3545    * be new for this request even when we re-use an existing connection */
3546   if(old_conn->user) {
3547     /* use the new user name and password though */
3548     Curl_safefree(conn->user);
3549     Curl_safefree(conn->passwd);
3550     conn->user = old_conn->user;
3551     conn->passwd = old_conn->passwd;
3552     old_conn->user = NULL;
3553     old_conn->passwd = NULL;
3554   }
3555
3556 #ifndef CURL_DISABLE_PROXY
3557   conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3558   if(conn->bits.proxy_user_passwd) {
3559     /* use the new proxy user name and proxy password though */
3560     Curl_safefree(conn->http_proxy.user);
3561     Curl_safefree(conn->socks_proxy.user);
3562     Curl_safefree(conn->http_proxy.passwd);
3563     Curl_safefree(conn->socks_proxy.passwd);
3564     conn->http_proxy.user = old_conn->http_proxy.user;
3565     conn->socks_proxy.user = old_conn->socks_proxy.user;
3566     conn->http_proxy.passwd = old_conn->http_proxy.passwd;
3567     conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
3568     old_conn->http_proxy.user = NULL;
3569     old_conn->socks_proxy.user = NULL;
3570     old_conn->http_proxy.passwd = NULL;
3571     old_conn->socks_proxy.passwd = NULL;
3572   }
3573 #endif
3574
3575   Curl_free_idnconverted_hostname(&conn->host);
3576   Curl_free_idnconverted_hostname(&conn->conn_to_host);
3577   Curl_safefree(conn->host.rawalloc);
3578   Curl_safefree(conn->conn_to_host.rawalloc);
3579   conn->host = old_conn->host;
3580   old_conn->host.rawalloc = NULL;
3581   old_conn->host.encalloc = NULL;
3582   conn->conn_to_host = old_conn->conn_to_host;
3583   old_conn->conn_to_host.rawalloc = NULL;
3584   conn->conn_to_port = old_conn->conn_to_port;
3585   conn->remote_port = old_conn->remote_port;
3586   Curl_safefree(conn->hostname_resolve);
3587
3588   conn->hostname_resolve = old_conn->hostname_resolve;
3589   old_conn->hostname_resolve = NULL;
3590
3591   /* persist connection info in session handle */
3592   if(conn->transport == TRNSPRT_TCP) {
3593     Curl_conninfo_local(data, conn->sock[FIRSTSOCKET],
3594                         local_ip, &local_port);
3595   }
3596   Curl_persistconninfo(data, conn, local_ip, local_port);
3597
3598   conn_reset_all_postponed_data(old_conn); /* free buffers */
3599
3600   /* re-use init */
3601   conn->bits.reuse = TRUE; /* yes, we're re-using here */
3602
3603   conn_free(old_conn);
3604 }
3605
3606 /**
3607  * create_conn() sets up a new connectdata struct, or re-uses an already
3608  * existing one, and resolves host name.
3609  *
3610  * if this function returns CURLE_OK and *async is set to TRUE, the resolve
3611  * response will be coming asynchronously. If *async is FALSE, the name is
3612  * already resolved.
3613  *
3614  * @param data The sessionhandle pointer
3615  * @param in_connect is set to the next connection data pointer
3616  * @param async is set TRUE when an async DNS resolution is pending
3617  * @see Curl_setup_conn()
3618  *
3619  */
3620
3621 static CURLcode create_conn(struct Curl_easy *data,
3622                             struct connectdata **in_connect,
3623                             bool *async)
3624 {
3625   CURLcode result = CURLE_OK;
3626   struct connectdata *conn;
3627   struct connectdata *conn_temp = NULL;
3628   bool reuse;
3629   bool connections_available = TRUE;
3630   bool force_reuse = FALSE;
3631   bool waitpipe = FALSE;
3632   size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
3633   size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
3634
3635   *async = FALSE;
3636   *in_connect = NULL;
3637
3638   /*************************************************************
3639    * Check input data
3640    *************************************************************/
3641   if(!data->state.url) {
3642     result = CURLE_URL_MALFORMAT;
3643     goto out;
3644   }
3645
3646   /* First, split up the current URL in parts so that we can use the
3647      parts for checking against the already present connections. In order
3648      to not have to modify everything at once, we allocate a temporary
3649      connection data struct and fill in for comparison purposes. */
3650   conn = allocate_conn(data);
3651
3652   if(!conn) {
3653     result = CURLE_OUT_OF_MEMORY;
3654     goto out;
3655   }
3656
3657   /* We must set the return variable as soon as possible, so that our
3658      parent can cleanup any possible allocs we may have done before
3659      any failure */
3660   *in_connect = conn;
3661
3662   result = parseurlandfillconn(data, conn);
3663   if(result)
3664     goto out;
3665
3666   if(data->set.str[STRING_SASL_AUTHZID]) {
3667     conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]);
3668     if(!conn->sasl_authzid) {
3669       result = CURLE_OUT_OF_MEMORY;
3670       goto out;
3671     }
3672   }
3673
3674   if(data->set.str[STRING_BEARER]) {
3675     conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
3676     if(!conn->oauth_bearer) {
3677       result = CURLE_OUT_OF_MEMORY;
3678       goto out;
3679     }
3680   }
3681
3682 #ifdef USE_UNIX_SOCKETS
3683   if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
3684     conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
3685     if(!conn->unix_domain_socket) {
3686       result = CURLE_OUT_OF_MEMORY;
3687       goto out;
3688     }
3689     conn->bits.abstract_unix_socket = data->set.abstract_unix_socket;
3690   }
3691 #endif
3692
3693   /* After the unix socket init but before the proxy vars are used, parse and
3694      initialize the proxy vars */
3695 #ifndef CURL_DISABLE_PROXY
3696   result = create_conn_helper_init_proxy(data, conn);
3697   if(result)
3698     goto out;
3699
3700   /*************************************************************
3701    * If the protocol is using SSL and HTTP proxy is used, we set
3702    * the tunnel_proxy bit.
3703    *************************************************************/
3704   if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
3705     conn->bits.tunnel_proxy = TRUE;
3706 #endif
3707
3708   /*************************************************************
3709    * Figure out the remote port number and fix it in the URL
3710    *************************************************************/
3711   result = parse_remote_port(data, conn);
3712   if(result)
3713     goto out;
3714
3715   /* Check for overridden login details and set them accordingly so that
3716      they are known when protocol->setup_connection is called! */
3717   result = override_login(data, conn);
3718   if(result)
3719     goto out;
3720
3721   result = set_login(data, conn); /* default credentials */
3722   if(result)
3723     goto out;
3724
3725   /*************************************************************
3726    * Process the "connect to" linked list of hostname/port mappings.
3727    * Do this after the remote port number has been fixed in the URL.
3728    *************************************************************/
3729   result = parse_connect_to_slist(data, conn, data->set.connect_to);
3730   if(result)
3731     goto out;
3732
3733
3734   /*************************************************************
3735    * Check whether the host and the "connect to host" are equal.
3736    * Do this after the hostnames have been IDN-converted.
3737    *************************************************************/
3738   if(conn->bits.conn_to_host &&
3739      strcasecompare(conn->conn_to_host.name, conn->host.name)) {
3740     conn->bits.conn_to_host = FALSE;
3741   }
3742
3743   /*************************************************************
3744    * Check whether the port and the "connect to port" are equal.
3745    * Do this after the remote port number has been fixed in the URL.
3746    *************************************************************/
3747   if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) {
3748     conn->bits.conn_to_port = FALSE;
3749   }
3750
3751 #ifndef CURL_DISABLE_PROXY
3752   /*************************************************************
3753    * If the "connect to" feature is used with an HTTP proxy,
3754    * we set the tunnel_proxy bit.
3755    *************************************************************/
3756   if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
3757       conn->bits.httpproxy)
3758     conn->bits.tunnel_proxy = TRUE;
3759 #endif
3760
3761   /*************************************************************
3762    * Setup internals depending on protocol. Needs to be done after
3763    * we figured out what/if proxy to use.
3764    *************************************************************/
3765   result = setup_connection_internals(data, conn);
3766   if(result)
3767     goto out;
3768
3769   conn->recv[FIRSTSOCKET] = Curl_recv_plain;
3770   conn->send[FIRSTSOCKET] = Curl_send_plain;
3771   conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
3772   conn->send[SECONDARYSOCKET] = Curl_send_plain;
3773
3774   conn->bits.tcp_fastopen = data->set.tcp_fastopen;
3775
3776   /***********************************************************************
3777    * file: is a special case in that it doesn't need a network connection
3778    ***********************************************************************/
3779 #ifndef CURL_DISABLE_FILE
3780   if(conn->handler->flags & PROTOPT_NONETWORK) {
3781     bool done;
3782     /* this is supposed to be the connect function so we better at least check
3783        that the file is present here! */
3784     DEBUGASSERT(conn->handler->connect_it);
3785     Curl_persistconninfo(data, conn, NULL, -1);
3786     result = conn->handler->connect_it(data, &done);
3787
3788     /* Setup a "faked" transfer that'll do nothing */
3789     if(!result) {
3790       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
3791
3792       Curl_attach_connection(data, conn);
3793       result = Curl_conncache_add_conn(data);
3794       if(result)
3795         goto out;
3796
3797       /*
3798        * Setup whatever necessary for a resumed transfer
3799        */
3800       result = setup_range(data);
3801       if(result) {
3802         DEBUGASSERT(conn->handler->done);
3803         /* we ignore the return code for the protocol-specific DONE */
3804         (void)conn->handler->done(data, result, FALSE);
3805         goto out;
3806       }
3807       Curl_setup_transfer(data, -1, -1, FALSE, -1);
3808     }
3809
3810     /* since we skip do_init() */
3811     Curl_init_do(data, conn);
3812
3813     goto out;
3814   }
3815 #endif
3816
3817   /* Get a cloned copy of the SSL config situation stored in the
3818      connection struct. But to get this going nicely, we must first make
3819      sure that the strings in the master copy are pointing to the correct
3820      strings in the session handle strings array!
3821
3822      Keep in mind that the pointers in the master copy are pointing to strings
3823      that will be freed as part of the Curl_easy struct, but all cloned
3824      copies will be separately allocated.
3825   */
3826   data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH];
3827   data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
3828   data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
3829   data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
3830   data->set.ssl.primary.cipher_list =
3831     data->set.str[STRING_SSL_CIPHER_LIST];
3832   data->set.ssl.primary.cipher_list13 =
3833     data->set.str[STRING_SSL_CIPHER13_LIST];
3834   data->set.ssl.primary.pinned_key =
3835     data->set.str[STRING_SSL_PINNEDPUBLICKEY];
3836   data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT];
3837   data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO];
3838   data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
3839
3840 #ifndef CURL_DISABLE_PROXY
3841   data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
3842   data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
3843   data->set.proxy_ssl.primary.cipher_list =
3844     data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
3845   data->set.proxy_ssl.primary.cipher_list13 =
3846     data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
3847   data->set.proxy_ssl.primary.pinned_key =
3848     data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
3849   data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
3850   data->set.proxy_ssl.primary.ca_info_blob =
3851     data->set.blobs[BLOB_CAINFO_PROXY];
3852   data->set.proxy_ssl.primary.issuercert =
3853     data->set.str[STRING_SSL_ISSUERCERT_PROXY];
3854   data->set.proxy_ssl.primary.issuercert_blob =
3855     data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY];
3856   data->set.proxy_ssl.primary.CRLfile =
3857     data->set.str[STRING_SSL_CRLFILE_PROXY];
3858   data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
3859   data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
3860   data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
3861   data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
3862   data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
3863   data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
3864 #endif
3865   data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE];
3866   data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
3867   data->set.ssl.key = data->set.str[STRING_KEY];
3868   data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
3869   data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD];
3870   data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
3871 #ifdef USE_TLS_SRP
3872   data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME];
3873   data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD];
3874 #ifndef CURL_DISABLE_PROXY
3875   data->set.proxy_ssl.primary.username =
3876     data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
3877   data->set.proxy_ssl.primary.password =
3878     data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
3879 #endif
3880 #endif
3881   data->set.ssl.key_blob = data->set.blobs[BLOB_KEY];
3882
3883   if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
3884                                     &conn->ssl_config)) {
3885     result = CURLE_OUT_OF_MEMORY;
3886     goto out;
3887   }
3888
3889 #ifndef CURL_DISABLE_PROXY
3890   if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
3891                                     &conn->proxy_ssl_config)) {
3892     result = CURLE_OUT_OF_MEMORY;
3893     goto out;
3894   }
3895 #endif
3896
3897   prune_dead_connections(data);
3898
3899   /*************************************************************
3900    * Check the current list of connections to see if we can
3901    * re-use an already existing one or if we have to create a
3902    * new one.
3903    *************************************************************/
3904
3905   DEBUGASSERT(conn->user);
3906   DEBUGASSERT(conn->passwd);
3907
3908   /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3909      we only acknowledge this option if this is not a re-used connection
3910      already (which happens due to follow-location or during a HTTP
3911      authentication phase). CONNECT_ONLY transfers also refuse reuse. */
3912   if((data->set.reuse_fresh && !data->state.this_is_a_follow) ||
3913      data->set.connect_only)
3914     reuse = FALSE;
3915   else
3916     reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
3917
3918   if(reuse) {
3919     /*
3920      * We already have a connection for this, we got the former connection in
3921      * the conn_temp variable and thus we need to cleanup the one we just
3922      * allocated before we can move along and use the previously existing one.
3923      */
3924     reuse_conn(data, conn, conn_temp);
3925     conn = conn_temp;
3926     *in_connect = conn;
3927
3928 #ifndef CURL_DISABLE_PROXY
3929     infof(data, "Re-using existing connection #%ld with %s %s",
3930           conn->connection_id,
3931           conn->bits.proxy?"proxy":"host",
3932           conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
3933           conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
3934           conn->host.dispname);
3935 #else
3936     infof(data, "Re-using existing connection #%ld with host %s",
3937           conn->connection_id, conn->host.dispname);
3938 #endif
3939   }
3940   else {
3941     /* We have decided that we want a new connection. However, we may not
3942        be able to do that if we have reached the limit of how many
3943        connections we are allowed to open. */
3944
3945     if(conn->handler->flags & PROTOPT_ALPN) {
3946       /* The protocol wants it, so set the bits if enabled in the easy handle
3947          (default) */
3948       if(data->set.ssl_enable_alpn)
3949         conn->bits.tls_enable_alpn = TRUE;
3950     }
3951
3952     if(waitpipe)
3953       /* There is a connection that *might* become usable for multiplexing
3954          "soon", and we wait for that */
3955       connections_available = FALSE;
3956     else {
3957       /* this gets a lock on the conncache */
3958       struct connectbundle *bundle =
3959         Curl_conncache_find_bundle(data, conn, data->state.conn_cache);
3960
3961       if(max_host_connections > 0 && bundle &&
3962          (bundle->num_connections >= max_host_connections)) {
3963         struct connectdata *conn_candidate;
3964
3965         /* The bundle is full. Extract the oldest connection. */
3966         conn_candidate = Curl_conncache_extract_bundle(data, bundle);
3967         CONNCACHE_UNLOCK(data);
3968
3969         if(conn_candidate)
3970           Curl_disconnect(data, conn_candidate, FALSE);
3971         else {
3972           infof(data, "No more connections allowed to host: %zu",
3973                 max_host_connections);
3974           connections_available = FALSE;
3975         }
3976       }
3977       else
3978         CONNCACHE_UNLOCK(data);
3979
3980     }
3981
3982     if(connections_available &&
3983        (max_total_connections > 0) &&
3984        (Curl_conncache_size(data) >= max_total_connections)) {
3985       struct connectdata *conn_candidate;
3986
3987       /* The cache is full. Let's see if we can kill a connection. */
3988       conn_candidate = Curl_conncache_extract_oldest(data);
3989       if(conn_candidate)
3990         Curl_disconnect(data, conn_candidate, FALSE);
3991       else {
3992         infof(data, "No connections available in cache");
3993         connections_available = FALSE;
3994       }
3995     }
3996
3997     if(!connections_available) {
3998       infof(data, "No connections available.");
3999
4000       conn_free(conn);
4001       *in_connect = NULL;
4002
4003       result = CURLE_NO_CONNECTION_AVAILABLE;
4004       goto out;
4005     }
4006     else {
4007       /*
4008        * This is a brand new connection, so let's store it in the connection
4009        * cache of ours!
4010        */
4011       Curl_attach_connection(data, conn);
4012       result = Curl_conncache_add_conn(data);
4013       if(result)
4014         goto out;
4015     }
4016
4017 #if defined(USE_NTLM)
4018     /* If NTLM is requested in a part of this connection, make sure we don't
4019        assume the state is fine as this is a fresh connection and NTLM is
4020        connection based. */
4021     if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
4022        data->state.authhost.done) {
4023       infof(data, "NTLM picked AND auth done set, clear picked");
4024       data->state.authhost.picked = CURLAUTH_NONE;
4025       data->state.authhost.done = FALSE;
4026     }
4027
4028     if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
4029        data->state.authproxy.done) {
4030       infof(data, "NTLM-proxy picked AND auth done set, clear picked");
4031       data->state.authproxy.picked = CURLAUTH_NONE;
4032       data->state.authproxy.done = FALSE;
4033     }
4034 #endif
4035   }
4036
4037   /* Setup and init stuff before DO starts, in preparing for the transfer. */
4038   Curl_init_do(data, conn);
4039
4040   /*
4041    * Setup whatever necessary for a resumed transfer
4042    */
4043   result = setup_range(data);
4044   if(result)
4045     goto out;
4046
4047   /* Continue connectdata initialization here. */
4048
4049   /*
4050    * Inherit the proper values from the urldata struct AFTER we have arranged
4051    * the persistent connection stuff
4052    */
4053   conn->seek_func = data->set.seek_func;
4054   conn->seek_client = data->set.seek_client;
4055
4056   /*************************************************************
4057    * Resolve the address of the server or proxy
4058    *************************************************************/
4059   result = resolve_server(data, conn, async);
4060
4061 out:
4062   return result;
4063 }
4064
4065 /* Curl_setup_conn() is called after the name resolve initiated in
4066  * create_conn() is all done.
4067  *
4068  * Curl_setup_conn() also handles reused connections
4069  */
4070 CURLcode Curl_setup_conn(struct Curl_easy *data,
4071                          bool *protocol_done)
4072 {
4073   CURLcode result = CURLE_OK;
4074   struct connectdata *conn = data->conn;
4075
4076   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
4077
4078   if(conn->handler->flags & PROTOPT_NONETWORK) {
4079     /* nothing to setup when not using a network */
4080     *protocol_done = TRUE;
4081     return result;
4082   }
4083   *protocol_done = FALSE; /* default to not done */
4084
4085 #ifndef CURL_DISABLE_PROXY
4086   /* set proxy_connect_closed to false unconditionally already here since it
4087      is used strictly to provide extra information to a parent function in the
4088      case of proxy CONNECT failures and we must make sure we don't have it
4089      lingering set from a previous invoke */
4090   conn->bits.proxy_connect_closed = FALSE;
4091 #endif
4092
4093 #ifdef CURL_DO_LINEEND_CONV
4094   data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
4095 #endif /* CURL_DO_LINEEND_CONV */
4096
4097   /* set start time here for timeout purposes in the connect procedure, it
4098      is later set again for the progress meter purpose */
4099   conn->now = Curl_now();
4100
4101   if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
4102     conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
4103     result = Curl_connecthost(data, conn, conn->dns_entry);
4104     if(result)
4105       return result;
4106   }
4107   else {
4108     Curl_pgrsTime(data, TIMER_CONNECT);    /* we're connected already */
4109     if(conn->ssl[FIRSTSOCKET].use ||
4110        (conn->handler->protocol & PROTO_FAMILY_SSH))
4111       Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
4112     conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
4113     *protocol_done = TRUE;
4114     Curl_updateconninfo(data, conn, conn->sock[FIRSTSOCKET]);
4115     Curl_verboseconnect(data, conn);
4116   }
4117
4118   conn->now = Curl_now(); /* time this *after* the connect is done, we set
4119                              this here perhaps a second time */
4120   return result;
4121 }
4122
4123 CURLcode Curl_connect(struct Curl_easy *data,
4124                       bool *asyncp,
4125                       bool *protocol_done)
4126 {
4127   CURLcode result;
4128   struct connectdata *conn;
4129
4130   *asyncp = FALSE; /* assume synchronous resolves by default */
4131
4132   /* init the single-transfer specific data */
4133   Curl_free_request_state(data);
4134   memset(&data->req, 0, sizeof(struct SingleRequest));
4135   data->req.size = data->req.maxdownload = -1;
4136
4137   /* call the stuff that needs to be called */
4138   result = create_conn(data, &conn, asyncp);
4139
4140   if(!result) {
4141     if(CONN_INUSE(conn) > 1)
4142       /* multiplexed */
4143       *protocol_done = TRUE;
4144     else if(!*asyncp) {
4145       /* DNS resolution is done: that's either because this is a reused
4146          connection, in which case DNS was unnecessary, or because DNS
4147          really did finish already (synch resolver/fast async resolve) */
4148       result = Curl_setup_conn(data, protocol_done);
4149     }
4150   }
4151
4152   if(result == CURLE_NO_CONNECTION_AVAILABLE) {
4153     return result;
4154   }
4155   else if(result && conn) {
4156     /* We're not allowed to return failure with memory left allocated in the
4157        connectdata struct, free those here */
4158     Curl_detach_connection(data);
4159     Curl_conncache_remove_conn(data, conn, TRUE);
4160     Curl_disconnect(data, conn, TRUE);
4161   }
4162
4163   return result;
4164 }
4165
4166 /*
4167  * Curl_init_do() inits the readwrite session. This is inited each time (in
4168  * the DO function before the protocol-specific DO functions are invoked) for
4169  * a transfer, sometimes multiple times on the same Curl_easy. Make sure
4170  * nothing in here depends on stuff that are setup dynamically for the
4171  * transfer.
4172  *
4173  * Allow this function to get called with 'conn' set to NULL.
4174  */
4175
4176 CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
4177 {
4178   struct SingleRequest *k = &data->req;
4179
4180   /* if this is a pushed stream, we need this: */
4181   CURLcode result = Curl_preconnect(data);
4182   if(result)
4183     return result;
4184
4185   if(conn) {
4186     conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
4187                                    use */
4188     /* if the protocol used doesn't support wildcards, switch it off */
4189     if(data->state.wildcardmatch &&
4190        !(conn->handler->flags & PROTOPT_WILDCARD))
4191       data->state.wildcardmatch = FALSE;
4192   }
4193
4194   data->state.done = FALSE; /* *_done() is not called yet */
4195   data->state.expect100header = FALSE;
4196
4197   if(data->set.opt_no_body)
4198     /* in HTTP lingo, no body means using the HEAD request... */
4199     data->state.httpreq = HTTPREQ_HEAD;
4200
4201   k->start = Curl_now(); /* start time */
4202   k->now = k->start;   /* current time is now */
4203   k->header = TRUE; /* assume header */
4204   k->bytecount = 0;
4205   k->ignorebody = FALSE;
4206
4207   Curl_speedinit(data);
4208   Curl_pgrsSetUploadCounter(data, 0);
4209   Curl_pgrsSetDownloadCounter(data, 0);
4210
4211   return CURLE_OK;
4212 }