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