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