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