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