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