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