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