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