VirtualBox

source: vbox/trunk/src/libs/curl-7.64.0/lib/url.c@ 86643

Last change on this file since 86643 was 85671, checked in by vboxsync, 4 years ago

Export out internal curl copy to make it a lot simpler to build VBox (OSE) on Windows. bugref:9814

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette