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