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