• 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.primary.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->http09_allowed = FALSE;
626   set->httpwant =
627 #ifdef USE_NGHTTP2
628     CURL_HTTP_VERSION_2TLS
629 #else
630     CURL_HTTP_VERSION_1_1
631 #endif
632     ;
633   Curl_http2_init_userset(set);
634   return result;
635 }
636 
637 /**
638  * Curl_open()
639  *
640  * @param curl is a pointer to a sessionhandle pointer that gets set by this
641  * function.
642  * @return CURLcode
643  */
644 
Curl_open(struct Curl_easy ** curl)645 CURLcode Curl_open(struct Curl_easy **curl)
646 {
647   CURLcode result;
648   struct Curl_easy *data;
649 
650   /* Very simple start-up: alloc the struct, init it with zeroes and return */
651   data = calloc(1, sizeof(struct Curl_easy));
652   if(!data) {
653     /* this is a very serious error */
654     DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n"));
655     return CURLE_OUT_OF_MEMORY;
656   }
657 
658   data->magic = CURLEASY_MAGIC_NUMBER;
659 
660   result = Curl_resolver_init(data, &data->state.async.resolver);
661   if(result) {
662     DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
663     free(data);
664     return result;
665   }
666 
667   result = Curl_init_userdefined(data);
668   if(!result) {
669     Curl_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER);
670     Curl_convert_init(data);
671     Curl_initinfo(data);
672 
673     /* most recent connection is not yet defined */
674     data->state.lastconnect_id = -1;
675 
676     data->progress.flags |= PGRS_HIDE;
677     data->state.current_speed = -1; /* init to negative == impossible */
678   }
679 
680   if(result) {
681     Curl_resolver_cleanup(data->state.async.resolver);
682     Curl_dyn_free(&data->state.headerb);
683     Curl_freeset(data);
684     free(data);
685     data = NULL;
686   }
687   else
688     *curl = data;
689 
690   return result;
691 }
692 
693 #ifdef USE_RECV_BEFORE_SEND_WORKAROUND
conn_reset_postponed_data(struct connectdata * conn,int num)694 static void conn_reset_postponed_data(struct connectdata *conn, int num)
695 {
696   struct postponed_data * const psnd = &(conn->postponed[num]);
697   if(psnd->buffer) {
698     DEBUGASSERT(psnd->allocated_size > 0);
699     DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
700     DEBUGASSERT(psnd->recv_size ?
701                 (psnd->recv_processed < psnd->recv_size) :
702                 (psnd->recv_processed == 0));
703     DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD);
704     free(psnd->buffer);
705     psnd->buffer = NULL;
706     psnd->allocated_size = 0;
707     psnd->recv_size = 0;
708     psnd->recv_processed = 0;
709 #ifdef DEBUGBUILD
710     psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */
711 #endif /* DEBUGBUILD */
712   }
713   else {
714     DEBUGASSERT(psnd->allocated_size == 0);
715     DEBUGASSERT(psnd->recv_size == 0);
716     DEBUGASSERT(psnd->recv_processed == 0);
717     DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD);
718   }
719 }
720 
conn_reset_all_postponed_data(struct connectdata * conn)721 static void conn_reset_all_postponed_data(struct connectdata *conn)
722 {
723   conn_reset_postponed_data(conn, 0);
724   conn_reset_postponed_data(conn, 1);
725 }
726 #else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
727 /* Use "do-nothing" macro instead of function when workaround not used */
728 #define conn_reset_all_postponed_data(c) do {} while(0)
729 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
730 
731 
conn_shutdown(struct Curl_easy * data,struct connectdata * conn)732 static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
733 {
734   DEBUGASSERT(conn);
735   DEBUGASSERT(data);
736   infof(data, "Closing connection %ld", conn->connection_id);
737 
738   /* possible left-overs from the async name resolvers */
739   Curl_resolver_cancel(data);
740 
741   /* close the SSL stuff before we close any sockets since they will/may
742      write to the sockets */
743   Curl_ssl_close(data, conn, FIRSTSOCKET);
744   Curl_ssl_close(data, conn, SECONDARYSOCKET);
745 
746   /* close possibly still open sockets */
747   if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
748     Curl_closesocket(data, conn, conn->sock[SECONDARYSOCKET]);
749   if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
750     Curl_closesocket(data, conn, conn->sock[FIRSTSOCKET]);
751   if(CURL_SOCKET_BAD != conn->tempsock[0])
752     Curl_closesocket(data, conn, conn->tempsock[0]);
753   if(CURL_SOCKET_BAD != conn->tempsock[1])
754     Curl_closesocket(data, conn, conn->tempsock[1]);
755 }
756 
conn_free(struct connectdata * conn)757 static void conn_free(struct connectdata *conn)
758 {
759   DEBUGASSERT(conn);
760 
761   Curl_free_idnconverted_hostname(&conn->host);
762   Curl_free_idnconverted_hostname(&conn->conn_to_host);
763 #ifndef CURL_DISABLE_PROXY
764   Curl_free_idnconverted_hostname(&conn->http_proxy.host);
765   Curl_free_idnconverted_hostname(&conn->socks_proxy.host);
766   Curl_safefree(conn->http_proxy.user);
767   Curl_safefree(conn->socks_proxy.user);
768   Curl_safefree(conn->http_proxy.passwd);
769   Curl_safefree(conn->socks_proxy.passwd);
770   Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
771   Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
772   Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
773 #endif
774   Curl_safefree(conn->user);
775   Curl_safefree(conn->passwd);
776   Curl_safefree(conn->sasl_authzid);
777   Curl_safefree(conn->options);
778   Curl_safefree(conn->oauth_bearer);
779   Curl_dyn_free(&conn->trailer);
780   Curl_safefree(conn->host.rawalloc); /* host name buffer */
781   Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
782   Curl_safefree(conn->hostname_resolve);
783   Curl_safefree(conn->secondaryhostname);
784   Curl_safefree(conn->connect_state);
785 
786   conn_reset_all_postponed_data(conn);
787   Curl_llist_destroy(&conn->easyq, NULL);
788   Curl_safefree(conn->localdev);
789   Curl_free_primary_ssl_config(&conn->ssl_config);
790 
791 #ifdef USE_UNIX_SOCKETS
792   Curl_safefree(conn->unix_domain_socket);
793 #endif
794 
795 #ifdef USE_SSL
796   Curl_safefree(conn->ssl_extra);
797 #endif
798   free(conn); /* free all the connection oriented data */
799 }
800 
801 /*
802  * Disconnects the given connection. Note the connection may not be the
803  * primary connection, like when freeing room in the connection cache or
804  * killing of a dead old connection.
805  *
806  * A connection needs an easy handle when closing down. We support this passed
807  * in separately since the connection to get closed here is often already
808  * disassociated from an easy handle.
809  *
810  * This function MUST NOT reset state in the Curl_easy struct if that
811  * isn't strictly bound to the life-time of *this* particular connection.
812  *
813  */
814 
Curl_disconnect(struct Curl_easy * data,struct connectdata * conn,bool dead_connection)815 CURLcode Curl_disconnect(struct Curl_easy *data,
816                          struct connectdata *conn, bool dead_connection)
817 {
818   /* there must be a connection to close */
819   DEBUGASSERT(conn);
820 
821   /* it must be removed from the connection cache */
822   DEBUGASSERT(!conn->bundle);
823 
824   /* there must be an associated transfer */
825   DEBUGASSERT(data);
826 
827   /* the transfer must be detached from the connection */
828   DEBUGASSERT(!data->conn);
829 
830   /*
831    * If this connection isn't marked to force-close, leave it open if there
832    * are other users of it
833    */
834   if(CONN_INUSE(conn) && !dead_connection) {
835     DEBUGF(infof(data, "Curl_disconnect when inuse: %zu", CONN_INUSE(conn)));
836     return CURLE_OK;
837   }
838 
839   if(conn->dns_entry != NULL) {
840     Curl_resolv_unlock(data, conn->dns_entry);
841     conn->dns_entry = NULL;
842   }
843 
844   /* Cleanup NTLM connection-related data */
845   Curl_http_auth_cleanup_ntlm(conn);
846 
847   /* Cleanup NEGOTIATE connection-related data */
848   Curl_http_auth_cleanup_negotiate(conn);
849 
850   if(conn->bits.connect_only)
851     /* treat the connection as dead in CONNECT_ONLY situations */
852     dead_connection = TRUE;
853 
854   /* temporarily attach the connection to this transfer handle for the
855      disconnect and shutdown */
856   Curl_attach_connnection(data, conn);
857 
858   if(conn->handler->disconnect)
859     /* This is set if protocol-specific cleanups should be made */
860     conn->handler->disconnect(data, conn, dead_connection);
861 
862   conn_shutdown(data, conn);
863 
864   /* detach it again */
865   Curl_detach_connnection(data);
866 
867   conn_free(conn);
868   return CURLE_OK;
869 }
870 
871 /*
872  * This function should return TRUE if the socket is to be assumed to
873  * be dead. Most commonly this happens when the server has closed the
874  * connection due to inactivity.
875  */
SocketIsDead(curl_socket_t sock)876 static bool SocketIsDead(curl_socket_t sock)
877 {
878   int sval;
879   bool ret_val = TRUE;
880 
881   sval = SOCKET_READABLE(sock, 0);
882   if(sval == 0)
883     /* timeout */
884     ret_val = FALSE;
885 
886   return ret_val;
887 }
888 
889 /*
890  * IsMultiplexingPossible()
891  *
892  * Return a bitmask with the available multiplexing options for the given
893  * requested connection.
894  */
IsMultiplexingPossible(const struct Curl_easy * handle,const struct connectdata * conn)895 static int IsMultiplexingPossible(const struct Curl_easy *handle,
896                                   const struct connectdata *conn)
897 {
898   int avail = 0;
899 
900   /* If a HTTP protocol and multiplexing is enabled */
901   if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
902      (!conn->bits.protoconnstart || !conn->bits.close)) {
903 
904     if(Curl_multiplex_wanted(handle->multi) &&
905        (handle->state.httpwant >= CURL_HTTP_VERSION_2))
906       /* allows HTTP/2 */
907       avail |= CURLPIPE_MULTIPLEX;
908   }
909   return avail;
910 }
911 
912 #ifndef CURL_DISABLE_PROXY
913 static bool
proxy_info_matches(const struct proxy_info * data,const struct proxy_info * needle)914 proxy_info_matches(const struct proxy_info *data,
915                    const struct proxy_info *needle)
916 {
917   if((data->proxytype == needle->proxytype) &&
918      (data->port == needle->port) &&
919      Curl_safe_strcasecompare(data->host.name, needle->host.name))
920     return TRUE;
921 
922   return FALSE;
923 }
924 
925 static bool
socks_proxy_info_matches(const struct proxy_info * data,const struct proxy_info * needle)926 socks_proxy_info_matches(const struct proxy_info *data,
927                          const struct proxy_info *needle)
928 {
929   if(!proxy_info_matches(data, needle))
930     return FALSE;
931 
932   /* the user information is case-sensitive
933      or at least it is not defined as case-insensitive
934      see https://tools.ietf.org/html/rfc3986#section-3.2.1 */
935   if(!data->user != !needle->user)
936     return FALSE;
937   /* curl_strequal does a case insentive comparison, so do not use it here! */
938   if(data->user &&
939      needle->user &&
940      strcmp(data->user, needle->user) != 0)
941     return FALSE;
942   if(!data->passwd != !needle->passwd)
943     return FALSE;
944   /* curl_strequal does a case insentive comparison, so do not use it here! */
945   if(data->passwd &&
946      needle->passwd &&
947      strcmp(data->passwd, needle->passwd) != 0)
948     return FALSE;
949   return TRUE;
950 }
951 #else
952 /* disabled, won't get called */
953 #define proxy_info_matches(x,y) FALSE
954 #define socks_proxy_info_matches(x,y) FALSE
955 #endif
956 
957 /* A connection has to have been idle for a shorter time than 'maxage_conn' to
958    be subject for reuse. The success rate is just too low after this. */
959 
conn_maxage(struct Curl_easy * data,struct connectdata * conn,struct curltime now)960 static bool conn_maxage(struct Curl_easy *data,
961                         struct connectdata *conn,
962                         struct curltime now)
963 {
964   timediff_t idletime = Curl_timediff(now, conn->lastused);
965   idletime /= 1000; /* integer seconds is fine */
966 
967   if(idletime > data->set.maxage_conn) {
968     infof(data, "Too old connection (%ld seconds), disconnect it",
969           idletime);
970     return TRUE;
971   }
972   return FALSE;
973 }
974 
975 /*
976  * This function checks if the given connection is dead and extracts it from
977  * the connection cache if so.
978  *
979  * When this is called as a Curl_conncache_foreach() callback, the connection
980  * cache lock is held!
981  *
982  * Returns TRUE if the connection was dead and extracted.
983  */
extract_if_dead(struct connectdata * conn,struct Curl_easy * data)984 static bool extract_if_dead(struct connectdata *conn,
985                             struct Curl_easy *data)
986 {
987   if(!CONN_INUSE(conn)) {
988     /* The check for a dead socket makes sense only if the connection isn't in
989        use */
990     bool dead;
991     struct curltime now = Curl_now();
992     if(conn_maxage(data, conn, now)) {
993       /* avoid check if already too old */
994       dead = TRUE;
995     }
996     else if(conn->handler->connection_check) {
997       /* The protocol has a special method for checking the state of the
998          connection. Use it to check if the connection is dead. */
999       unsigned int state;
1000 
1001       /* briefly attach the connection to this transfer for the purpose of
1002          checking it */
1003       Curl_attach_connnection(data, conn);
1004 
1005       state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD);
1006       dead = (state & CONNRESULT_DEAD);
1007       /* detach the connection again */
1008       Curl_detach_connnection(data);
1009 
1010     }
1011     else {
1012       /* Use the general method for determining the death of a connection */
1013       dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
1014     }
1015 
1016     if(dead) {
1017       infof(data, "Connection %ld seems to be dead!", conn->connection_id);
1018       Curl_conncache_remove_conn(data, conn, FALSE);
1019       return TRUE;
1020     }
1021   }
1022   return FALSE;
1023 }
1024 
1025 struct prunedead {
1026   struct Curl_easy *data;
1027   struct connectdata *extracted;
1028 };
1029 
1030 /*
1031  * Wrapper to use extract_if_dead() function in Curl_conncache_foreach()
1032  *
1033  */
call_extract_if_dead(struct Curl_easy * data,struct connectdata * conn,void * param)1034 static int call_extract_if_dead(struct Curl_easy *data,
1035                                 struct connectdata *conn, void *param)
1036 {
1037   struct prunedead *p = (struct prunedead *)param;
1038   if(extract_if_dead(conn, data)) {
1039     /* stop the iteration here, pass back the connection that was extracted */
1040     p->extracted = conn;
1041     return 1;
1042   }
1043   return 0; /* continue iteration */
1044 }
1045 
1046 /*
1047  * This function scans the connection cache for half-open/dead connections,
1048  * closes and removes them. The cleanup is done at most once per second.
1049  *
1050  * When called, this transfer has no connection attached.
1051  */
prune_dead_connections(struct Curl_easy * data)1052 static void prune_dead_connections(struct Curl_easy *data)
1053 {
1054   struct curltime now = Curl_now();
1055   timediff_t elapsed;
1056 
1057   DEBUGASSERT(!data->conn); /* no connection */
1058   CONNCACHE_LOCK(data);
1059   elapsed =
1060     Curl_timediff(now, data->state.conn_cache->last_cleanup);
1061   CONNCACHE_UNLOCK(data);
1062 
1063   if(elapsed >= 1000L) {
1064     struct prunedead prune;
1065     prune.data = data;
1066     prune.extracted = NULL;
1067     while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
1068                                  call_extract_if_dead)) {
1069       /* unlocked */
1070 
1071       /* remove connection from cache */
1072       Curl_conncache_remove_conn(data, prune.extracted, TRUE);
1073 
1074       /* disconnect it */
1075       (void)Curl_disconnect(data, prune.extracted, TRUE);
1076     }
1077     CONNCACHE_LOCK(data);
1078     data->state.conn_cache->last_cleanup = now;
1079     CONNCACHE_UNLOCK(data);
1080   }
1081 }
1082 
ssh_config_matches(struct connectdata * one,struct connectdata * two)1083 static bool ssh_config_matches(struct connectdata *one,
1084                                struct connectdata *two)
1085 {
1086   return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) &&
1087           Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub));
1088 }
1089 /*
1090  * Given one filled in connection struct (named needle), this function should
1091  * detect if there already is one that has all the significant details
1092  * exactly the same and thus should be used instead.
1093  *
1094  * If there is a match, this function returns TRUE - and has marked the
1095  * connection as 'in-use'. It must later be called with ConnectionDone() to
1096  * return back to 'idle' (unused) state.
1097  *
1098  * The force_reuse flag is set if the connection must be used.
1099  */
1100 static bool
ConnectionExists(struct Curl_easy * data,struct connectdata * needle,struct connectdata ** usethis,bool * force_reuse,bool * waitpipe)1101 ConnectionExists(struct Curl_easy *data,
1102                  struct connectdata *needle,
1103                  struct connectdata **usethis,
1104                  bool *force_reuse,
1105                  bool *waitpipe)
1106 {
1107   struct connectdata *check;
1108   struct connectdata *chosen = 0;
1109   bool foundPendingCandidate = FALSE;
1110   bool canmultiplex = IsMultiplexingPossible(data, needle);
1111   struct connectbundle *bundle;
1112   const char *hostbundle;
1113 
1114 #ifdef USE_NTLM
1115   bool wantNTLMhttp = ((data->state.authhost.want &
1116                         (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
1117                        (needle->handler->protocol & PROTO_FAMILY_HTTP));
1118 #ifndef CURL_DISABLE_PROXY
1119   bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
1120                             ((data->state.authproxy.want &
1121                               (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
1122                              (needle->handler->protocol & PROTO_FAMILY_HTTP)));
1123 #else
1124   bool wantProxyNTLMhttp = FALSE;
1125 #endif
1126 #endif
1127 
1128   *force_reuse = FALSE;
1129   *waitpipe = FALSE;
1130 
1131   /* Look up the bundle with all the connections to this particular host.
1132      Locks the connection cache, beware of early returns! */
1133   bundle = Curl_conncache_find_bundle(data, needle, data->state.conn_cache,
1134                                       &hostbundle);
1135   if(bundle) {
1136     /* Max pipe length is zero (unlimited) for multiplexed connections */
1137     struct Curl_llist_element *curr;
1138 
1139     infof(data, "Found bundle for host %s: %p [%s]",
1140           hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
1141                                        "can multiplex" : "serially"));
1142 
1143     /* We can't multiplex if we don't know anything about the server */
1144     if(canmultiplex) {
1145       if(bundle->multiuse == BUNDLE_UNKNOWN) {
1146         if(data->set.pipewait) {
1147           infof(data, "Server doesn't support multiplex yet, wait");
1148           *waitpipe = TRUE;
1149           CONNCACHE_UNLOCK(data);
1150           return FALSE; /* no re-use */
1151         }
1152 
1153         infof(data, "Server doesn't support multiplex (yet)");
1154         canmultiplex = FALSE;
1155       }
1156       if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
1157          !Curl_multiplex_wanted(data->multi)) {
1158         infof(data, "Could multiplex, but not asked to!");
1159         canmultiplex = FALSE;
1160       }
1161       if(bundle->multiuse == BUNDLE_NO_MULTIUSE) {
1162         infof(data, "Can not multiplex, even if we wanted to!");
1163         canmultiplex = FALSE;
1164       }
1165     }
1166 
1167     curr = bundle->conn_list.head;
1168     while(curr) {
1169       bool match = FALSE;
1170       size_t multiplexed = 0;
1171 
1172       /*
1173        * Note that if we use a HTTP proxy in normal mode (no tunneling), we
1174        * check connections to that proxy and not to the actual remote server.
1175        */
1176       check = curr->ptr;
1177       curr = curr->next;
1178 
1179       if(check->bits.connect_only || check->bits.close)
1180         /* connect-only or to-be-closed connections will not be reused */
1181         continue;
1182 
1183       if(extract_if_dead(check, data)) {
1184         /* disconnect it */
1185         (void)Curl_disconnect(data, check, TRUE);
1186         continue;
1187       }
1188 
1189       if(data->set.ipver != CURL_IPRESOLVE_WHATEVER
1190           && data->set.ipver != check->ip_version) {
1191         /* skip because the connection is not via the requested IP version */
1192         continue;
1193       }
1194 
1195       if(bundle->multiuse == BUNDLE_MULTIPLEX)
1196         multiplexed = CONN_INUSE(check);
1197 
1198       if(!canmultiplex) {
1199         if(multiplexed) {
1200           /* can only happen within multi handles, and means that another easy
1201              handle is using this connection */
1202           continue;
1203         }
1204 
1205         if(Curl_resolver_asynch()) {
1206           /* primary_ip[0] is NUL only if the resolving of the name hasn't
1207              completed yet and until then we don't re-use this connection */
1208           if(!check->primary_ip[0]) {
1209             infof(data,
1210                   "Connection #%ld is still name resolving, can't reuse",
1211                   check->connection_id);
1212             continue;
1213           }
1214         }
1215 
1216         if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
1217           foundPendingCandidate = TRUE;
1218           /* Don't pick a connection that hasn't connected yet */
1219           infof(data, "Connection #%ld isn't open enough, can't reuse",
1220                 check->connection_id);
1221           continue;
1222         }
1223       }
1224 
1225 #ifdef USE_UNIX_SOCKETS
1226       if(needle->unix_domain_socket) {
1227         if(!check->unix_domain_socket)
1228           continue;
1229         if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
1230           continue;
1231         if(needle->bits.abstract_unix_socket !=
1232            check->bits.abstract_unix_socket)
1233           continue;
1234       }
1235       else if(check->unix_domain_socket)
1236         continue;
1237 #endif
1238 
1239       if((needle->handler->flags&PROTOPT_SSL) !=
1240          (check->handler->flags&PROTOPT_SSL))
1241         /* don't do mixed SSL and non-SSL connections */
1242         if(get_protocol_family(check->handler) !=
1243            needle->handler->protocol || !check->bits.tls_upgraded)
1244           /* except protocols that have been upgraded via TLS */
1245           continue;
1246 
1247 #ifndef CURL_DISABLE_PROXY
1248       if(needle->bits.httpproxy != check->bits.httpproxy ||
1249          needle->bits.socksproxy != check->bits.socksproxy)
1250         continue;
1251 
1252       if(needle->bits.socksproxy &&
1253         !socks_proxy_info_matches(&needle->socks_proxy,
1254                                   &check->socks_proxy))
1255         continue;
1256 #endif
1257       if(needle->bits.conn_to_host != check->bits.conn_to_host)
1258         /* don't mix connections that use the "connect to host" feature and
1259          * connections that don't use this feature */
1260         continue;
1261 
1262       if(needle->bits.conn_to_port != check->bits.conn_to_port)
1263         /* don't mix connections that use the "connect to port" feature and
1264          * connections that don't use this feature */
1265         continue;
1266 
1267 #ifndef CURL_DISABLE_PROXY
1268       if(needle->bits.httpproxy) {
1269         if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
1270           continue;
1271 
1272         if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
1273           continue;
1274 
1275         if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
1276           /* use https proxy */
1277           if(needle->handler->flags&PROTOPT_SSL) {
1278             /* use double layer ssl */
1279             if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
1280                                         &check->proxy_ssl_config))
1281               continue;
1282             if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
1283               continue;
1284           }
1285           else {
1286             if(!Curl_ssl_config_matches(&needle->ssl_config,
1287                                         &check->ssl_config))
1288               continue;
1289             if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
1290               continue;
1291           }
1292         }
1293       }
1294 #endif
1295 
1296       if(!canmultiplex && CONN_INUSE(check))
1297         /* this request can't be multiplexed but the checked connection is
1298            already in use so we skip it */
1299         continue;
1300 
1301       if(CONN_INUSE(check)) {
1302         /* Subject for multiplex use if 'checks' belongs to the same multi
1303            handle as 'data' is. */
1304         struct Curl_llist_element *e = check->easyq.head;
1305         struct Curl_easy *entry = e->ptr;
1306         if(entry->multi != data->multi)
1307           continue;
1308       }
1309 
1310       if(needle->localdev || needle->localport) {
1311         /* If we are bound to a specific local end (IP+port), we must not
1312            re-use a random other one, although if we didn't ask for a
1313            particular one we can reuse one that was bound.
1314 
1315            This comparison is a bit rough and too strict. Since the input
1316            parameters can be specified in numerous ways and still end up the
1317            same it would take a lot of processing to make it really accurate.
1318            Instead, this matching will assume that re-uses of bound connections
1319            will most likely also re-use the exact same binding parameters and
1320            missing out a few edge cases shouldn't hurt anyone very much.
1321         */
1322         if((check->localport != needle->localport) ||
1323            (check->localportrange != needle->localportrange) ||
1324            (needle->localdev &&
1325             (!check->localdev || strcmp(check->localdev, needle->localdev))))
1326           continue;
1327       }
1328 
1329       if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
1330         /* This protocol requires credentials per connection,
1331            so verify that we're using the same name and password as well */
1332         if(strcmp(needle->user, check->user) ||
1333            strcmp(needle->passwd, check->passwd) ||
1334            !Curl_safecmp(needle->sasl_authzid, check->sasl_authzid) ||
1335            !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
1336           /* one of them was different */
1337           continue;
1338         }
1339       }
1340 
1341       /* If multiplexing isn't enabled on the h2 connection and h1 is
1342          explicitly requested, handle it: */
1343       if((needle->handler->protocol & PROTO_FAMILY_HTTP) &&
1344          (check->httpversion >= 20) &&
1345          (data->state.httpwant < CURL_HTTP_VERSION_2_0))
1346         continue;
1347 
1348       if(get_protocol_family(needle->handler) == PROTO_FAMILY_SSH) {
1349         if(!ssh_config_matches(needle, check))
1350           continue;
1351       }
1352 
1353       if((needle->handler->flags&PROTOPT_SSL)
1354 #ifndef CURL_DISABLE_PROXY
1355          || !needle->bits.httpproxy || needle->bits.tunnel_proxy
1356 #endif
1357         ) {
1358         /* The requested connection does not use a HTTP proxy or it uses SSL or
1359            it is a non-SSL protocol tunneled or it is a non-SSL protocol which
1360            is allowed to be upgraded via TLS */
1361 
1362         if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
1363             (get_protocol_family(check->handler) ==
1364              needle->handler->protocol && check->bits.tls_upgraded)) &&
1365            (!needle->bits.conn_to_host || strcasecompare(
1366             needle->conn_to_host.name, check->conn_to_host.name)) &&
1367            (!needle->bits.conn_to_port ||
1368              needle->conn_to_port == check->conn_to_port) &&
1369            strcasecompare(needle->host.name, check->host.name) &&
1370            needle->remote_port == check->remote_port) {
1371           /* The schemes match or the protocol family is the same and the
1372              previous connection was TLS upgraded, and the hostname and host
1373              port match */
1374           if(needle->handler->flags & PROTOPT_SSL) {
1375             /* This is a SSL connection so verify that we're using the same
1376                SSL options as well */
1377             if(!Curl_ssl_config_matches(&needle->ssl_config,
1378                                         &check->ssl_config)) {
1379               DEBUGF(infof(data,
1380                            "Connection #%ld has different SSL parameters, "
1381                            "can't reuse",
1382                            check->connection_id));
1383               continue;
1384             }
1385             if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
1386               foundPendingCandidate = TRUE;
1387               DEBUGF(infof(data,
1388                            "Connection #%ld has not started SSL connect, "
1389                            "can't reuse",
1390                            check->connection_id));
1391               continue;
1392             }
1393           }
1394           match = TRUE;
1395         }
1396       }
1397       else {
1398         /* The requested connection is using the same HTTP proxy in normal
1399            mode (no tunneling) */
1400         match = TRUE;
1401       }
1402 
1403       if(match) {
1404 #if defined(USE_NTLM)
1405         /* If we are looking for an HTTP+NTLM connection, check if this is
1406            already authenticating with the right credentials. If not, keep
1407            looking so that we can reuse NTLM connections if
1408            possible. (Especially we must not reuse the same connection if
1409            partway through a handshake!) */
1410         if(wantNTLMhttp) {
1411           if(strcmp(needle->user, check->user) ||
1412              strcmp(needle->passwd, check->passwd)) {
1413 
1414             /* we prefer a credential match, but this is at least a connection
1415                that can be reused and "upgraded" to NTLM */
1416             if(check->http_ntlm_state == NTLMSTATE_NONE)
1417               chosen = check;
1418             continue;
1419           }
1420         }
1421         else if(check->http_ntlm_state != NTLMSTATE_NONE) {
1422           /* Connection is using NTLM auth but we don't want NTLM */
1423           continue;
1424         }
1425 
1426 #ifndef CURL_DISABLE_PROXY
1427         /* Same for Proxy NTLM authentication */
1428         if(wantProxyNTLMhttp) {
1429           /* Both check->http_proxy.user and check->http_proxy.passwd can be
1430            * NULL */
1431           if(!check->http_proxy.user || !check->http_proxy.passwd)
1432             continue;
1433 
1434           if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
1435              strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
1436             continue;
1437         }
1438         else if(check->proxy_ntlm_state != NTLMSTATE_NONE) {
1439           /* Proxy connection is using NTLM auth but we don't want NTLM */
1440           continue;
1441         }
1442 #endif
1443         if(wantNTLMhttp || wantProxyNTLMhttp) {
1444           /* Credentials are already checked, we can use this connection */
1445           chosen = check;
1446 
1447           if((wantNTLMhttp &&
1448              (check->http_ntlm_state != NTLMSTATE_NONE)) ||
1449               (wantProxyNTLMhttp &&
1450                (check->proxy_ntlm_state != NTLMSTATE_NONE))) {
1451             /* We must use this connection, no other */
1452             *force_reuse = TRUE;
1453             break;
1454           }
1455 
1456           /* Continue look up for a better connection */
1457           continue;
1458         }
1459 #endif
1460         if(canmultiplex) {
1461           /* We can multiplex if we want to. Let's continue looking for
1462              the optimal connection to use. */
1463 
1464           if(!multiplexed) {
1465             /* We have the optimal connection. Let's stop looking. */
1466             chosen = check;
1467             break;
1468           }
1469 
1470 #ifdef USE_NGHTTP2
1471           /* If multiplexed, make sure we don't go over concurrency limit */
1472           if(check->bits.multiplex) {
1473             /* Multiplexed connections can only be HTTP/2 for now */
1474             struct http_conn *httpc = &check->proto.httpc;
1475             if(multiplexed >= httpc->settings.max_concurrent_streams) {
1476               infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)",
1477                     multiplexed);
1478               continue;
1479             }
1480             else if(multiplexed >=
1481                     Curl_multi_max_concurrent_streams(data->multi)) {
1482               infof(data, "client side MAX_CONCURRENT_STREAMS reached"
1483                     ", skip (%zu)",
1484                     multiplexed);
1485               continue;
1486             }
1487           }
1488 #endif
1489           /* When not multiplexed, we have a match here! */
1490           chosen = check;
1491           infof(data, "Multiplexed connection found!");
1492           break;
1493         }
1494         else {
1495           /* We have found a connection. Let's stop searching. */
1496           chosen = check;
1497           break;
1498         }
1499       }
1500     }
1501   }
1502 
1503   if(chosen) {
1504     /* mark it as used before releasing the lock */
1505     Curl_attach_connnection(data, chosen);
1506     CONNCACHE_UNLOCK(data);
1507     *usethis = chosen;
1508     return TRUE; /* yes, we found one to use! */
1509   }
1510   CONNCACHE_UNLOCK(data);
1511 
1512   if(foundPendingCandidate && data->set.pipewait) {
1513     infof(data,
1514           "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set");
1515     *waitpipe = TRUE;
1516   }
1517 
1518   return FALSE; /* no matching connecting exists */
1519 }
1520 
1521 /*
1522  * verboseconnect() displays verbose information after a connect
1523  */
1524 #ifndef CURL_DISABLE_VERBOSE_STRINGS
Curl_verboseconnect(struct Curl_easy * data,struct connectdata * conn)1525 void Curl_verboseconnect(struct Curl_easy *data,
1526                          struct connectdata *conn)
1527 {
1528   if(data->set.verbose)
1529     infof(data, "Connected to %s (%s) port %u (#%ld)",
1530 #ifndef CURL_DISABLE_PROXY
1531           conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
1532           conn->bits.httpproxy ? conn->http_proxy.host.dispname :
1533 #endif
1534           conn->bits.conn_to_host ? conn->conn_to_host.dispname :
1535           conn->host.dispname,
1536           conn->primary_ip, conn->port, conn->connection_id);
1537 }
1538 #endif
1539 
1540 /*
1541  * Helpers for IDNA conversions.
1542  */
Curl_is_ASCII_name(const char * hostname)1543 bool Curl_is_ASCII_name(const char *hostname)
1544 {
1545   /* get an UNSIGNED local version of the pointer */
1546   const unsigned char *ch = (const unsigned char *)hostname;
1547 
1548   if(!hostname) /* bad input, consider it ASCII! */
1549     return TRUE;
1550 
1551   while(*ch) {
1552     if(*ch++ & 0x80)
1553       return FALSE;
1554   }
1555   return TRUE;
1556 }
1557 
1558 /*
1559  * Strip single trailing dot in the hostname,
1560  * primarily for SNI and http host header.
1561  */
strip_trailing_dot(struct hostname * host)1562 static void strip_trailing_dot(struct hostname *host)
1563 {
1564   size_t len;
1565   if(!host || !host->name)
1566     return;
1567   len = strlen(host->name);
1568   if(len && (host->name[len-1] == '.'))
1569     host->name[len-1] = 0;
1570 }
1571 
1572 /*
1573  * Perform any necessary IDN conversion of hostname
1574  */
Curl_idnconvert_hostname(struct Curl_easy * data,struct hostname * host)1575 CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
1576                                   struct hostname *host)
1577 {
1578 #ifndef USE_LIBIDN2
1579   (void)data;
1580   (void)data;
1581 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
1582   (void)data;
1583 #endif
1584 
1585   /* set the name we use to display the host name */
1586   host->dispname = host->name;
1587 
1588   /* Check name for non-ASCII and convert hostname to ACE form if we can */
1589   if(!Curl_is_ASCII_name(host->name)) {
1590 #ifdef USE_LIBIDN2
1591     if(idn2_check_version(IDN2_VERSION)) {
1592       char *ace_hostname = NULL;
1593 #if IDN2_VERSION_NUMBER >= 0x00140000
1594       /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
1595          IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
1596          processing. */
1597       int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
1598 #else
1599       int flags = IDN2_NFC_INPUT;
1600 #endif
1601       int rc = IDN2_LOOKUP(host->name, &ace_hostname, flags);
1602       if(rc != IDN2_OK)
1603         /* fallback to TR46 Transitional mode for better IDNA2003
1604            compatibility */
1605         rc = IDN2_LOOKUP(host->name, &ace_hostname,
1606                          IDN2_TRANSITIONAL);
1607       if(rc == IDN2_OK) {
1608         host->encalloc = (char *)ace_hostname;
1609         /* change the name pointer to point to the encoded hostname */
1610         host->name = host->encalloc;
1611       }
1612       else {
1613         failf(data, "Failed to convert %s to ACE; %s", host->name,
1614               idn2_strerror(rc));
1615         return CURLE_URL_MALFORMAT;
1616       }
1617     }
1618 #elif defined(USE_WIN32_IDN)
1619     char *ace_hostname = NULL;
1620 
1621     if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
1622       host->encalloc = ace_hostname;
1623       /* change the name pointer to point to the encoded hostname */
1624       host->name = host->encalloc;
1625     }
1626     else {
1627       char buffer[STRERROR_LEN];
1628       failf(data, "Failed to convert %s to ACE; %s", host->name,
1629             Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
1630       return CURLE_URL_MALFORMAT;
1631     }
1632 #else
1633     infof(data, "IDN support not present, can't parse Unicode domains");
1634 #endif
1635   }
1636   return CURLE_OK;
1637 }
1638 
1639 /*
1640  * Frees data allocated by idnconvert_hostname()
1641  */
Curl_free_idnconverted_hostname(struct hostname * host)1642 void Curl_free_idnconverted_hostname(struct hostname *host)
1643 {
1644 #if defined(USE_LIBIDN2)
1645   if(host->encalloc) {
1646     idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
1647                                  allocated by libidn */
1648     host->encalloc = NULL;
1649   }
1650 #elif defined(USE_WIN32_IDN)
1651   free(host->encalloc); /* must be freed with free() since this was
1652                            allocated by curl_win32_idn_to_ascii */
1653   host->encalloc = NULL;
1654 #else
1655   (void)host;
1656 #endif
1657 }
1658 
1659 /*
1660  * Allocate and initialize a new connectdata object.
1661  */
allocate_conn(struct Curl_easy * data)1662 static struct connectdata *allocate_conn(struct Curl_easy *data)
1663 {
1664   struct connectdata *conn = calloc(1, sizeof(struct connectdata));
1665   if(!conn)
1666     return NULL;
1667 
1668 #ifdef USE_SSL
1669   /* The SSL backend-specific data (ssl_backend_data) objects are allocated as
1670      a separate array to ensure suitable alignment.
1671      Note that these backend pointers can be swapped by vtls (eg ssl backend
1672      data becomes proxy backend data). */
1673   {
1674     size_t sslsize = Curl_ssl->sizeof_ssl_backend_data;
1675     char *ssl = calloc(4, sslsize);
1676     if(!ssl) {
1677       free(conn);
1678       return NULL;
1679     }
1680     conn->ssl_extra = ssl;
1681     conn->ssl[0].backend = (void *)ssl;
1682     conn->ssl[1].backend = (void *)(ssl + sslsize);
1683 #ifndef CURL_DISABLE_PROXY
1684     conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize);
1685     conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize);
1686 #endif
1687   }
1688 #endif
1689 
1690   conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
1691                                            already from start to avoid NULL
1692                                            situations and checks */
1693 
1694   /* and we setup a few fields in case we end up actually using this struct */
1695 
1696   conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
1697   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
1698   conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
1699   conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
1700   conn->connection_id = -1;    /* no ID */
1701   conn->port = -1; /* unknown at this point */
1702   conn->remote_port = -1; /* unknown at this point */
1703 #if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
1704   conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
1705   conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
1706 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */
1707 
1708   /* Default protocol-independent behavior doesn't support persistent
1709      connections, so we set this to force-close. Protocols that support
1710      this need to set this to FALSE in their "curl_do" functions. */
1711   connclose(conn, "Default to force-close");
1712 
1713   /* Store creation time to help future close decision making */
1714   conn->created = Curl_now();
1715 
1716   /* Store current time to give a baseline to keepalive connection times. */
1717   conn->keepalive = Curl_now();
1718 
1719 #ifndef CURL_DISABLE_PROXY
1720   conn->http_proxy.proxytype = data->set.proxytype;
1721   conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
1722 
1723   /* note that these two proxy bits are now just on what looks to be
1724      requested, they may be altered down the road */
1725   conn->bits.proxy = (data->set.str[STRING_PROXY] &&
1726                       *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
1727   conn->bits.httpproxy = (conn->bits.proxy &&
1728                           (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
1729                            conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
1730                            conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
1731                            TRUE : FALSE;
1732   conn->bits.socksproxy = (conn->bits.proxy &&
1733                            !conn->bits.httpproxy) ? TRUE : FALSE;
1734 
1735   if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) {
1736     conn->bits.proxy = TRUE;
1737     conn->bits.socksproxy = TRUE;
1738   }
1739 
1740   conn->bits.proxy_user_passwd =
1741     (data->state.aptr.proxyuser) ? TRUE : FALSE;
1742   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
1743 #endif /* CURL_DISABLE_PROXY */
1744 
1745   conn->bits.user_passwd = (data->state.aptr.user) ? TRUE : FALSE;
1746 #ifndef CURL_DISABLE_FTP
1747   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
1748   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
1749 #endif
1750   conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
1751   conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
1752   conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
1753   conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options;
1754 #ifdef USE_TLS_SRP
1755 #endif
1756 #ifndef CURL_DISABLE_PROXY
1757   conn->proxy_ssl_config.verifystatus =
1758     data->set.proxy_ssl.primary.verifystatus;
1759   conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
1760   conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
1761   conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options;
1762 #ifdef USE_TLS_SRP
1763 #endif
1764 #endif
1765   conn->ip_version = data->set.ipver;
1766   conn->bits.connect_only = data->set.connect_only;
1767   conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
1768 
1769 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
1770     defined(NTLM_WB_ENABLED)
1771   conn->ntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
1772   conn->proxyntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
1773 #endif
1774 
1775   /* Initialize the easy handle list */
1776   Curl_llist_init(&conn->easyq, NULL);
1777 
1778 #ifdef HAVE_GSSAPI
1779   conn->data_prot = PROT_CLEAR;
1780 #endif
1781 
1782   /* Store the local bind parameters that will be used for this connection */
1783   if(data->set.str[STRING_DEVICE]) {
1784     conn->localdev = strdup(data->set.str[STRING_DEVICE]);
1785     if(!conn->localdev)
1786       goto error;
1787   }
1788   conn->localportrange = data->set.localportrange;
1789   conn->localport = data->set.localport;
1790 
1791   /* the close socket stuff needs to be copied to the connection struct as
1792      it may live on without (this specific) Curl_easy */
1793   conn->fclosesocket = data->set.fclosesocket;
1794   conn->closesocket_client = data->set.closesocket_client;
1795   conn->lastused = Curl_now(); /* used now */
1796 
1797   return conn;
1798   error:
1799 
1800   Curl_llist_destroy(&conn->easyq, NULL);
1801   free(conn->localdev);
1802 #ifdef USE_SSL
1803   free(conn->ssl_extra);
1804 #endif
1805   free(conn);
1806   return NULL;
1807 }
1808 
1809 /* returns the handler if the given scheme is built-in */
Curl_builtin_scheme(const char * scheme)1810 const struct Curl_handler *Curl_builtin_scheme(const char *scheme)
1811 {
1812   const struct Curl_handler * const *pp;
1813   const struct Curl_handler *p;
1814   /* Scan protocol handler table and match against 'scheme'. The handler may
1815      be changed later when the protocol specific setup function is called. */
1816   for(pp = protocols; (p = *pp) != NULL; pp++)
1817     if(strcasecompare(p->scheme, scheme))
1818       /* Protocol found in table. Check if allowed */
1819       return p;
1820   return NULL; /* not found */
1821 }
1822 
1823 
findprotocol(struct Curl_easy * data,struct connectdata * conn,const char * protostr)1824 static CURLcode findprotocol(struct Curl_easy *data,
1825                              struct connectdata *conn,
1826                              const char *protostr)
1827 {
1828   const struct Curl_handler *p = Curl_builtin_scheme(protostr);
1829 
1830   if(p && /* Protocol found in table. Check if allowed */
1831      (data->set.allowed_protocols & p->protocol)) {
1832 
1833     /* it is allowed for "normal" request, now do an extra check if this is
1834        the result of a redirect */
1835     if(data->state.this_is_a_follow &&
1836        !(data->set.redir_protocols & p->protocol))
1837       /* nope, get out */
1838       ;
1839     else {
1840       /* Perform setup complement if some. */
1841       conn->handler = conn->given = p;
1842 
1843       /* 'port' and 'remote_port' are set in setup_connection_internals() */
1844       return CURLE_OK;
1845     }
1846   }
1847 
1848   /* The protocol was not found in the table, but we don't have to assign it
1849      to anything since it is already assigned to a dummy-struct in the
1850      create_conn() function when the connectdata struct is allocated. */
1851   failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
1852         protostr);
1853 
1854   return CURLE_UNSUPPORTED_PROTOCOL;
1855 }
1856 
1857 
Curl_uc_to_curlcode(CURLUcode uc)1858 CURLcode Curl_uc_to_curlcode(CURLUcode uc)
1859 {
1860   switch(uc) {
1861   default:
1862     return CURLE_URL_MALFORMAT;
1863   case CURLUE_UNSUPPORTED_SCHEME:
1864     return CURLE_UNSUPPORTED_PROTOCOL;
1865   case CURLUE_OUT_OF_MEMORY:
1866     return CURLE_OUT_OF_MEMORY;
1867   case CURLUE_USER_NOT_ALLOWED:
1868     return CURLE_LOGIN_DENIED;
1869   }
1870 }
1871 
1872 /*
1873  * If the URL was set with an IPv6 numerical address with a zone id part, set
1874  * the scope_id based on that!
1875  */
1876 
zonefrom_url(CURLU * uh,struct Curl_easy * data,struct connectdata * conn)1877 static void zonefrom_url(CURLU *uh, struct Curl_easy *data,
1878                          struct connectdata *conn)
1879 {
1880   char *zoneid;
1881   CURLUcode uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
1882 #ifdef CURL_DISABLE_VERBOSE_STRINGS
1883   (void)data;
1884 #endif
1885 
1886   if(!uc && zoneid) {
1887     char *endp;
1888     unsigned long scope = strtoul(zoneid, &endp, 10);
1889     if(!*endp && (scope < UINT_MAX))
1890       /* A plain number, use it directly as a scope id. */
1891       conn->scope_id = (unsigned int)scope;
1892 #if defined(HAVE_IF_NAMETOINDEX)
1893     else {
1894 #elif defined(WIN32)
1895     else if(Curl_if_nametoindex) {
1896 #endif
1897 
1898 #if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32)
1899       /* Zone identifier is not numeric */
1900       unsigned int scopeidx = 0;
1901 #if defined(WIN32)
1902       scopeidx = Curl_if_nametoindex(zoneid);
1903 #else
1904       scopeidx = if_nametoindex(zoneid);
1905 #endif
1906       if(!scopeidx)
1907         infof(data, "Invalid zoneid: %s; %s", zoneid,
1908               strerror(errno));
1909       else
1910         conn->scope_id = scopeidx;
1911     }
1912 #endif /* HAVE_IF_NAMETOINDEX || WIN32 */
1913 
1914     free(zoneid);
1915   }
1916 }
1917 
1918 /*
1919  * Parse URL and fill in the relevant members of the connection struct.
1920  */
1921 static CURLcode parseurlandfillconn(struct Curl_easy *data,
1922                                     struct connectdata *conn)
1923 {
1924   CURLcode result;
1925   CURLU *uh;
1926   CURLUcode uc;
1927   char *hostname;
1928   bool use_set_uh = (data->set.uh && !data->state.this_is_a_follow);
1929 
1930   up_free(data); /* cleanup previous leftovers first */
1931 
1932   /* parse the URL */
1933   if(use_set_uh) {
1934     uh = data->state.uh = curl_url_dup(data->set.uh);
1935   }
1936   else {
1937     uh = data->state.uh = curl_url();
1938   }
1939 
1940   if(!uh)
1941     return CURLE_OUT_OF_MEMORY;
1942 
1943   if(data->set.str[STRING_DEFAULT_PROTOCOL] &&
1944      !Curl_is_absolute_url(data->state.url, NULL, MAX_SCHEME_LEN)) {
1945     char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL],
1946                         data->state.url);
1947     if(!url)
1948       return CURLE_OUT_OF_MEMORY;
1949     if(data->state.url_alloc)
1950       free(data->state.url);
1951     data->state.url = url;
1952     data->state.url_alloc = TRUE;
1953   }
1954 
1955   if(!use_set_uh) {
1956     char *newurl;
1957     uc = curl_url_set(uh, CURLUPART_URL, data->state.url,
1958                     CURLU_GUESS_SCHEME |
1959                     CURLU_NON_SUPPORT_SCHEME |
1960                     (data->set.disallow_username_in_url ?
1961                      CURLU_DISALLOW_USER : 0) |
1962                     (data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
1963     if(uc) {
1964       DEBUGF(infof(data, "curl_url_set rejected %s", data->state.url));
1965       return Curl_uc_to_curlcode(uc);
1966     }
1967 
1968     /* after it was parsed, get the generated normalized version */
1969     uc = curl_url_get(uh, CURLUPART_URL, &newurl, 0);
1970     if(uc)
1971       return Curl_uc_to_curlcode(uc);
1972     if(data->state.url_alloc)
1973       free(data->state.url);
1974     data->state.url = newurl;
1975     data->state.url_alloc = TRUE;
1976   }
1977 
1978   uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
1979   if(uc)
1980     return Curl_uc_to_curlcode(uc);
1981 
1982   uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0);
1983   if(uc) {
1984     if(!strcasecompare("file", data->state.up.scheme))
1985       return CURLE_OUT_OF_MEMORY;
1986   }
1987 
1988   hostname = data->state.up.hostname;
1989 
1990   if(hostname && hostname[0] == '[') {
1991     /* This looks like an IPv6 address literal. See if there is an address
1992        scope. */
1993     size_t hlen;
1994     conn->bits.ipv6_ip = TRUE;
1995     /* cut off the brackets! */
1996     hostname++;
1997     hlen = strlen(hostname);
1998     hostname[hlen - 1] = 0;
1999 
2000     zonefrom_url(uh, data, conn);
2001   }
2002 
2003   /* make sure the connect struct gets its own copy of the host name */
2004   conn->host.rawalloc = strdup(hostname ? hostname : "");
2005   if(!conn->host.rawalloc)
2006     return CURLE_OUT_OF_MEMORY;
2007   conn->host.name = conn->host.rawalloc;
2008 
2009   /*************************************************************
2010    * IDN-convert the hostnames
2011    *************************************************************/
2012   result = Curl_idnconvert_hostname(data, &conn->host);
2013   if(result)
2014     return result;
2015   if(conn->bits.conn_to_host) {
2016     result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
2017     if(result)
2018       return result;
2019   }
2020 #ifndef CURL_DISABLE_PROXY
2021   if(conn->bits.httpproxy) {
2022     result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
2023     if(result)
2024       return result;
2025   }
2026   if(conn->bits.socksproxy) {
2027     result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
2028     if(result)
2029       return result;
2030   }
2031 #endif
2032 
2033 #ifndef CURL_DISABLE_HSTS
2034   /* HSTS upgrade */
2035   if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
2036     /* This MUST use the IDN decoded name */
2037     if(Curl_hsts(data->hsts, conn->host.name, TRUE)) {
2038       char *url;
2039       Curl_safefree(data->state.up.scheme);
2040       uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
2041       if(uc)
2042         return Curl_uc_to_curlcode(uc);
2043       if(data->state.url_alloc)
2044         Curl_safefree(data->state.url);
2045       /* after update, get the updated version */
2046       uc = curl_url_get(uh, CURLUPART_URL, &url, 0);
2047       if(uc)
2048         return Curl_uc_to_curlcode(uc);
2049       uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
2050       if(uc) {
2051         free(url);
2052         return Curl_uc_to_curlcode(uc);
2053       }
2054       data->state.url = url;
2055       data->state.url_alloc = TRUE;
2056       infof(data, "Switched from HTTP to HTTPS due to HSTS => %s",
2057             data->state.url);
2058     }
2059   }
2060 #endif
2061 
2062   result = findprotocol(data, conn, data->state.up.scheme);
2063   if(result)
2064     return result;
2065 
2066   /*
2067    * User name and password set with their own options override the
2068    * credentials possibly set in the URL.
2069    */
2070   if(!data->state.aptr.user) {
2071     /* we don't use the URL API's URL decoder option here since it rejects
2072        control codes and we want to allow them for some schemes in the user
2073        and password fields */
2074     uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
2075     if(!uc) {
2076       char *decoded;
2077       result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL,
2078                               conn->handler->flags&PROTOPT_USERPWDCTRL ?
2079                               REJECT_ZERO : REJECT_CTRL);
2080       if(result)
2081         return result;
2082       conn->user = decoded;
2083       conn->bits.user_passwd = TRUE;
2084       result = Curl_setstropt(&data->state.aptr.user, decoded);
2085       if(result)
2086         return result;
2087     }
2088     else if(uc != CURLUE_NO_USER)
2089       return Curl_uc_to_curlcode(uc);
2090   }
2091 
2092   if(!data->state.aptr.passwd) {
2093     uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
2094     if(!uc) {
2095       char *decoded;
2096       result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL,
2097                               conn->handler->flags&PROTOPT_USERPWDCTRL ?
2098                               REJECT_ZERO : REJECT_CTRL);
2099       if(result)
2100         return result;
2101       conn->passwd = decoded;
2102       conn->bits.user_passwd = TRUE;
2103       result = Curl_setstropt(&data->state.aptr.passwd, decoded);
2104       if(result)
2105         return result;
2106     }
2107     else if(uc != CURLUE_NO_PASSWORD)
2108       return Curl_uc_to_curlcode(uc);
2109   }
2110 
2111   uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options,
2112                     CURLU_URLDECODE);
2113   if(!uc) {
2114     conn->options = strdup(data->state.up.options);
2115     if(!conn->options)
2116       return CURLE_OUT_OF_MEMORY;
2117   }
2118   else if(uc != CURLUE_NO_OPTIONS)
2119     return Curl_uc_to_curlcode(uc);
2120 
2121   uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, 0);
2122   if(uc)
2123     return Curl_uc_to_curlcode(uc);
2124 
2125   uc = curl_url_get(uh, CURLUPART_PORT, &data->state.up.port,
2126                     CURLU_DEFAULT_PORT);
2127   if(uc) {
2128     if(!strcasecompare("file", data->state.up.scheme))
2129       return CURLE_OUT_OF_MEMORY;
2130   }
2131   else {
2132     unsigned long port = strtoul(data->state.up.port, NULL, 10);
2133     conn->port = conn->remote_port =
2134       (data->set.use_port && data->state.allow_port) ?
2135       (int)data->set.use_port : curlx_ultous(port);
2136   }
2137 
2138   (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
2139 
2140   if(data->set.scope_id)
2141     /* Override any scope that was set above.  */
2142     conn->scope_id = data->set.scope_id;
2143 
2144   return CURLE_OK;
2145 }
2146 
2147 
2148 /*
2149  * If we're doing a resumed transfer, we need to setup our stuff
2150  * properly.
2151  */
2152 static CURLcode setup_range(struct Curl_easy *data)
2153 {
2154   struct UrlState *s = &data->state;
2155   s->resume_from = data->set.set_resume_from;
2156   if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
2157     if(s->rangestringalloc)
2158       free(s->range);
2159 
2160     if(s->resume_from)
2161       s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from);
2162     else
2163       s->range = strdup(data->set.str[STRING_SET_RANGE]);
2164 
2165     s->rangestringalloc = (s->range) ? TRUE : FALSE;
2166 
2167     if(!s->range)
2168       return CURLE_OUT_OF_MEMORY;
2169 
2170     /* tell ourselves to fetch this range */
2171     s->use_range = TRUE;        /* enable range download */
2172   }
2173   else
2174     s->use_range = FALSE; /* disable range download */
2175 
2176   return CURLE_OK;
2177 }
2178 
2179 
2180 /*
2181  * setup_connection_internals() -
2182  *
2183  * Setup connection internals specific to the requested protocol in the
2184  * Curl_easy. This is inited and setup before the connection is made but
2185  * is about the particular protocol that is to be used.
2186  *
2187  * This MUST get called after proxy magic has been figured out.
2188  */
2189 static CURLcode setup_connection_internals(struct Curl_easy *data,
2190                                            struct connectdata *conn)
2191 {
2192   const struct Curl_handler *p;
2193   CURLcode result;
2194 
2195   /* Perform setup complement if some. */
2196   p = conn->handler;
2197 
2198   if(p->setup_connection) {
2199     result = (*p->setup_connection)(data, conn);
2200 
2201     if(result)
2202       return result;
2203 
2204     p = conn->handler;              /* May have changed. */
2205   }
2206 
2207   if(conn->port < 0)
2208     /* we check for -1 here since if proxy was detected already, this
2209        was very likely already set to the proxy port */
2210     conn->port = p->defport;
2211 
2212   return CURLE_OK;
2213 }
2214 
2215 /*
2216  * Curl_free_request_state() should free temp data that was allocated in the
2217  * Curl_easy for this single request.
2218  */
2219 
2220 void Curl_free_request_state(struct Curl_easy *data)
2221 {
2222   Curl_safefree(data->req.p.http);
2223   Curl_safefree(data->req.newurl);
2224 
2225 #ifndef CURL_DISABLE_DOH
2226   if(data->req.doh) {
2227     Curl_close(&data->req.doh->probe[0].easy);
2228     Curl_close(&data->req.doh->probe[1].easy);
2229   }
2230 #endif
2231 }
2232 
2233 
2234 #ifndef CURL_DISABLE_PROXY
2235 /****************************************************************
2236 * Checks if the host is in the noproxy list. returns true if it matches
2237 * and therefore the proxy should NOT be used.
2238 ****************************************************************/
2239 static bool check_noproxy(const char *name, const char *no_proxy)
2240 {
2241   /* no_proxy=domain1.dom,host.domain2.dom
2242    *   (a comma-separated list of hosts which should
2243    *   not be proxied, or an asterisk to override
2244    *   all proxy variables)
2245    */
2246   if(no_proxy && no_proxy[0]) {
2247     size_t tok_start;
2248     size_t tok_end;
2249     const char *separator = ", ";
2250     size_t no_proxy_len;
2251     size_t namelen;
2252     char *endptr;
2253     if(strcasecompare("*", no_proxy)) {
2254       return TRUE;
2255     }
2256 
2257     /* NO_PROXY was specified and it wasn't just an asterisk */
2258 
2259     no_proxy_len = strlen(no_proxy);
2260     if(name[0] == '[') {
2261       /* IPv6 numerical address */
2262       endptr = strchr(name, ']');
2263       if(!endptr)
2264         return FALSE;
2265       name++;
2266       namelen = endptr - name;
2267     }
2268     else
2269       namelen = strlen(name);
2270 
2271     for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
2272       while(tok_start < no_proxy_len &&
2273             strchr(separator, no_proxy[tok_start]) != NULL) {
2274         /* Look for the beginning of the token. */
2275         ++tok_start;
2276       }
2277 
2278       if(tok_start == no_proxy_len)
2279         break; /* It was all trailing separator chars, no more tokens. */
2280 
2281       for(tok_end = tok_start; tok_end < no_proxy_len &&
2282             strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
2283         /* Look for the end of the token. */
2284         ;
2285 
2286       /* To match previous behavior, where it was necessary to specify
2287        * ".local.com" to prevent matching "notlocal.com", we will leave
2288        * the '.' off.
2289        */
2290       if(no_proxy[tok_start] == '.')
2291         ++tok_start;
2292 
2293       if((tok_end - tok_start) <= namelen) {
2294         /* Match the last part of the name to the domain we are checking. */
2295         const char *checkn = name + namelen - (tok_end - tok_start);
2296         if(strncasecompare(no_proxy + tok_start, checkn,
2297                            tok_end - tok_start)) {
2298           if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
2299             /* We either have an exact match, or the previous character is a .
2300              * so it is within the same domain, so no proxy for this host.
2301              */
2302             return TRUE;
2303           }
2304         }
2305       } /* if((tok_end - tok_start) <= namelen) */
2306     } /* for(tok_start = 0; tok_start < no_proxy_len;
2307          tok_start = tok_end + 1) */
2308   } /* NO_PROXY was specified and it wasn't just an asterisk */
2309 
2310   return FALSE;
2311 }
2312 
2313 #ifndef CURL_DISABLE_HTTP
2314 /****************************************************************
2315 * Detect what (if any) proxy to use. Remember that this selects a host
2316 * name and is not limited to HTTP proxies only.
2317 * The returned pointer must be freed by the caller (unless NULL)
2318 ****************************************************************/
2319 static char *detect_proxy(struct Curl_easy *data,
2320                           struct connectdata *conn)
2321 {
2322   char *proxy = NULL;
2323 
2324   /* If proxy was not specified, we check for default proxy environment
2325    * variables, to enable i.e Lynx compliance:
2326    *
2327    * http_proxy=http://some.server.dom:port/
2328    * https_proxy=http://some.server.dom:port/
2329    * ftp_proxy=http://some.server.dom:port/
2330    * no_proxy=domain1.dom,host.domain2.dom
2331    *   (a comma-separated list of hosts which should
2332    *   not be proxied, or an asterisk to override
2333    *   all proxy variables)
2334    * all_proxy=http://some.server.dom:port/
2335    *   (seems to exist for the CERN www lib. Probably
2336    *   the first to check for.)
2337    *
2338    * For compatibility, the all-uppercase versions of these variables are
2339    * checked if the lowercase versions don't exist.
2340    */
2341   char proxy_env[128];
2342   const char *protop = conn->handler->scheme;
2343   char *envp = proxy_env;
2344   char *prox;
2345 #ifdef CURL_DISABLE_VERBOSE_STRINGS
2346   (void)data;
2347 #endif
2348 
2349   /* Now, build <protocol>_proxy and check for such a one to use */
2350   while(*protop)
2351     *envp++ = (char)tolower((int)*protop++);
2352 
2353   /* append _proxy */
2354   strcpy(envp, "_proxy");
2355 
2356   /* read the protocol proxy: */
2357   prox = curl_getenv(proxy_env);
2358 
2359   /*
2360    * We don't try the uppercase version of HTTP_PROXY because of
2361    * security reasons:
2362    *
2363    * When curl is used in a webserver application
2364    * environment (cgi or php), this environment variable can
2365    * be controlled by the web server user by setting the
2366    * http header 'Proxy:' to some value.
2367    *
2368    * This can cause 'internal' http/ftp requests to be
2369    * arbitrarily redirected by any external attacker.
2370    */
2371   if(!prox && !strcasecompare("http_proxy", proxy_env)) {
2372     /* There was no lowercase variable, try the uppercase version: */
2373     Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
2374     prox = curl_getenv(proxy_env);
2375   }
2376 
2377   envp = proxy_env;
2378   if(prox) {
2379     proxy = prox; /* use this */
2380   }
2381   else {
2382     envp = (char *)"all_proxy";
2383     proxy = curl_getenv(envp); /* default proxy to use */
2384     if(!proxy) {
2385       envp = (char *)"ALL_PROXY";
2386       proxy = curl_getenv(envp);
2387     }
2388   }
2389   if(proxy)
2390     infof(data, "Uses proxy env variable %s == '%s'", envp, proxy);
2391 
2392   return proxy;
2393 }
2394 #endif /* CURL_DISABLE_HTTP */
2395 
2396 /*
2397  * If this is supposed to use a proxy, we need to figure out the proxy
2398  * host name, so that we can re-use an existing connection
2399  * that may exist registered to the same proxy host.
2400  */
2401 static CURLcode parse_proxy(struct Curl_easy *data,
2402                             struct connectdata *conn, char *proxy,
2403                             curl_proxytype proxytype)
2404 {
2405   char *portptr = NULL;
2406   int port = -1;
2407   char *proxyuser = NULL;
2408   char *proxypasswd = NULL;
2409   char *host;
2410   bool sockstype;
2411   CURLUcode uc;
2412   struct proxy_info *proxyinfo;
2413   CURLU *uhp = curl_url();
2414   CURLcode result = CURLE_OK;
2415   char *scheme = NULL;
2416 
2417   /* When parsing the proxy, allowing non-supported schemes since we have
2418      these made up ones for proxies. Guess scheme for URLs without it. */
2419   uc = curl_url_set(uhp, CURLUPART_URL, proxy,
2420                     CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME);
2421   if(!uc) {
2422     /* parsed okay as a URL */
2423     uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0);
2424     if(uc) {
2425       result = CURLE_OUT_OF_MEMORY;
2426       goto error;
2427     }
2428 
2429     if(strcasecompare("https", scheme))
2430       proxytype = CURLPROXY_HTTPS;
2431     else if(strcasecompare("socks5h", scheme))
2432       proxytype = CURLPROXY_SOCKS5_HOSTNAME;
2433     else if(strcasecompare("socks5", scheme))
2434       proxytype = CURLPROXY_SOCKS5;
2435     else if(strcasecompare("socks4a", scheme))
2436       proxytype = CURLPROXY_SOCKS4A;
2437     else if(strcasecompare("socks4", scheme) ||
2438             strcasecompare("socks", scheme))
2439       proxytype = CURLPROXY_SOCKS4;
2440     else if(strcasecompare("http", scheme))
2441       ; /* leave it as HTTP or HTTP/1.0 */
2442     else {
2443       /* Any other xxx:// reject! */
2444       failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
2445       result = CURLE_COULDNT_CONNECT;
2446       goto error;
2447     }
2448   }
2449   else {
2450     failf(data, "Unsupported proxy syntax in \'%s\'", proxy);
2451     result = CURLE_COULDNT_RESOLVE_PROXY;
2452     goto error;
2453   }
2454 
2455 #ifdef USE_SSL
2456   if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY))
2457 #endif
2458     if(proxytype == CURLPROXY_HTTPS) {
2459       failf(data, "Unsupported proxy \'%s\', libcurl is built without the "
2460                   "HTTPS-proxy support.", proxy);
2461       result = CURLE_NOT_BUILT_IN;
2462       goto error;
2463     }
2464 
2465   sockstype =
2466     proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
2467     proxytype == CURLPROXY_SOCKS5 ||
2468     proxytype == CURLPROXY_SOCKS4A ||
2469     proxytype == CURLPROXY_SOCKS4;
2470 
2471   proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy;
2472   proxyinfo->proxytype = proxytype;
2473 
2474   /* Is there a username and password given in this proxy url? */
2475   uc = curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE);
2476   if(uc && (uc != CURLUE_NO_USER))
2477     goto error;
2478   uc = curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE);
2479   if(uc && (uc != CURLUE_NO_PASSWORD))
2480     goto error;
2481 
2482   if(proxyuser || proxypasswd) {
2483     Curl_safefree(proxyinfo->user);
2484     proxyinfo->user = proxyuser;
2485     result = Curl_setstropt(&data->state.aptr.proxyuser, proxyuser);
2486     proxyuser = NULL;
2487     if(result)
2488       goto error;
2489     Curl_safefree(proxyinfo->passwd);
2490     if(!proxypasswd) {
2491       proxypasswd = strdup("");
2492       if(!proxypasswd) {
2493         result = CURLE_OUT_OF_MEMORY;
2494         goto error;
2495       }
2496     }
2497     proxyinfo->passwd = proxypasswd;
2498     result = Curl_setstropt(&data->state.aptr.proxypasswd, proxypasswd);
2499     proxypasswd = NULL;
2500     if(result)
2501       goto error;
2502     conn->bits.proxy_user_passwd = TRUE; /* enable it */
2503   }
2504 
2505   (void)curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
2506 
2507   if(portptr) {
2508     port = (int)strtol(portptr, NULL, 10);
2509     free(portptr);
2510   }
2511   else {
2512     if(data->set.proxyport)
2513       /* None given in the proxy string, then get the default one if it is
2514          given */
2515       port = (int)data->set.proxyport;
2516     else {
2517       if(proxytype == CURLPROXY_HTTPS)
2518         port = CURL_DEFAULT_HTTPS_PROXY_PORT;
2519       else
2520         port = CURL_DEFAULT_PROXY_PORT;
2521     }
2522   }
2523   if(port >= 0) {
2524     proxyinfo->port = port;
2525     if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
2526       conn->port = port;
2527   }
2528 
2529   /* now, clone the proxy host name */
2530   uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE);
2531   if(uc) {
2532     result = CURLE_OUT_OF_MEMORY;
2533     goto error;
2534   }
2535   Curl_safefree(proxyinfo->host.rawalloc);
2536   proxyinfo->host.rawalloc = host;
2537   if(host[0] == '[') {
2538     /* this is a numerical IPv6, strip off the brackets */
2539     size_t len = strlen(host);
2540     host[len-1] = 0; /* clear the trailing bracket */
2541     host++;
2542     zonefrom_url(uhp, data, conn);
2543   }
2544   proxyinfo->host.name = host;
2545 
2546   error:
2547   free(proxyuser);
2548   free(proxypasswd);
2549   free(scheme);
2550   curl_url_cleanup(uhp);
2551   return result;
2552 }
2553 
2554 /*
2555  * Extract the user and password from the authentication string
2556  */
2557 static CURLcode parse_proxy_auth(struct Curl_easy *data,
2558                                  struct connectdata *conn)
2559 {
2560   const char *proxyuser = data->state.aptr.proxyuser ?
2561     data->state.aptr.proxyuser : "";
2562   const char *proxypasswd = data->state.aptr.proxypasswd ?
2563     data->state.aptr.proxypasswd : "";
2564   CURLcode result = CURLE_OK;
2565 
2566   if(proxyuser) {
2567     result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
2568                             REJECT_ZERO);
2569     if(!result)
2570       result = Curl_setstropt(&data->state.aptr.proxyuser,
2571                               conn->http_proxy.user);
2572   }
2573   if(!result && proxypasswd) {
2574     result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
2575                             NULL, REJECT_ZERO);
2576     if(!result)
2577       result = Curl_setstropt(&data->state.aptr.proxypasswd,
2578                               conn->http_proxy.passwd);
2579   }
2580   return result;
2581 }
2582 
2583 /* create_conn helper to parse and init proxy values. to be called after unix
2584    socket init but before any proxy vars are evaluated. */
2585 static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
2586                                               struct connectdata *conn)
2587 {
2588   char *proxy = NULL;
2589   char *socksproxy = NULL;
2590   char *no_proxy = NULL;
2591   CURLcode result = CURLE_OK;
2592 
2593   /*************************************************************
2594    * Extract the user and password from the authentication string
2595    *************************************************************/
2596   if(conn->bits.proxy_user_passwd) {
2597     result = parse_proxy_auth(data, conn);
2598     if(result)
2599       goto out;
2600   }
2601 
2602   /*************************************************************
2603    * Detect what (if any) proxy to use
2604    *************************************************************/
2605   if(data->set.str[STRING_PROXY]) {
2606     proxy = strdup(data->set.str[STRING_PROXY]);
2607     /* if global proxy is set, this is it */
2608     if(NULL == proxy) {
2609       failf(data, "memory shortage");
2610       result = CURLE_OUT_OF_MEMORY;
2611       goto out;
2612     }
2613   }
2614 
2615   if(data->set.str[STRING_PRE_PROXY]) {
2616     socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
2617     /* if global socks proxy is set, this is it */
2618     if(NULL == socksproxy) {
2619       failf(data, "memory shortage");
2620       result = CURLE_OUT_OF_MEMORY;
2621       goto out;
2622     }
2623   }
2624 
2625   if(!data->set.str[STRING_NOPROXY]) {
2626     const char *p = "no_proxy";
2627     no_proxy = curl_getenv(p);
2628     if(!no_proxy) {
2629       p = "NO_PROXY";
2630       no_proxy = curl_getenv(p);
2631     }
2632     if(no_proxy) {
2633       infof(data, "Uses proxy env variable %s == '%s'", p, no_proxy);
2634     }
2635   }
2636 
2637   if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ?
2638       data->set.str[STRING_NOPROXY] : no_proxy)) {
2639     Curl_safefree(proxy);
2640     Curl_safefree(socksproxy);
2641   }
2642 #ifndef CURL_DISABLE_HTTP
2643   else if(!proxy && !socksproxy)
2644     /* if the host is not in the noproxy list, detect proxy. */
2645     proxy = detect_proxy(data, conn);
2646 #endif /* CURL_DISABLE_HTTP */
2647 
2648   Curl_safefree(no_proxy);
2649 
2650 #ifdef USE_UNIX_SOCKETS
2651   /* For the time being do not mix proxy and unix domain sockets. See #1274 */
2652   if(proxy && conn->unix_domain_socket) {
2653     free(proxy);
2654     proxy = NULL;
2655   }
2656 #endif
2657 
2658   if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
2659     free(proxy);  /* Don't bother with an empty proxy string or if the
2660                      protocol doesn't work with network */
2661     proxy = NULL;
2662   }
2663   if(socksproxy && (!*socksproxy ||
2664                     (conn->handler->flags & PROTOPT_NONETWORK))) {
2665     free(socksproxy);  /* Don't bother with an empty socks proxy string or if
2666                           the protocol doesn't work with network */
2667     socksproxy = NULL;
2668   }
2669 
2670   /***********************************************************************
2671    * If this is supposed to use a proxy, we need to figure out the proxy host
2672    * name, proxy type and port number, so that we can re-use an existing
2673    * connection that may exist registered to the same proxy host.
2674    ***********************************************************************/
2675   if(proxy || socksproxy) {
2676     if(proxy) {
2677       result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
2678       Curl_safefree(proxy); /* parse_proxy copies the proxy string */
2679       if(result)
2680         goto out;
2681     }
2682 
2683     if(socksproxy) {
2684       result = parse_proxy(data, conn, socksproxy,
2685                            conn->socks_proxy.proxytype);
2686       /* parse_proxy copies the socks proxy string */
2687       Curl_safefree(socksproxy);
2688       if(result)
2689         goto out;
2690     }
2691 
2692     if(conn->http_proxy.host.rawalloc) {
2693 #ifdef CURL_DISABLE_HTTP
2694       /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
2695       result = CURLE_UNSUPPORTED_PROTOCOL;
2696       goto out;
2697 #else
2698       /* force this connection's protocol to become HTTP if compatible */
2699       if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) {
2700         if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) &&
2701            !conn->bits.tunnel_proxy)
2702           conn->handler = &Curl_handler_http;
2703         else
2704           /* if not converting to HTTP over the proxy, enforce tunneling */
2705           conn->bits.tunnel_proxy = TRUE;
2706       }
2707       conn->bits.httpproxy = TRUE;
2708 #endif
2709     }
2710     else {
2711       conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
2712       conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
2713     }
2714 
2715     if(conn->socks_proxy.host.rawalloc) {
2716       if(!conn->http_proxy.host.rawalloc) {
2717         /* once a socks proxy */
2718         if(!conn->socks_proxy.user) {
2719           conn->socks_proxy.user = conn->http_proxy.user;
2720           conn->http_proxy.user = NULL;
2721           Curl_safefree(conn->socks_proxy.passwd);
2722           conn->socks_proxy.passwd = conn->http_proxy.passwd;
2723           conn->http_proxy.passwd = NULL;
2724         }
2725       }
2726       conn->bits.socksproxy = TRUE;
2727     }
2728     else
2729       conn->bits.socksproxy = FALSE; /* not a socks proxy */
2730   }
2731   else {
2732     conn->bits.socksproxy = FALSE;
2733     conn->bits.httpproxy = FALSE;
2734   }
2735   conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
2736 
2737   if(!conn->bits.proxy) {
2738     /* we aren't using the proxy after all... */
2739     conn->bits.proxy = FALSE;
2740     conn->bits.httpproxy = FALSE;
2741     conn->bits.socksproxy = FALSE;
2742     conn->bits.proxy_user_passwd = FALSE;
2743     conn->bits.tunnel_proxy = FALSE;
2744     /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need
2745        to signal that CURLPROXY_HTTPS is not used for this connection */
2746     conn->http_proxy.proxytype = CURLPROXY_HTTP;
2747   }
2748 
2749 out:
2750 
2751   free(socksproxy);
2752   free(proxy);
2753   return result;
2754 }
2755 #endif /* CURL_DISABLE_PROXY */
2756 
2757 /*
2758  * Curl_parse_login_details()
2759  *
2760  * This is used to parse a login string for user name, password and options in
2761  * the following formats:
2762  *
2763  *   user
2764  *   user:password
2765  *   user:password;options
2766  *   user;options
2767  *   user;options:password
2768  *   :password
2769  *   :password;options
2770  *   ;options
2771  *   ;options:password
2772  *
2773  * Parameters:
2774  *
2775  * login    [in]     - The login string.
2776  * len      [in]     - The length of the login string.
2777  * userp    [in/out] - The address where a pointer to newly allocated memory
2778  *                     holding the user will be stored upon completion.
2779  * passwdp  [in/out] - The address where a pointer to newly allocated memory
2780  *                     holding the password will be stored upon completion.
2781  * optionsp [in/out] - The address where a pointer to newly allocated memory
2782  *                     holding the options will be stored upon completion.
2783  *
2784  * Returns CURLE_OK on success.
2785  */
2786 CURLcode Curl_parse_login_details(const char *login, const size_t len,
2787                                   char **userp, char **passwdp,
2788                                   char **optionsp)
2789 {
2790   CURLcode result = CURLE_OK;
2791   char *ubuf = NULL;
2792   char *pbuf = NULL;
2793   char *obuf = NULL;
2794   const char *psep = NULL;
2795   const char *osep = NULL;
2796   size_t ulen;
2797   size_t plen;
2798   size_t olen;
2799 
2800   /* the input length check is because this is called directcly from setopt
2801      and isn't going through the regular string length check */
2802   size_t llen = strlen(login);
2803   if(llen > CURL_MAX_INPUT_LENGTH)
2804     return CURLE_BAD_FUNCTION_ARGUMENT;
2805 
2806   /* Attempt to find the password separator */
2807   if(passwdp) {
2808     psep = strchr(login, ':');
2809 
2810     /* Within the constraint of the login string */
2811     if(psep >= login + len)
2812       psep = NULL;
2813   }
2814 
2815   /* Attempt to find the options separator */
2816   if(optionsp) {
2817     osep = strchr(login, ';');
2818 
2819     /* Within the constraint of the login string */
2820     if(osep >= login + len)
2821       osep = NULL;
2822   }
2823 
2824   /* Calculate the portion lengths */
2825   ulen = (psep ?
2826           (size_t)(osep && psep > osep ? osep - login : psep - login) :
2827           (osep ? (size_t)(osep - login) : len));
2828   plen = (psep ?
2829           (osep && osep > psep ? (size_t)(osep - psep) :
2830                                  (size_t)(login + len - psep)) - 1 : 0);
2831   olen = (osep ?
2832           (psep && psep > osep ? (size_t)(psep - osep) :
2833                                  (size_t)(login + len - osep)) - 1 : 0);
2834 
2835   /* Allocate the user portion buffer */
2836   if(userp && ulen) {
2837     ubuf = malloc(ulen + 1);
2838     if(!ubuf)
2839       result = CURLE_OUT_OF_MEMORY;
2840   }
2841 
2842   /* Allocate the password portion buffer */
2843   if(!result && passwdp && plen) {
2844     pbuf = malloc(plen + 1);
2845     if(!pbuf) {
2846       free(ubuf);
2847       result = CURLE_OUT_OF_MEMORY;
2848     }
2849   }
2850 
2851   /* Allocate the options portion buffer */
2852   if(!result && optionsp && olen) {
2853     obuf = malloc(olen + 1);
2854     if(!obuf) {
2855       free(pbuf);
2856       free(ubuf);
2857       result = CURLE_OUT_OF_MEMORY;
2858     }
2859   }
2860 
2861   if(!result) {
2862     /* Store the user portion if necessary */
2863     if(ubuf) {
2864       memcpy(ubuf, login, ulen);
2865       ubuf[ulen] = '\0';
2866       Curl_safefree(*userp);
2867       *userp = ubuf;
2868     }
2869 
2870     /* Store the password portion if necessary */
2871     if(pbuf) {
2872       memcpy(pbuf, psep + 1, plen);
2873       pbuf[plen] = '\0';
2874       Curl_safefree(*passwdp);
2875       *passwdp = pbuf;
2876     }
2877 
2878     /* Store the options portion if necessary */
2879     if(obuf) {
2880       memcpy(obuf, osep + 1, olen);
2881       obuf[olen] = '\0';
2882       Curl_safefree(*optionsp);
2883       *optionsp = obuf;
2884     }
2885   }
2886 
2887   return result;
2888 }
2889 
2890 /*************************************************************
2891  * Figure out the remote port number and fix it in the URL
2892  *
2893  * No matter if we use a proxy or not, we have to figure out the remote
2894  * port number of various reasons.
2895  *
2896  * The port number embedded in the URL is replaced, if necessary.
2897  *************************************************************/
2898 static CURLcode parse_remote_port(struct Curl_easy *data,
2899                                   struct connectdata *conn)
2900 {
2901 
2902   if(data->set.use_port && data->state.allow_port) {
2903     /* if set, we use this instead of the port possibly given in the URL */
2904     char portbuf[16];
2905     CURLUcode uc;
2906     conn->remote_port = (unsigned short)data->set.use_port;
2907     msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port);
2908     uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0);
2909     if(uc)
2910       return CURLE_OUT_OF_MEMORY;
2911   }
2912 
2913   return CURLE_OK;
2914 }
2915 
2916 /*
2917  * Override the login details from the URL with that in the CURLOPT_USERPWD
2918  * option or a .netrc file, if applicable.
2919  */
2920 static CURLcode override_login(struct Curl_easy *data,
2921                                struct connectdata *conn)
2922 {
2923   CURLUcode uc;
2924   char **userp = &conn->user;
2925   char **passwdp = &conn->passwd;
2926   char **optionsp = &conn->options;
2927 
2928 #ifndef CURL_DISABLE_NETRC
2929   if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) {
2930     Curl_safefree(*userp);
2931     Curl_safefree(*passwdp);
2932     conn->bits.user_passwd = FALSE; /* disable user+password */
2933   }
2934 #endif
2935 
2936   if(data->set.str[STRING_OPTIONS]) {
2937     free(*optionsp);
2938     *optionsp = strdup(data->set.str[STRING_OPTIONS]);
2939     if(!*optionsp)
2940       return CURLE_OUT_OF_MEMORY;
2941   }
2942 
2943 #ifndef CURL_DISABLE_NETRC
2944   conn->bits.netrc = FALSE;
2945   if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
2946     bool netrc_user_changed = FALSE;
2947     bool netrc_passwd_changed = FALSE;
2948     int ret;
2949 
2950     ret = Curl_parsenetrc(conn->host.name,
2951                           userp, passwdp,
2952                           &netrc_user_changed, &netrc_passwd_changed,
2953                           data->set.str[STRING_NETRC_FILE]);
2954     if(ret > 0) {
2955       infof(data, "Couldn't find host %s in the %s file; using defaults",
2956             conn->host.name, data->set.str[STRING_NETRC_FILE]);
2957     }
2958     else if(ret < 0) {
2959       return CURLE_OUT_OF_MEMORY;
2960     }
2961     else {
2962       /* set bits.netrc TRUE to remember that we got the name from a .netrc
2963          file, so that it is safe to use even if we followed a Location: to a
2964          different host or similar. */
2965       conn->bits.netrc = TRUE;
2966       conn->bits.user_passwd = TRUE; /* enable user+password */
2967     }
2968   }
2969 #endif
2970 
2971   /* for updated strings, we update them in the URL */
2972   if(*userp) {
2973     CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp);
2974     if(result)
2975       return result;
2976   }
2977   if(data->state.aptr.user) {
2978     uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
2979                       CURLU_URLENCODE);
2980     if(uc)
2981       return Curl_uc_to_curlcode(uc);
2982     if(!*userp) {
2983       *userp = strdup(data->state.aptr.user);
2984       if(!*userp)
2985         return CURLE_OUT_OF_MEMORY;
2986     }
2987   }
2988 
2989   if(*passwdp) {
2990     CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
2991     if(result)
2992       return result;
2993   }
2994   if(data->state.aptr.passwd) {
2995     uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD,
2996                       data->state.aptr.passwd, CURLU_URLENCODE);
2997     if(uc)
2998       return Curl_uc_to_curlcode(uc);
2999     if(!*passwdp) {
3000       *passwdp = strdup(data->state.aptr.passwd);
3001       if(!*passwdp)
3002         return CURLE_OUT_OF_MEMORY;
3003     }
3004   }
3005 
3006   return CURLE_OK;
3007 }
3008 
3009 /*
3010  * Set the login details so they're available in the connection
3011  */
3012 static CURLcode set_login(struct connectdata *conn)
3013 {
3014   CURLcode result = CURLE_OK;
3015   const char *setuser = CURL_DEFAULT_USER;
3016   const char *setpasswd = CURL_DEFAULT_PASSWORD;
3017 
3018   /* If our protocol needs a password and we have none, use the defaults */
3019   if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd)
3020     ;
3021   else {
3022     setuser = "";
3023     setpasswd = "";
3024   }
3025   /* Store the default user */
3026   if(!conn->user) {
3027     conn->user = strdup(setuser);
3028     if(!conn->user)
3029       return CURLE_OUT_OF_MEMORY;
3030   }
3031 
3032   /* Store the default password */
3033   if(!conn->passwd) {
3034     conn->passwd = strdup(setpasswd);
3035     if(!conn->passwd)
3036       result = CURLE_OUT_OF_MEMORY;
3037   }
3038 
3039   return result;
3040 }
3041 
3042 /*
3043  * Parses a "host:port" string to connect to.
3044  * The hostname and the port may be empty; in this case, NULL is returned for
3045  * the hostname and -1 for the port.
3046  */
3047 static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
3048                                            const char *host,
3049                                            char **hostname_result,
3050                                            int *port_result)
3051 {
3052   char *host_dup;
3053   char *hostptr;
3054   char *host_portno;
3055   char *portptr;
3056   int port = -1;
3057   CURLcode result = CURLE_OK;
3058 
3059 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
3060   (void) data;
3061 #endif
3062 
3063   *hostname_result = NULL;
3064   *port_result = -1;
3065 
3066   if(!host || !*host)
3067     return CURLE_OK;
3068 
3069   host_dup = strdup(host);
3070   if(!host_dup)
3071     return CURLE_OUT_OF_MEMORY;
3072 
3073   hostptr = host_dup;
3074 
3075   /* start scanning for port number at this point */
3076   portptr = hostptr;
3077 
3078   /* detect and extract RFC6874-style IPv6-addresses */
3079   if(*hostptr == '[') {
3080 #ifdef ENABLE_IPV6
3081     char *ptr = ++hostptr; /* advance beyond the initial bracket */
3082     while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
3083       ptr++;
3084     if(*ptr == '%') {
3085       /* There might be a zone identifier */
3086       if(strncmp("%25", ptr, 3))
3087         infof(data, "Please URL encode %% as %%25, see RFC 6874.");
3088       ptr++;
3089       /* Allow unreserved characters as defined in RFC 3986 */
3090       while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
3091                      (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
3092         ptr++;
3093     }
3094     if(*ptr == ']')
3095       /* yeps, it ended nicely with a bracket as well */
3096       *ptr++ = '\0';
3097     else
3098       infof(data, "Invalid IPv6 address format");
3099     portptr = ptr;
3100     /* Note that if this didn't end with a bracket, we still advanced the
3101      * hostptr first, but I can't see anything wrong with that as no host
3102      * name nor a numeric can legally start with a bracket.
3103      */
3104 #else
3105     failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in!");
3106     result = CURLE_NOT_BUILT_IN;
3107     goto error;
3108 #endif
3109   }
3110 
3111   /* Get port number off server.com:1080 */
3112   host_portno = strchr(portptr, ':');
3113   if(host_portno) {
3114     char *endp = NULL;
3115     *host_portno = '\0'; /* cut off number from host name */
3116     host_portno++;
3117     if(*host_portno) {
3118       long portparse = strtol(host_portno, &endp, 10);
3119       if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
3120         failf(data, "No valid port number in connect to host string (%s)",
3121               host_portno);
3122         result = CURLE_SETOPT_OPTION_SYNTAX;
3123         goto error;
3124       }
3125       else
3126         port = (int)portparse; /* we know it will fit */
3127     }
3128   }
3129 
3130   /* now, clone the cleaned host name */
3131   if(hostptr) {
3132     *hostname_result = strdup(hostptr);
3133     if(!*hostname_result) {
3134       result = CURLE_OUT_OF_MEMORY;
3135       goto error;
3136     }
3137   }
3138 
3139   *port_result = port;
3140 
3141   error:
3142   free(host_dup);
3143   return result;
3144 }
3145 
3146 /*
3147  * Parses one "connect to" string in the form:
3148  * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT".
3149  */
3150 static CURLcode parse_connect_to_string(struct Curl_easy *data,
3151                                         struct connectdata *conn,
3152                                         const char *conn_to_host,
3153                                         char **host_result,
3154                                         int *port_result)
3155 {
3156   CURLcode result = CURLE_OK;
3157   const char *ptr = conn_to_host;
3158   int host_match = FALSE;
3159   int port_match = FALSE;
3160 
3161   *host_result = NULL;
3162   *port_result = -1;
3163 
3164   if(*ptr == ':') {
3165     /* an empty hostname always matches */
3166     host_match = TRUE;
3167     ptr++;
3168   }
3169   else {
3170     /* check whether the URL's hostname matches */
3171     size_t hostname_to_match_len;
3172     char *hostname_to_match = aprintf("%s%s%s",
3173                                       conn->bits.ipv6_ip ? "[" : "",
3174                                       conn->host.name,
3175                                       conn->bits.ipv6_ip ? "]" : "");
3176     if(!hostname_to_match)
3177       return CURLE_OUT_OF_MEMORY;
3178     hostname_to_match_len = strlen(hostname_to_match);
3179     host_match = strncasecompare(ptr, hostname_to_match,
3180                                  hostname_to_match_len);
3181     free(hostname_to_match);
3182     ptr += hostname_to_match_len;
3183 
3184     host_match = host_match && *ptr == ':';
3185     ptr++;
3186   }
3187 
3188   if(host_match) {
3189     if(*ptr == ':') {
3190       /* an empty port always matches */
3191       port_match = TRUE;
3192       ptr++;
3193     }
3194     else {
3195       /* check whether the URL's port matches */
3196       char *ptr_next = strchr(ptr, ':');
3197       if(ptr_next) {
3198         char *endp = NULL;
3199         long port_to_match = strtol(ptr, &endp, 10);
3200         if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
3201           port_match = TRUE;
3202           ptr = ptr_next + 1;
3203         }
3204       }
3205     }
3206   }
3207 
3208   if(host_match && port_match) {
3209     /* parse the hostname and port to connect to */
3210     result = parse_connect_to_host_port(data, ptr, host_result, port_result);
3211   }
3212 
3213   return result;
3214 }
3215 
3216 /*
3217  * Processes all strings in the "connect to" slist, and uses the "connect
3218  * to host" and "connect to port" of the first string that matches.
3219  */
3220 static CURLcode parse_connect_to_slist(struct Curl_easy *data,
3221                                        struct connectdata *conn,
3222                                        struct curl_slist *conn_to_host)
3223 {
3224   CURLcode result = CURLE_OK;
3225   char *host = NULL;
3226   int port = -1;
3227 
3228   while(conn_to_host && !host && port == -1) {
3229     result = parse_connect_to_string(data, conn, conn_to_host->data,
3230                                      &host, &port);
3231     if(result)
3232       return result;
3233 
3234     if(host && *host) {
3235       conn->conn_to_host.rawalloc = host;
3236       conn->conn_to_host.name = host;
3237       conn->bits.conn_to_host = TRUE;
3238 
3239       infof(data, "Connecting to hostname: %s", host);
3240     }
3241     else {
3242       /* no "connect to host" */
3243       conn->bits.conn_to_host = FALSE;
3244       Curl_safefree(host);
3245     }
3246 
3247     if(port >= 0) {
3248       conn->conn_to_port = port;
3249       conn->bits.conn_to_port = TRUE;
3250       infof(data, "Connecting to port: %d", port);
3251     }
3252     else {
3253       /* no "connect to port" */
3254       conn->bits.conn_to_port = FALSE;
3255       port = -1;
3256     }
3257 
3258     conn_to_host = conn_to_host->next;
3259   }
3260 
3261 #ifndef CURL_DISABLE_ALTSVC
3262   if(data->asi && !host && (port == -1) &&
3263      ((conn->handler->protocol == CURLPROTO_HTTPS) ||
3264 #ifdef CURLDEBUG
3265       /* allow debug builds to circumvent the HTTPS restriction */
3266       getenv("CURL_ALTSVC_HTTP")
3267 #else
3268       0
3269 #endif
3270        )) {
3271     /* no connect_to match, try alt-svc! */
3272     enum alpnid srcalpnid;
3273     bool hit;
3274     struct altsvc *as;
3275     const int allowed_versions = ( ALPN_h1
3276 #ifdef USE_NGHTTP2
3277       | ALPN_h2
3278 #endif
3279 #ifdef ENABLE_QUIC
3280       | ALPN_h3
3281 #endif
3282       ) & data->asi->flags;
3283 
3284     host = conn->host.rawalloc;
3285 #ifdef USE_NGHTTP2
3286     /* with h2 support, check that first */
3287     srcalpnid = ALPN_h2;
3288     hit = Curl_altsvc_lookup(data->asi,
3289                              srcalpnid, host, conn->remote_port, /* from */
3290                              &as /* to */,
3291                              allowed_versions);
3292     if(!hit)
3293 #endif
3294     {
3295       srcalpnid = ALPN_h1;
3296       hit = Curl_altsvc_lookup(data->asi,
3297                                srcalpnid, host, conn->remote_port, /* from */
3298                                &as /* to */,
3299                                allowed_versions);
3300     }
3301     if(hit) {
3302       char *hostd = strdup((char *)as->dst.host);
3303       if(!hostd)
3304         return CURLE_OUT_OF_MEMORY;
3305       conn->conn_to_host.rawalloc = hostd;
3306       conn->conn_to_host.name = hostd;
3307       conn->bits.conn_to_host = TRUE;
3308       conn->conn_to_port = as->dst.port;
3309       conn->bits.conn_to_port = TRUE;
3310       conn->bits.altused = TRUE;
3311       infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d",
3312             Curl_alpnid2str(srcalpnid), host, conn->remote_port,
3313             Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port);
3314       if(srcalpnid != as->dst.alpnid) {
3315         /* protocol version switch */
3316         switch(as->dst.alpnid) {
3317         case ALPN_h1:
3318           conn->httpversion = 11;
3319           break;
3320         case ALPN_h2:
3321           conn->httpversion = 20;
3322           break;
3323         case ALPN_h3:
3324           conn->transport = TRNSPRT_QUIC;
3325           conn->httpversion = 30;
3326           break;
3327         default: /* shouldn't be possible */
3328           break;
3329         }
3330       }
3331     }
3332   }
3333 #endif
3334 
3335   return result;
3336 }
3337 
3338 /*************************************************************
3339  * Resolve the address of the server or proxy
3340  *************************************************************/
3341 static CURLcode resolve_server(struct Curl_easy *data,
3342                                struct connectdata *conn,
3343                                bool *async)
3344 {
3345   CURLcode result = CURLE_OK;
3346   timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3347 
3348   DEBUGASSERT(conn);
3349   DEBUGASSERT(data);
3350   /*************************************************************
3351    * Resolve the name of the server or proxy
3352    *************************************************************/
3353   if(conn->bits.reuse)
3354     /* We're reusing the connection - no need to resolve anything, and
3355        idnconvert_hostname() was called already in create_conn() for the re-use
3356        case. */
3357     *async = FALSE;
3358 
3359   else {
3360     /* this is a fresh connect */
3361     int rc;
3362     struct Curl_dns_entry *hostaddr = NULL;
3363 
3364 #ifdef USE_UNIX_SOCKETS
3365     if(conn->unix_domain_socket) {
3366       /* Unix domain sockets are local. The host gets ignored, just use the
3367        * specified domain socket address. Do not cache "DNS entries". There is
3368        * no DNS involved and we already have the filesystem path available */
3369       const char *path = conn->unix_domain_socket;
3370 
3371       hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
3372       if(!hostaddr)
3373         result = CURLE_OUT_OF_MEMORY;
3374       else {
3375         bool longpath = FALSE;
3376         hostaddr->addr = Curl_unix2addr(path, &longpath,
3377                                         conn->bits.abstract_unix_socket);
3378         if(hostaddr->addr)
3379           hostaddr->inuse++;
3380         else {
3381           /* Long paths are not supported for now */
3382           if(longpath) {
3383             failf(data, "Unix socket path too long: '%s'", path);
3384             result = CURLE_COULDNT_RESOLVE_HOST;
3385           }
3386           else
3387             result = CURLE_OUT_OF_MEMORY;
3388           free(hostaddr);
3389           hostaddr = NULL;
3390         }
3391       }
3392     }
3393     else
3394 #endif
3395 
3396     if(!conn->bits.proxy) {
3397       struct hostname *connhost;
3398       if(conn->bits.conn_to_host)
3399         connhost = &conn->conn_to_host;
3400       else
3401         connhost = &conn->host;
3402 
3403       /* If not connecting via a proxy, extract the port from the URL, if it is
3404        * there, thus overriding any defaults that might have been set above. */
3405       if(conn->bits.conn_to_port)
3406         conn->port = conn->conn_to_port;
3407       else
3408         conn->port = conn->remote_port;
3409 
3410       /* Resolve target host right on */
3411       conn->hostname_resolve = strdup(connhost->name);
3412       if(!conn->hostname_resolve)
3413         return CURLE_OUT_OF_MEMORY;
3414       rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
3415                                &hostaddr, timeout_ms);
3416       if(rc == CURLRESOLV_PENDING)
3417         *async = TRUE;
3418 
3419       else if(rc == CURLRESOLV_TIMEDOUT) {
3420         failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
3421               connhost->dispname,
3422               Curl_timediff(Curl_now(), data->progress.t_startsingle));
3423         result = CURLE_OPERATION_TIMEDOUT;
3424       }
3425       else if(!hostaddr) {
3426         failf(data, "Could not resolve host: %s", connhost->dispname);
3427         result = CURLE_COULDNT_RESOLVE_HOST;
3428         /* don't return yet, we need to clean up the timeout first */
3429       }
3430     }
3431 #ifndef CURL_DISABLE_PROXY
3432     else {
3433       /* This is a proxy that hasn't been resolved yet. */
3434 
3435       struct hostname * const host = conn->bits.socksproxy ?
3436         &conn->socks_proxy.host : &conn->http_proxy.host;
3437 
3438       /* resolve proxy */
3439       conn->hostname_resolve = strdup(host->name);
3440       if(!conn->hostname_resolve)
3441         return CURLE_OUT_OF_MEMORY;
3442       rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
3443                                &hostaddr, timeout_ms);
3444 
3445       if(rc == CURLRESOLV_PENDING)
3446         *async = TRUE;
3447 
3448       else if(rc == CURLRESOLV_TIMEDOUT)
3449         result = CURLE_OPERATION_TIMEDOUT;
3450 
3451       else if(!hostaddr) {
3452         failf(data, "Couldn't resolve proxy '%s'", host->dispname);
3453         result = CURLE_COULDNT_RESOLVE_PROXY;
3454         /* don't return yet, we need to clean up the timeout first */
3455       }
3456     }
3457 #endif
3458     DEBUGASSERT(conn->dns_entry == NULL);
3459     conn->dns_entry = hostaddr;
3460   }
3461 
3462   return result;
3463 }
3464 
3465 /*
3466  * Cleanup the connection just allocated before we can move along and use the
3467  * previously existing one.  All relevant data is copied over and old_conn is
3468  * ready for freeing once this function returns.
3469  */
3470 static void reuse_conn(struct Curl_easy *data,
3471                        struct connectdata *old_conn,
3472                        struct connectdata *conn)
3473 {
3474   /* 'local_ip' and 'local_port' get filled with local's numerical
3475      ip address and port number whenever an outgoing connection is
3476      **established** from the primary socket to a remote address. */
3477   char local_ip[MAX_IPADR_LEN] = "";
3478   int local_port = -1;
3479 #ifndef CURL_DISABLE_PROXY
3480   Curl_free_idnconverted_hostname(&old_conn->http_proxy.host);
3481   Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host);
3482 
3483   free(old_conn->http_proxy.host.rawalloc);
3484   free(old_conn->socks_proxy.host.rawalloc);
3485   Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
3486 #endif
3487   /* free the SSL config struct from this connection struct as this was
3488      allocated in vain and is targeted for destruction */
3489   Curl_free_primary_ssl_config(&old_conn->ssl_config);
3490 
3491   /* get the user+password information from the old_conn struct since it may
3492    * be new for this request even when we re-use an existing connection */
3493   conn->bits.user_passwd = old_conn->bits.user_passwd;
3494   if(conn->bits.user_passwd) {
3495     /* use the new user name and password though */
3496     Curl_safefree(conn->user);
3497     Curl_safefree(conn->passwd);
3498     conn->user = old_conn->user;
3499     conn->passwd = old_conn->passwd;
3500     old_conn->user = NULL;
3501     old_conn->passwd = NULL;
3502   }
3503 
3504 #ifndef CURL_DISABLE_PROXY
3505   conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3506   if(conn->bits.proxy_user_passwd) {
3507     /* use the new proxy user name and proxy password though */
3508     Curl_safefree(conn->http_proxy.user);
3509     Curl_safefree(conn->socks_proxy.user);
3510     Curl_safefree(conn->http_proxy.passwd);
3511     Curl_safefree(conn->socks_proxy.passwd);
3512     conn->http_proxy.user = old_conn->http_proxy.user;
3513     conn->socks_proxy.user = old_conn->socks_proxy.user;
3514     conn->http_proxy.passwd = old_conn->http_proxy.passwd;
3515     conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
3516     old_conn->http_proxy.user = NULL;
3517     old_conn->socks_proxy.user = NULL;
3518     old_conn->http_proxy.passwd = NULL;
3519     old_conn->socks_proxy.passwd = NULL;
3520   }
3521   Curl_safefree(old_conn->http_proxy.user);
3522   Curl_safefree(old_conn->socks_proxy.user);
3523   Curl_safefree(old_conn->http_proxy.passwd);
3524   Curl_safefree(old_conn->socks_proxy.passwd);
3525 #endif
3526 
3527   /* host can change, when doing keepalive with a proxy or if the case is
3528      different this time etc */
3529   Curl_free_idnconverted_hostname(&conn->host);
3530   Curl_free_idnconverted_hostname(&conn->conn_to_host);
3531   Curl_safefree(conn->host.rawalloc);
3532   Curl_safefree(conn->conn_to_host.rawalloc);
3533   conn->host = old_conn->host;
3534   conn->conn_to_host = old_conn->conn_to_host;
3535   conn->conn_to_port = old_conn->conn_to_port;
3536   conn->remote_port = old_conn->remote_port;
3537   Curl_safefree(conn->hostname_resolve);
3538 
3539   conn->hostname_resolve = old_conn->hostname_resolve;
3540   old_conn->hostname_resolve = NULL;
3541 
3542   /* persist connection info in session handle */
3543   if(conn->transport == TRNSPRT_TCP) {
3544     Curl_conninfo_local(data, conn->sock[FIRSTSOCKET],
3545                         local_ip, &local_port);
3546   }
3547   Curl_persistconninfo(data, conn, local_ip, local_port);
3548 
3549   conn_reset_all_postponed_data(old_conn); /* free buffers */
3550 
3551   /* re-use init */
3552   conn->bits.reuse = TRUE; /* yes, we're re-using here */
3553 
3554   Curl_safefree(old_conn->user);
3555   Curl_safefree(old_conn->passwd);
3556   Curl_safefree(old_conn->options);
3557   Curl_safefree(old_conn->localdev);
3558   Curl_llist_destroy(&old_conn->easyq, NULL);
3559 
3560 #ifdef USE_UNIX_SOCKETS
3561   Curl_safefree(old_conn->unix_domain_socket);
3562 #endif
3563 }
3564 
3565 /**
3566  * create_conn() sets up a new connectdata struct, or re-uses an already
3567  * existing one, and resolves host name.
3568  *
3569  * if this function returns CURLE_OK and *async is set to TRUE, the resolve
3570  * response will be coming asynchronously. If *async is FALSE, the name is
3571  * already resolved.
3572  *
3573  * @param data The sessionhandle pointer
3574  * @param in_connect is set to the next connection data pointer
3575  * @param async is set TRUE when an async DNS resolution is pending
3576  * @see Curl_setup_conn()
3577  *
3578  */
3579 
3580 static CURLcode create_conn(struct Curl_easy *data,
3581                             struct connectdata **in_connect,
3582                             bool *async)
3583 {
3584   CURLcode result = CURLE_OK;
3585   struct connectdata *conn;
3586   struct connectdata *conn_temp = NULL;
3587   bool reuse;
3588   bool connections_available = TRUE;
3589   bool force_reuse = FALSE;
3590   bool waitpipe = FALSE;
3591   size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
3592   size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
3593 
3594   *async = FALSE;
3595   *in_connect = NULL;
3596 
3597   /*************************************************************
3598    * Check input data
3599    *************************************************************/
3600   if(!data->state.url) {
3601     result = CURLE_URL_MALFORMAT;
3602     goto out;
3603   }
3604 
3605   /* First, split up the current URL in parts so that we can use the
3606      parts for checking against the already present connections. In order
3607      to not have to modify everything at once, we allocate a temporary
3608      connection data struct and fill in for comparison purposes. */
3609   conn = allocate_conn(data);
3610 
3611   if(!conn) {
3612     result = CURLE_OUT_OF_MEMORY;
3613     goto out;
3614   }
3615 
3616   /* We must set the return variable as soon as possible, so that our
3617      parent can cleanup any possible allocs we may have done before
3618      any failure */
3619   *in_connect = conn;
3620 
3621   result = parseurlandfillconn(data, conn);
3622   if(result)
3623     goto out;
3624 
3625   if(data->set.str[STRING_SASL_AUTHZID]) {
3626     conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]);
3627     if(!conn->sasl_authzid) {
3628       result = CURLE_OUT_OF_MEMORY;
3629       goto out;
3630     }
3631   }
3632 
3633   if(data->set.str[STRING_BEARER]) {
3634     conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
3635     if(!conn->oauth_bearer) {
3636       result = CURLE_OUT_OF_MEMORY;
3637       goto out;
3638     }
3639   }
3640 
3641 #ifdef USE_UNIX_SOCKETS
3642   if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
3643     conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
3644     if(!conn->unix_domain_socket) {
3645       result = CURLE_OUT_OF_MEMORY;
3646       goto out;
3647     }
3648     conn->bits.abstract_unix_socket = data->set.abstract_unix_socket;
3649   }
3650 #endif
3651 
3652   /* After the unix socket init but before the proxy vars are used, parse and
3653      initialize the proxy vars */
3654 #ifndef CURL_DISABLE_PROXY
3655   result = create_conn_helper_init_proxy(data, conn);
3656   if(result)
3657     goto out;
3658 
3659   /*************************************************************
3660    * If the protocol is using SSL and HTTP proxy is used, we set
3661    * the tunnel_proxy bit.
3662    *************************************************************/
3663   if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
3664     conn->bits.tunnel_proxy = TRUE;
3665 #endif
3666 
3667   /*************************************************************
3668    * Figure out the remote port number and fix it in the URL
3669    *************************************************************/
3670   result = parse_remote_port(data, conn);
3671   if(result)
3672     goto out;
3673 
3674   /* Check for overridden login details and set them accordingly so that
3675      they are known when protocol->setup_connection is called! */
3676   result = override_login(data, conn);
3677   if(result)
3678     goto out;
3679 
3680   result = set_login(conn); /* default credentials */
3681   if(result)
3682     goto out;
3683 
3684   /*************************************************************
3685    * Process the "connect to" linked list of hostname/port mappings.
3686    * Do this after the remote port number has been fixed in the URL.
3687    *************************************************************/
3688   result = parse_connect_to_slist(data, conn, data->set.connect_to);
3689   if(result)
3690     goto out;
3691 
3692 
3693   /*************************************************************
3694    * Check whether the host and the "connect to host" are equal.
3695    * Do this after the hostnames have been IDN-converted.
3696    *************************************************************/
3697   if(conn->bits.conn_to_host &&
3698      strcasecompare(conn->conn_to_host.name, conn->host.name)) {
3699     conn->bits.conn_to_host = FALSE;
3700   }
3701 
3702   /*************************************************************
3703    * Check whether the port and the "connect to port" are equal.
3704    * Do this after the remote port number has been fixed in the URL.
3705    *************************************************************/
3706   if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) {
3707     conn->bits.conn_to_port = FALSE;
3708   }
3709 
3710 #ifndef CURL_DISABLE_PROXY
3711   /*************************************************************
3712    * If the "connect to" feature is used with an HTTP proxy,
3713    * we set the tunnel_proxy bit.
3714    *************************************************************/
3715   if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
3716       conn->bits.httpproxy)
3717     conn->bits.tunnel_proxy = TRUE;
3718 #endif
3719 
3720   /*************************************************************
3721    * Setup internals depending on protocol. Needs to be done after
3722    * we figured out what/if proxy to use.
3723    *************************************************************/
3724   result = setup_connection_internals(data, conn);
3725   if(result)
3726     goto out;
3727 
3728   conn->recv[FIRSTSOCKET] = Curl_recv_plain;
3729   conn->send[FIRSTSOCKET] = Curl_send_plain;
3730   conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
3731   conn->send[SECONDARYSOCKET] = Curl_send_plain;
3732 
3733   conn->bits.tcp_fastopen = data->set.tcp_fastopen;
3734 
3735   /***********************************************************************
3736    * file: is a special case in that it doesn't need a network connection
3737    ***********************************************************************/
3738 #ifndef CURL_DISABLE_FILE
3739   if(conn->handler->flags & PROTOPT_NONETWORK) {
3740     bool done;
3741     /* this is supposed to be the connect function so we better at least check
3742        that the file is present here! */
3743     DEBUGASSERT(conn->handler->connect_it);
3744     Curl_persistconninfo(data, conn, NULL, -1);
3745     result = conn->handler->connect_it(data, &done);
3746 
3747     /* Setup a "faked" transfer that'll do nothing */
3748     if(!result) {
3749       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
3750 
3751       Curl_attach_connnection(data, conn);
3752       result = Curl_conncache_add_conn(data);
3753       if(result)
3754         goto out;
3755 
3756       /*
3757        * Setup whatever necessary for a resumed transfer
3758        */
3759       result = setup_range(data);
3760       if(result) {
3761         DEBUGASSERT(conn->handler->done);
3762         /* we ignore the return code for the protocol-specific DONE */
3763         (void)conn->handler->done(data, result, FALSE);
3764         goto out;
3765       }
3766       Curl_setup_transfer(data, -1, -1, FALSE, -1);
3767     }
3768 
3769     /* since we skip do_init() */
3770     Curl_init_do(data, conn);
3771 
3772     goto out;
3773   }
3774 #endif
3775 
3776   /* Get a cloned copy of the SSL config situation stored in the
3777      connection struct. But to get this going nicely, we must first make
3778      sure that the strings in the master copy are pointing to the correct
3779      strings in the session handle strings array!
3780 
3781      Keep in mind that the pointers in the master copy are pointing to strings
3782      that will be freed as part of the Curl_easy struct, but all cloned
3783      copies will be separately allocated.
3784   */
3785   data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH];
3786   data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
3787   data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
3788   data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
3789   data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
3790   data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
3791   data->set.ssl.primary.cipher_list =
3792     data->set.str[STRING_SSL_CIPHER_LIST];
3793   data->set.ssl.primary.cipher_list13 =
3794     data->set.str[STRING_SSL_CIPHER13_LIST];
3795   data->set.ssl.primary.pinned_key =
3796     data->set.str[STRING_SSL_PINNEDPUBLICKEY];
3797   data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT];
3798   data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO];
3799   data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
3800 
3801 #ifndef CURL_DISABLE_PROXY
3802   data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
3803   data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
3804   data->set.proxy_ssl.primary.random_file =
3805     data->set.str[STRING_SSL_RANDOM_FILE];
3806   data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
3807   data->set.proxy_ssl.primary.cipher_list =
3808     data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
3809   data->set.proxy_ssl.primary.cipher_list13 =
3810     data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
3811   data->set.proxy_ssl.primary.pinned_key =
3812     data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
3813   data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
3814   data->set.proxy_ssl.primary.ca_info_blob =
3815     data->set.blobs[BLOB_CAINFO_PROXY];
3816   data->set.proxy_ssl.primary.issuercert =
3817     data->set.str[STRING_SSL_ISSUERCERT_PROXY];
3818   data->set.proxy_ssl.primary.issuercert_blob =
3819     data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY];
3820   data->set.proxy_ssl.primary.CRLfile =
3821     data->set.str[STRING_SSL_CRLFILE_PROXY];
3822   data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
3823   data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
3824   data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
3825   data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
3826   data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
3827   data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
3828 #endif
3829   data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE];
3830   data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
3831   data->set.ssl.key = data->set.str[STRING_KEY];
3832   data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
3833   data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD];
3834   data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
3835 #ifdef USE_TLS_SRP
3836   data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME];
3837   data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD];
3838 #ifndef CURL_DISABLE_PROXY
3839   data->set.proxy_ssl.primary.username =
3840     data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
3841   data->set.proxy_ssl.primary.password =
3842     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.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