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