source: EcnlProtoTool/trunk/curl-7.57.0/lib/url.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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