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