url.c revision e3149cc1cf501b46caba8d47652ac90b95c78eac
1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#ifdef HAVE_NETINET_IN_H
26#include <netinet/in.h>
27#endif
28#ifdef HAVE_NETDB_H
29#include <netdb.h>
30#endif
31#ifdef HAVE_ARPA_INET_H
32#include <arpa/inet.h>
33#endif
34#ifdef HAVE_NET_IF_H
35#include <net/if.h>
36#endif
37#ifdef HAVE_SYS_IOCTL_H
38#include <sys/ioctl.h>
39#endif
40
41#ifdef HAVE_SYS_PARAM_H
42#include <sys/param.h>
43#endif
44
45#ifdef __VMS
46#include <in.h>
47#include <inet.h>
48#endif
49
50#ifdef HAVE_SYS_UN_H
51#include <sys/un.h>
52#endif
53
54#ifndef HAVE_SOCKET
55#error "We can't compile without socket() support!"
56#endif
57
58#ifdef HAVE_LIMITS_H
59#include <limits.h>
60#endif
61
62#ifdef USE_LIBIDN
63#include <idna.h>
64#include <tld.h>
65#include <stringprep.h>
66#ifdef HAVE_IDN_FREE_H
67#include <idn-free.h>
68#else
69/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
70void idn_free (void *ptr);
71#endif
72#ifndef HAVE_IDN_FREE
73/* if idn_free() was not found in this version of libidn use free() instead */
74#define idn_free(x) (free)(x)
75#endif
76#elif defined(USE_WIN32_IDN)
77/* prototype for curl_win32_idn_to_ascii() */
78bool curl_win32_idn_to_ascii(const char *in, char **out);
79#endif  /* USE_LIBIDN */
80
81#include "urldata.h"
82#include "netrc.h"
83
84#include "formdata.h"
85#include "vtls/vtls.h"
86#include "hostip.h"
87#include "transfer.h"
88#include "sendf.h"
89#include "progress.h"
90#include "cookie.h"
91#include "strequal.h"
92#include "strerror.h"
93#include "escape.h"
94#include "strtok.h"
95#include "share.h"
96#include "content_encoding.h"
97#include "http_digest.h"
98#include "http_negotiate.h"
99#include "select.h"
100#include "multiif.h"
101#include "easyif.h"
102#include "speedcheck.h"
103#include "rawstr.h"
104#include "warnless.h"
105#include "non-ascii.h"
106#include "inet_pton.h"
107
108/* And now for the protocols */
109#include "ftp.h"
110#include "dict.h"
111#include "telnet.h"
112#include "tftp.h"
113#include "http.h"
114#include "http2.h"
115#include "file.h"
116#include "curl_ldap.h"
117#include "ssh.h"
118#include "imap.h"
119#include "url.h"
120#include "connect.h"
121#include "inet_ntop.h"
122#include "http_ntlm.h"
123#include "curl_ntlm_wb.h"
124#include "socks.h"
125#include "curl_rtmp.h"
126#include "gopher.h"
127#include "http_proxy.h"
128#include "conncache.h"
129#include "multihandle.h"
130#include "pipeline.h"
131#include "dotdot.h"
132#include "strdup.h"
133/* The last 3 #include files should be in this order */
134#include "curl_printf.h"
135#include "curl_memory.h"
136#include "memdebug.h"
137
138/* Local static prototypes */
139static struct connectdata *
140find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
141                                      struct connectbundle *bundle);
142static void conn_free(struct connectdata *conn);
143static void free_fixed_hostname(struct hostname *host);
144static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
145static CURLcode parse_url_login(struct Curl_easy *data,
146                                struct connectdata *conn,
147                                char **userptr, char **passwdptr,
148                                char **optionsptr);
149static CURLcode parse_login_details(const char *login, const size_t len,
150                                    char **userptr, char **passwdptr,
151                                    char **optionsptr);
152static unsigned int get_protocol_family(unsigned int protocol);
153
154/*
155 * Protocol table.
156 */
157
158static const struct Curl_handler * const protocols[] = {
159
160#ifndef CURL_DISABLE_HTTP
161  &Curl_handler_http,
162#endif
163
164#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
165  &Curl_handler_https,
166#endif
167
168#ifndef CURL_DISABLE_FTP
169  &Curl_handler_ftp,
170#endif
171
172#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
173  &Curl_handler_ftps,
174#endif
175
176#ifndef CURL_DISABLE_TELNET
177  &Curl_handler_telnet,
178#endif
179
180#ifndef CURL_DISABLE_DICT
181  &Curl_handler_dict,
182#endif
183
184#ifndef CURL_DISABLE_LDAP
185  &Curl_handler_ldap,
186#if !defined(CURL_DISABLE_LDAPS) && \
187    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
188     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
189  &Curl_handler_ldaps,
190#endif
191#endif
192
193#ifndef CURL_DISABLE_FILE
194  &Curl_handler_file,
195#endif
196
197#ifndef CURL_DISABLE_TFTP
198  &Curl_handler_tftp,
199#endif
200
201#ifdef USE_LIBSSH2
202  &Curl_handler_scp,
203  &Curl_handler_sftp,
204#endif
205
206#ifndef CURL_DISABLE_IMAP
207  &Curl_handler_imap,
208#ifdef USE_SSL
209  &Curl_handler_imaps,
210#endif
211#endif
212
213#ifndef CURL_DISABLE_POP3
214  &Curl_handler_pop3,
215#ifdef USE_SSL
216  &Curl_handler_pop3s,
217#endif
218#endif
219
220#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
221   (CURL_SIZEOF_CURL_OFF_T > 4) && \
222   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
223  &Curl_handler_smb,
224#ifdef USE_SSL
225  &Curl_handler_smbs,
226#endif
227#endif
228
229#ifndef CURL_DISABLE_SMTP
230  &Curl_handler_smtp,
231#ifdef USE_SSL
232  &Curl_handler_smtps,
233#endif
234#endif
235
236#ifndef CURL_DISABLE_RTSP
237  &Curl_handler_rtsp,
238#endif
239
240#ifndef CURL_DISABLE_GOPHER
241  &Curl_handler_gopher,
242#endif
243
244#ifdef USE_LIBRTMP
245  &Curl_handler_rtmp,
246  &Curl_handler_rtmpt,
247  &Curl_handler_rtmpe,
248  &Curl_handler_rtmpte,
249  &Curl_handler_rtmps,
250  &Curl_handler_rtmpts,
251#endif
252
253  (struct Curl_handler *) NULL
254};
255
256/*
257 * Dummy handler for undefined protocol schemes.
258 */
259
260static const struct Curl_handler Curl_handler_dummy = {
261  "<no protocol>",                      /* scheme */
262  ZERO_NULL,                            /* setup_connection */
263  ZERO_NULL,                            /* do_it */
264  ZERO_NULL,                            /* done */
265  ZERO_NULL,                            /* do_more */
266  ZERO_NULL,                            /* connect_it */
267  ZERO_NULL,                            /* connecting */
268  ZERO_NULL,                            /* doing */
269  ZERO_NULL,                            /* proto_getsock */
270  ZERO_NULL,                            /* doing_getsock */
271  ZERO_NULL,                            /* domore_getsock */
272  ZERO_NULL,                            /* perform_getsock */
273  ZERO_NULL,                            /* disconnect */
274  ZERO_NULL,                            /* readwrite */
275  0,                                    /* defport */
276  0,                                    /* protocol */
277  PROTOPT_NONE                          /* flags */
278};
279
280void Curl_freeset(struct Curl_easy *data)
281{
282  /* Free all dynamic strings stored in the data->set substructure. */
283  enum dupstring i;
284  for(i=(enum dupstring)0; i < STRING_LAST; i++) {
285    Curl_safefree(data->set.str[i]);
286  }
287
288  if(data->change.referer_alloc) {
289    Curl_safefree(data->change.referer);
290    data->change.referer_alloc = FALSE;
291  }
292  data->change.referer = NULL;
293  if(data->change.url_alloc) {
294    Curl_safefree(data->change.url);
295    data->change.url_alloc = FALSE;
296  }
297  data->change.url = NULL;
298}
299
300static CURLcode setstropt(char **charp, const char *s)
301{
302  /* Release the previous storage at `charp' and replace by a dynamic storage
303     copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
304
305  Curl_safefree(*charp);
306
307  if(s) {
308    char *str = strdup(s);
309
310    if(!str)
311      return CURLE_OUT_OF_MEMORY;
312
313    *charp = str;
314  }
315
316  return CURLE_OK;
317}
318
319static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
320{
321  CURLcode result = CURLE_OK;
322  char *user = NULL;
323  char *passwd = NULL;
324
325  /* Parse the login details if specified. It not then we treat NULL as a hint
326     to clear the existing data */
327  if(option) {
328    result = parse_login_details(option, strlen(option),
329                                 (userp ? &user : NULL),
330                                 (passwdp ? &passwd : NULL),
331                                 NULL);
332  }
333
334  if(!result) {
335    /* Store the username part of option if required */
336    if(userp) {
337      if(!user && option && option[0] == ':') {
338        /* Allocate an empty string instead of returning NULL as user name */
339        user = strdup("");
340        if(!user)
341          result = CURLE_OUT_OF_MEMORY;
342      }
343
344      Curl_safefree(*userp);
345      *userp = user;
346    }
347
348    /* Store the password part of option if required */
349    if(passwdp) {
350      Curl_safefree(*passwdp);
351      *passwdp = passwd;
352    }
353  }
354
355  return result;
356}
357
358CURLcode Curl_dupset(struct Curl_easy *dst, struct Curl_easy *src)
359{
360  CURLcode result = CURLE_OK;
361  enum dupstring i;
362
363  /* Copy src->set into dst->set first, then deal with the strings
364     afterwards */
365  dst->set = src->set;
366
367  /* clear all string pointers first */
368  memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
369
370  /* duplicate all strings */
371  for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
372    result = setstropt(&dst->set.str[i], src->set.str[i]);
373    if(result)
374      return result;
375  }
376
377  /* duplicate memory areas pointed to */
378  i = STRING_COPYPOSTFIELDS;
379  if(src->set.postfieldsize && src->set.str[i]) {
380    /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
381    dst->set.str[i] = Curl_memdup(src->set.str[i],
382                                  curlx_sotouz(src->set.postfieldsize));
383    if(!dst->set.str[i])
384      return CURLE_OUT_OF_MEMORY;
385    /* point to the new copy */
386    dst->set.postfields = dst->set.str[i];
387  }
388
389  return CURLE_OK;
390}
391
392/*
393 * This is the internal function curl_easy_cleanup() calls. This should
394 * cleanup and free all resources associated with this sessionhandle.
395 *
396 * NOTE: if we ever add something that attempts to write to a socket or
397 * similar here, we must ignore SIGPIPE first. It is currently only done
398 * when curl_easy_perform() is invoked.
399 */
400
401CURLcode Curl_close(struct Curl_easy *data)
402{
403  struct Curl_multi *m;
404
405  if(!data)
406    return CURLE_OK;
407
408  Curl_expire(data, 0); /* shut off timers */
409
410  m = data->multi;
411
412  if(m)
413    /* This handle is still part of a multi handle, take care of this first
414       and detach this handle from there. */
415    curl_multi_remove_handle(data->multi, data);
416
417  if(data->multi_easy)
418    /* when curl_easy_perform() is used, it creates its own multi handle to
419       use and this is the one */
420    curl_multi_cleanup(data->multi_easy);
421
422  /* Destroy the timeout list that is held in the easy handle. It is
423     /normally/ done by curl_multi_remove_handle() but this is "just in
424     case" */
425  if(data->state.timeoutlist) {
426    Curl_llist_destroy(data->state.timeoutlist, NULL);
427    data->state.timeoutlist = NULL;
428  }
429
430  data->magic = 0; /* force a clear AFTER the possibly enforced removal from
431                      the multi handle, since that function uses the magic
432                      field! */
433
434  if(data->state.rangestringalloc)
435    free(data->state.range);
436
437  /* Free the pathbuffer */
438  Curl_safefree(data->state.pathbuffer);
439  data->state.path = NULL;
440
441  /* freed here just in case DONE wasn't called */
442  Curl_free_request_state(data);
443
444  /* Close down all open SSL info and sessions */
445  Curl_ssl_close_all(data);
446  Curl_safefree(data->state.first_host);
447  Curl_safefree(data->state.scratch);
448  Curl_ssl_free_certinfo(data);
449
450  /* Cleanup possible redirect junk */
451  free(data->req.newurl);
452  data->req.newurl = NULL;
453
454  if(data->change.referer_alloc) {
455    Curl_safefree(data->change.referer);
456    data->change.referer_alloc = FALSE;
457  }
458  data->change.referer = NULL;
459
460  if(data->change.url_alloc) {
461    Curl_safefree(data->change.url);
462    data->change.url_alloc = FALSE;
463  }
464  data->change.url = NULL;
465
466  Curl_safefree(data->state.headerbuff);
467
468  Curl_flush_cookies(data, 1);
469
470  Curl_digest_cleanup(data);
471
472  Curl_safefree(data->info.contenttype);
473  Curl_safefree(data->info.wouldredirect);
474
475  /* this destroys the channel and we cannot use it anymore after this */
476  Curl_resolver_cleanup(data->state.resolver);
477
478  Curl_convert_close(data);
479
480  /* No longer a dirty share, if it exists */
481  if(data->share) {
482    Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
483    data->share->dirty--;
484    Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
485  }
486
487  if(data->set.wildcardmatch) {
488    /* destruct wildcard structures if it is needed */
489    struct WildcardData *wc = &data->wildcard;
490    Curl_wildcard_dtor(wc);
491  }
492
493  Curl_freeset(data);
494  free(data);
495  return CURLE_OK;
496}
497
498/*
499 * Initialize the UserDefined fields within a Curl_easy.
500 * This may be safely called on a new or existing Curl_easy.
501 */
502CURLcode Curl_init_userdefined(struct UserDefined *set)
503{
504  CURLcode result = CURLE_OK;
505
506  set->out = stdout; /* default output to stdout */
507  set->in_set = stdin;  /* default input from stdin */
508  set->err  = stderr;  /* default stderr to stderr */
509
510  /* use fwrite as default function to store output */
511  set->fwrite_func = (curl_write_callback)fwrite;
512
513  /* use fread as default function to read input */
514  set->fread_func_set = (curl_read_callback)fread;
515  set->is_fread_set = 0;
516  set->is_fwrite_set = 0;
517
518  set->seek_func = ZERO_NULL;
519  set->seek_client = ZERO_NULL;
520
521  /* conversion callbacks for non-ASCII hosts */
522  set->convfromnetwork = ZERO_NULL;
523  set->convtonetwork   = ZERO_NULL;
524  set->convfromutf8    = ZERO_NULL;
525
526  set->filesize = -1;        /* we don't know the size */
527  set->postfieldsize = -1;   /* unknown size */
528  set->maxredirs = -1;       /* allow any amount by default */
529
530  set->httpreq = HTTPREQ_GET; /* Default HTTP request */
531  set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
532  set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
533  set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
534  set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
535  set->ftp_filemethod = FTPFILE_MULTICWD;
536
537  set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
538
539  /* Set the default size of the SSL session ID cache */
540  set->ssl.max_ssl_sessions = 5;
541
542  set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
543  set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
544  set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
545  set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
546
547  /* make libcurl quiet by default: */
548  set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
549
550  /*
551   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
552   * switched off unless wanted.
553   */
554  set->ssl.verifypeer = TRUE;
555  set->ssl.verifyhost = TRUE;
556#ifdef USE_TLS_SRP
557  set->ssl.authtype = CURL_TLSAUTH_NONE;
558#endif
559  set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
560                                                      type */
561  set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
562
563  set->new_file_perms = 0644;    /* Default permissions */
564  set->new_directory_perms = 0755; /* Default permissions */
565
566  /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
567     define since we internally only use the lower 16 bits for the passed
568     in bitmask to not conflict with the private bits */
569  set->allowed_protocols = CURLPROTO_ALL;
570  set->redir_protocols = CURLPROTO_ALL &  /* All except FILE, SCP and SMB */
571                          ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
572                            CURLPROTO_SMBS);
573
574#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
575  /*
576   * disallow unprotected protection negotiation NEC reference implementation
577   * seem not to follow rfc1961 section 4.3/4.4
578   */
579  set->socks5_gssapi_nec = FALSE;
580#endif
581
582  /* This is our preferred CA cert bundle/path since install time */
583#if defined(CURL_CA_BUNDLE)
584  result = setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE);
585  if(result)
586    return result;
587#endif
588#if defined(CURL_CA_PATH)
589  result = setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH);
590  if(result)
591    return result;
592#endif
593
594  set->wildcardmatch  = FALSE;
595  set->chunk_bgn      = ZERO_NULL;
596  set->chunk_end      = ZERO_NULL;
597
598  /* tcp keepalives are disabled by default, but provide reasonable values for
599   * the interval and idle times.
600   */
601  set->tcp_keepalive = FALSE;
602  set->tcp_keepintvl = 60;
603  set->tcp_keepidle = 60;
604  set->tcp_fastopen = FALSE;
605
606  set->ssl_enable_npn = TRUE;
607  set->ssl_enable_alpn = TRUE;
608
609  set->expect_100_timeout = 1000L; /* Wait for a second by default. */
610  set->sep_headers = TRUE; /* separated header lists by default */
611
612  Curl_http2_init_userset(set);
613  return result;
614}
615
616/**
617 * Curl_open()
618 *
619 * @param curl is a pointer to a sessionhandle pointer that gets set by this
620 * function.
621 * @return CURLcode
622 */
623
624CURLcode Curl_open(struct Curl_easy **curl)
625{
626  CURLcode result;
627  struct Curl_easy *data;
628
629  /* Very simple start-up: alloc the struct, init it with zeroes and return */
630  data = calloc(1, sizeof(struct Curl_easy));
631  if(!data) {
632    /* this is a very serious error */
633    DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n"));
634    return CURLE_OUT_OF_MEMORY;
635  }
636
637  data->magic = CURLEASY_MAGIC_NUMBER;
638
639  result = Curl_resolver_init(&data->state.resolver);
640  if(result) {
641    DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
642    free(data);
643    return result;
644  }
645
646  /* We do some initial setup here, all those fields that can't be just 0 */
647
648  data->state.headerbuff = malloc(HEADERSIZE);
649  if(!data->state.headerbuff) {
650    DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
651    result = CURLE_OUT_OF_MEMORY;
652  }
653  else {
654    result = Curl_init_userdefined(&data->set);
655
656    data->state.headersize=HEADERSIZE;
657
658    Curl_convert_init(data);
659
660    /* most recent connection is not yet defined */
661    data->state.lastconnect = NULL;
662
663    data->progress.flags |= PGRS_HIDE;
664    data->state.current_speed = -1; /* init to negative == impossible */
665
666    data->wildcard.state = CURLWC_INIT;
667    data->wildcard.filelist = NULL;
668    data->set.fnmatch = ZERO_NULL;
669    data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
670
671    Curl_http2_init_state(&data->state);
672  }
673
674  if(result) {
675    Curl_resolver_cleanup(data->state.resolver);
676    free(data->state.headerbuff);
677    Curl_freeset(data);
678    free(data);
679    data = NULL;
680  }
681  else
682    *curl = data;
683
684  return result;
685}
686
687CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
688                     va_list param)
689{
690  char *argptr;
691  CURLcode result = CURLE_OK;
692  long arg;
693#ifndef CURL_DISABLE_HTTP
694  curl_off_t bigsize;
695#endif
696
697  switch(option) {
698  case CURLOPT_DNS_CACHE_TIMEOUT:
699    data->set.dns_cache_timeout = va_arg(param, long);
700    break;
701  case CURLOPT_DNS_USE_GLOBAL_CACHE:
702    /* remember we want this enabled */
703    arg = va_arg(param, long);
704    data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE;
705    break;
706  case CURLOPT_SSL_CIPHER_LIST:
707    /* set a list of cipher we want to use in the SSL connection */
708    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
709                       va_arg(param, char *));
710    break;
711
712  case CURLOPT_RANDOM_FILE:
713    /*
714     * This is the path name to a file that contains random data to seed
715     * the random SSL stuff with. The file is only used for reading.
716     */
717    result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
718                       va_arg(param, char *));
719    break;
720  case CURLOPT_EGDSOCKET:
721    /*
722     * The Entropy Gathering Daemon socket pathname
723     */
724    result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
725                       va_arg(param, char *));
726    break;
727  case CURLOPT_MAXCONNECTS:
728    /*
729     * Set the absolute number of maximum simultaneous alive connection that
730     * libcurl is allowed to have.
731     */
732    data->set.maxconnects = va_arg(param, long);
733    break;
734  case CURLOPT_FORBID_REUSE:
735    /*
736     * When this transfer is done, it must not be left to be reused by a
737     * subsequent transfer but shall be closed immediately.
738     */
739    data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE;
740    break;
741  case CURLOPT_FRESH_CONNECT:
742    /*
743     * This transfer shall not use a previously cached connection but
744     * should be made with a fresh new connect!
745     */
746    data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE;
747    break;
748  case CURLOPT_VERBOSE:
749    /*
750     * Verbose means infof() calls that give a lot of information about
751     * the connection and transfer procedures as well as internal choices.
752     */
753    data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE;
754    break;
755  case CURLOPT_HEADER:
756    /*
757     * Set to include the header in the general data output stream.
758     */
759    data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE;
760    break;
761  case CURLOPT_NOPROGRESS:
762    /*
763     * Shut off the internal supported progress meter
764     */
765    data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE;
766    if(data->set.hide_progress)
767      data->progress.flags |= PGRS_HIDE;
768    else
769      data->progress.flags &= ~PGRS_HIDE;
770    break;
771  case CURLOPT_NOBODY:
772    /*
773     * Do not include the body part in the output data stream.
774     */
775    data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
776    break;
777  case CURLOPT_FAILONERROR:
778    /*
779     * Don't output the >=400 error code HTML-page, but instead only
780     * return error.
781     */
782    data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
783    break;
784  case CURLOPT_UPLOAD:
785  case CURLOPT_PUT:
786    /*
787     * We want to sent data to the remote host. If this is HTTP, that equals
788     * using the PUT request.
789     */
790    data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
791    if(data->set.upload) {
792      /* If this is HTTP, PUT is what's needed to "upload" */
793      data->set.httpreq = HTTPREQ_PUT;
794      data->set.opt_no_body = FALSE; /* this is implied */
795    }
796    else
797      /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
798         then this can be changed to HEAD later on) */
799      data->set.httpreq = HTTPREQ_GET;
800    break;
801  case CURLOPT_FILETIME:
802    /*
803     * Try to get the file time of the remote document. The time will
804     * later (possibly) become available using curl_easy_getinfo().
805     */
806    data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
807    break;
808  case CURLOPT_FTP_CREATE_MISSING_DIRS:
809    /*
810     * An FTP option that modifies an upload to create missing directories on
811     * the server.
812     */
813    switch(va_arg(param, long)) {
814    case 0:
815      data->set.ftp_create_missing_dirs = 0;
816      break;
817    case 1:
818      data->set.ftp_create_missing_dirs = 1;
819      break;
820    case 2:
821      data->set.ftp_create_missing_dirs = 2;
822      break;
823    default:
824      /* reserve other values for future use */
825      result = CURLE_UNKNOWN_OPTION;
826      break;
827    }
828    break;
829  case CURLOPT_SERVER_RESPONSE_TIMEOUT:
830    /*
831     * Option that specifies how quickly an server response must be obtained
832     * before it is considered failure. For pingpong protocols.
833     */
834    data->set.server_response_timeout = va_arg(param, long) * 1000;
835    break;
836  case CURLOPT_TFTP_NO_OPTIONS:
837    /*
838     * Option that prevents libcurl from sending TFTP option requests to the
839     * server.
840     */
841    data->set.tftp_no_options = va_arg(param, long) != 0;
842    break;
843  case CURLOPT_TFTP_BLKSIZE:
844    /*
845     * TFTP option that specifies the block size to use for data transmission.
846     */
847    data->set.tftp_blksize = va_arg(param, long);
848    break;
849  case CURLOPT_DIRLISTONLY:
850    /*
851     * An option that changes the command to one that asks for a list
852     * only, no file info details.
853     */
854    data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
855    break;
856  case CURLOPT_APPEND:
857    /*
858     * We want to upload and append to an existing file.
859     */
860    data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
861    break;
862  case CURLOPT_FTP_FILEMETHOD:
863    /*
864     * How do access files over FTP.
865     */
866    data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
867    break;
868  case CURLOPT_NETRC:
869    /*
870     * Parse the $HOME/.netrc file
871     */
872    data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
873    break;
874  case CURLOPT_NETRC_FILE:
875    /*
876     * Use this file instead of the $HOME/.netrc file
877     */
878    result = setstropt(&data->set.str[STRING_NETRC_FILE],
879                       va_arg(param, char *));
880    break;
881  case CURLOPT_TRANSFERTEXT:
882    /*
883     * This option was previously named 'FTPASCII'. Renamed to work with
884     * more protocols than merely FTP.
885     *
886     * Transfer using ASCII (instead of BINARY).
887     */
888    data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE;
889    break;
890  case CURLOPT_TIMECONDITION:
891    /*
892     * Set HTTP time condition. This must be one of the defines in the
893     * curl/curl.h header file.
894     */
895    data->set.timecondition = (curl_TimeCond)va_arg(param, long);
896    break;
897  case CURLOPT_TIMEVALUE:
898    /*
899     * This is the value to compare with the remote document with the
900     * method set with CURLOPT_TIMECONDITION
901     */
902    data->set.timevalue = (time_t)va_arg(param, long);
903    break;
904  case CURLOPT_SSLVERSION:
905    /*
906     * Set explicit SSL version to try to connect with, as some SSL
907     * implementations are lame.
908     */
909#ifdef USE_SSL
910    data->set.ssl.version = va_arg(param, long);
911#else
912    result = CURLE_UNKNOWN_OPTION;
913#endif
914    break;
915
916#ifndef CURL_DISABLE_HTTP
917  case CURLOPT_AUTOREFERER:
918    /*
919     * Switch on automatic referer that gets set if curl follows locations.
920     */
921    data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
922    break;
923
924  case CURLOPT_ACCEPT_ENCODING:
925    /*
926     * String to use at the value of Accept-Encoding header.
927     *
928     * If the encoding is set to "" we use an Accept-Encoding header that
929     * encompasses all the encodings we support.
930     * If the encoding is set to NULL we don't send an Accept-Encoding header
931     * and ignore an received Content-Encoding header.
932     *
933     */
934    argptr = va_arg(param, char *);
935    result = setstropt(&data->set.str[STRING_ENCODING],
936                       (argptr && !*argptr)?
937                       ALL_CONTENT_ENCODINGS: argptr);
938    break;
939
940  case CURLOPT_TRANSFER_ENCODING:
941    data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
942                                       TRUE : FALSE;
943    break;
944
945  case CURLOPT_FOLLOWLOCATION:
946    /*
947     * Follow Location: header hints on a HTTP-server.
948     */
949    data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
950    break;
951
952  case CURLOPT_UNRESTRICTED_AUTH:
953    /*
954     * Send authentication (user+password) when following locations, even when
955     * hostname changed.
956     */
957    data->set.http_disable_hostname_check_before_authentication =
958      (0 != va_arg(param, long)) ? TRUE : FALSE;
959    break;
960
961  case CURLOPT_MAXREDIRS:
962    /*
963     * The maximum amount of hops you allow curl to follow Location:
964     * headers. This should mostly be used to detect never-ending loops.
965     */
966    data->set.maxredirs = va_arg(param, long);
967    break;
968
969  case CURLOPT_POSTREDIR:
970  {
971    /*
972     * Set the behaviour of POST when redirecting
973     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
974     * CURL_REDIR_POST_301 - POST is kept as POST after 301
975     * CURL_REDIR_POST_302 - POST is kept as POST after 302
976     * CURL_REDIR_POST_303 - POST is kept as POST after 303
977     * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
978     * other - POST is kept as POST after 301 and 302
979     */
980    int postRedir = curlx_sltosi(va_arg(param, long));
981    data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
982  }
983  break;
984
985  case CURLOPT_POST:
986    /* Does this option serve a purpose anymore? Yes it does, when
987       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
988       callback! */
989    if(va_arg(param, long)) {
990      data->set.httpreq = HTTPREQ_POST;
991      data->set.opt_no_body = FALSE; /* this is implied */
992    }
993    else
994      data->set.httpreq = HTTPREQ_GET;
995    break;
996
997  case CURLOPT_COPYPOSTFIELDS:
998    /*
999     * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
1000     * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
1001     *  CURLOPT_COPYPOSTFIELDS and not altered later.
1002     */
1003    argptr = va_arg(param, char *);
1004
1005    if(!argptr || data->set.postfieldsize == -1)
1006      result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
1007    else {
1008      /*
1009       *  Check that requested length does not overflow the size_t type.
1010       */
1011
1012      if((data->set.postfieldsize < 0) ||
1013         ((sizeof(curl_off_t) != sizeof(size_t)) &&
1014          (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1015        result = CURLE_OUT_OF_MEMORY;
1016      else {
1017        char * p;
1018
1019        (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1020
1021        /* Allocate even when size == 0. This satisfies the need of possible
1022           later address compare to detect the COPYPOSTFIELDS mode, and
1023           to mark that postfields is used rather than read function or
1024           form data.
1025        */
1026        p = malloc((size_t)(data->set.postfieldsize?
1027                            data->set.postfieldsize:1));
1028
1029        if(!p)
1030          result = CURLE_OUT_OF_MEMORY;
1031        else {
1032          if(data->set.postfieldsize)
1033            memcpy(p, argptr, (size_t)data->set.postfieldsize);
1034
1035          data->set.str[STRING_COPYPOSTFIELDS] = p;
1036        }
1037      }
1038    }
1039
1040    data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1041    data->set.httpreq = HTTPREQ_POST;
1042    break;
1043
1044  case CURLOPT_POSTFIELDS:
1045    /*
1046     * Like above, but use static data instead of copying it.
1047     */
1048    data->set.postfields = va_arg(param, void *);
1049    /* Release old copied data. */
1050    (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1051    data->set.httpreq = HTTPREQ_POST;
1052    break;
1053
1054  case CURLOPT_POSTFIELDSIZE:
1055    /*
1056     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1057     * figure it out. Enables binary posts.
1058     */
1059    bigsize = va_arg(param, long);
1060
1061    if(data->set.postfieldsize < bigsize &&
1062       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1063      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1064      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1065      data->set.postfields = NULL;
1066    }
1067
1068    data->set.postfieldsize = bigsize;
1069    break;
1070
1071  case CURLOPT_POSTFIELDSIZE_LARGE:
1072    /*
1073     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1074     * figure it out. Enables binary posts.
1075     */
1076    bigsize = va_arg(param, curl_off_t);
1077
1078    if(data->set.postfieldsize < bigsize &&
1079       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1080      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1081      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1082      data->set.postfields = NULL;
1083    }
1084
1085    data->set.postfieldsize = bigsize;
1086    break;
1087
1088  case CURLOPT_HTTPPOST:
1089    /*
1090     * Set to make us do HTTP POST
1091     */
1092    data->set.httppost = va_arg(param, struct curl_httppost *);
1093    data->set.httpreq = HTTPREQ_POST_FORM;
1094    data->set.opt_no_body = FALSE; /* this is implied */
1095    break;
1096
1097  case CURLOPT_REFERER:
1098    /*
1099     * String to set in the HTTP Referer: field.
1100     */
1101    if(data->change.referer_alloc) {
1102      Curl_safefree(data->change.referer);
1103      data->change.referer_alloc = FALSE;
1104    }
1105    result = setstropt(&data->set.str[STRING_SET_REFERER],
1106                       va_arg(param, char *));
1107    data->change.referer = data->set.str[STRING_SET_REFERER];
1108    break;
1109
1110  case CURLOPT_USERAGENT:
1111    /*
1112     * String to use in the HTTP User-Agent field
1113     */
1114    result = setstropt(&data->set.str[STRING_USERAGENT],
1115                       va_arg(param, char *));
1116    break;
1117
1118  case CURLOPT_HTTPHEADER:
1119    /*
1120     * Set a list with HTTP headers to use (or replace internals with)
1121     */
1122    data->set.headers = va_arg(param, struct curl_slist *);
1123    break;
1124
1125  case CURLOPT_PROXYHEADER:
1126    /*
1127     * Set a list with proxy headers to use (or replace internals with)
1128     *
1129     * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1130     * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1131     * used. As soon as this option has been used, if set to anything but
1132     * NULL, custom headers for proxies are only picked from this list.
1133     *
1134     * Set this option to NULL to restore the previous behavior.
1135     */
1136    data->set.proxyheaders = va_arg(param, struct curl_slist *);
1137    break;
1138
1139  case CURLOPT_HEADEROPT:
1140    /*
1141     * Set header option.
1142     */
1143    arg = va_arg(param, long);
1144    data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
1145    break;
1146
1147  case CURLOPT_HTTP200ALIASES:
1148    /*
1149     * Set a list of aliases for HTTP 200 in response header
1150     */
1151    data->set.http200aliases = va_arg(param, struct curl_slist *);
1152    break;
1153
1154#if !defined(CURL_DISABLE_COOKIES)
1155  case CURLOPT_COOKIE:
1156    /*
1157     * Cookie string to send to the remote server in the request.
1158     */
1159    result = setstropt(&data->set.str[STRING_COOKIE],
1160                       va_arg(param, char *));
1161    break;
1162
1163  case CURLOPT_COOKIEFILE:
1164    /*
1165     * Set cookie file to read and parse. Can be used multiple times.
1166     */
1167    argptr = (char *)va_arg(param, void *);
1168    if(argptr) {
1169      struct curl_slist *cl;
1170      /* append the cookie file name to the list of file names, and deal with
1171         them later */
1172      cl = curl_slist_append(data->change.cookielist, argptr);
1173      if(!cl) {
1174        curl_slist_free_all(data->change.cookielist);
1175        data->change.cookielist = NULL;
1176        return CURLE_OUT_OF_MEMORY;
1177      }
1178      data->change.cookielist = cl; /* store the list for later use */
1179    }
1180    break;
1181
1182  case CURLOPT_COOKIEJAR:
1183    /*
1184     * Set cookie file name to dump all cookies to when we're done.
1185     */
1186  {
1187    struct CookieInfo *newcookies;
1188    result = setstropt(&data->set.str[STRING_COOKIEJAR],
1189                       va_arg(param, char *));
1190
1191    /*
1192     * Activate the cookie parser. This may or may not already
1193     * have been made.
1194     */
1195    newcookies = Curl_cookie_init(data, NULL, data->cookies,
1196                                  data->set.cookiesession);
1197    if(!newcookies)
1198      result = CURLE_OUT_OF_MEMORY;
1199    data->cookies = newcookies;
1200  }
1201    break;
1202
1203  case CURLOPT_COOKIESESSION:
1204    /*
1205     * Set this option to TRUE to start a new "cookie session". It will
1206     * prevent the forthcoming read-cookies-from-file actions to accept
1207     * cookies that are marked as being session cookies, as they belong to a
1208     * previous session.
1209     *
1210     * In the original Netscape cookie spec, "session cookies" are cookies
1211     * with no expire date set. RFC2109 describes the same action if no
1212     * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1213     * a 'Discard' action that can enforce the discard even for cookies that
1214     * have a Max-Age.
1215     *
1216     * We run mostly with the original cookie spec, as hardly anyone implements
1217     * anything else.
1218     */
1219    data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE;
1220    break;
1221
1222  case CURLOPT_COOKIELIST:
1223    argptr = va_arg(param, char *);
1224
1225    if(argptr == NULL)
1226      break;
1227
1228    if(Curl_raw_equal(argptr, "ALL")) {
1229      /* clear all cookies */
1230      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1231      Curl_cookie_clearall(data->cookies);
1232      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1233    }
1234    else if(Curl_raw_equal(argptr, "SESS")) {
1235      /* clear session cookies */
1236      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1237      Curl_cookie_clearsess(data->cookies);
1238      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1239    }
1240    else if(Curl_raw_equal(argptr, "FLUSH")) {
1241      /* flush cookies to file, takes care of the locking */
1242      Curl_flush_cookies(data, 0);
1243    }
1244    else if(Curl_raw_equal(argptr, "RELOAD")) {
1245      /* reload cookies from file */
1246      Curl_cookie_loadfiles(data);
1247      break;
1248    }
1249    else {
1250      if(!data->cookies)
1251        /* if cookie engine was not running, activate it */
1252        data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1253
1254      argptr = strdup(argptr);
1255      if(!argptr || !data->cookies) {
1256        result = CURLE_OUT_OF_MEMORY;
1257        free(argptr);
1258      }
1259      else {
1260        Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1261
1262        if(checkprefix("Set-Cookie:", argptr))
1263          /* HTTP Header format line */
1264          Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1265
1266        else
1267          /* Netscape format line */
1268          Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1269
1270        Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1271        free(argptr);
1272      }
1273    }
1274
1275    break;
1276#endif /* CURL_DISABLE_COOKIES */
1277
1278  case CURLOPT_HTTPGET:
1279    /*
1280     * Set to force us do HTTP GET
1281     */
1282    if(va_arg(param, long)) {
1283      data->set.httpreq = HTTPREQ_GET;
1284      data->set.upload = FALSE; /* switch off upload */
1285      data->set.opt_no_body = FALSE; /* this is implied */
1286    }
1287    break;
1288
1289  case CURLOPT_HTTP_VERSION:
1290    /*
1291     * This sets a requested HTTP version to be used. The value is one of
1292     * the listed enums in curl/curl.h.
1293     */
1294    arg = va_arg(param, long);
1295#ifndef USE_NGHTTP2
1296    if(arg >= CURL_HTTP_VERSION_2)
1297      return CURLE_UNSUPPORTED_PROTOCOL;
1298#endif
1299    data->set.httpversion = arg;
1300    break;
1301
1302  case CURLOPT_HTTPAUTH:
1303    /*
1304     * Set HTTP Authentication type BITMASK.
1305     */
1306  {
1307    int bitcheck;
1308    bool authbits;
1309    unsigned long auth = va_arg(param, unsigned long);
1310
1311    if(auth == CURLAUTH_NONE) {
1312      data->set.httpauth = auth;
1313      break;
1314    }
1315
1316    /* the DIGEST_IE bit is only used to set a special marker, for all the
1317       rest we need to handle it as normal DIGEST */
1318    data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
1319
1320    if(auth & CURLAUTH_DIGEST_IE) {
1321      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1322      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1323    }
1324
1325    /* switch off bits we can't support */
1326#ifndef USE_NTLM
1327    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
1328    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1329#elif !defined(NTLM_WB_ENABLED)
1330    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1331#endif
1332#ifndef USE_SPNEGO
1333    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1334                                    GSS-API or SSPI */
1335#endif
1336
1337    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1338    bitcheck = 0;
1339    authbits = FALSE;
1340    while(bitcheck < 31) {
1341      if(auth & (1UL << bitcheck++)) {
1342        authbits = TRUE;
1343        break;
1344      }
1345    }
1346    if(!authbits)
1347      return CURLE_NOT_BUILT_IN; /* no supported types left! */
1348
1349    data->set.httpauth = auth;
1350  }
1351  break;
1352
1353  case CURLOPT_EXPECT_100_TIMEOUT_MS:
1354    /*
1355     * Time to wait for a response to a HTTP request containing an
1356     * Expect: 100-continue header before sending the data anyway.
1357     */
1358    data->set.expect_100_timeout = va_arg(param, long);
1359    break;
1360
1361#endif   /* CURL_DISABLE_HTTP */
1362
1363  case CURLOPT_CUSTOMREQUEST:
1364    /*
1365     * Set a custom string to use as request
1366     */
1367    result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1368                       va_arg(param, char *));
1369
1370    /* we don't set
1371       data->set.httpreq = HTTPREQ_CUSTOM;
1372       here, we continue as if we were using the already set type
1373       and this just changes the actual request keyword */
1374    break;
1375
1376#ifndef CURL_DISABLE_PROXY
1377  case CURLOPT_HTTPPROXYTUNNEL:
1378    /*
1379     * Tunnel operations through the proxy instead of normal proxy use
1380     */
1381    data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ?
1382                                      TRUE : FALSE;
1383    break;
1384
1385  case CURLOPT_PROXYPORT:
1386    /*
1387     * Explicitly set HTTP proxy port number.
1388     */
1389    data->set.proxyport = va_arg(param, long);
1390    break;
1391
1392  case CURLOPT_PROXYAUTH:
1393    /*
1394     * Set HTTP Authentication type BITMASK.
1395     */
1396  {
1397    int bitcheck;
1398    bool authbits;
1399    unsigned long auth = va_arg(param, unsigned long);
1400
1401    if(auth == CURLAUTH_NONE) {
1402      data->set.proxyauth = auth;
1403      break;
1404    }
1405
1406    /* the DIGEST_IE bit is only used to set a special marker, for all the
1407       rest we need to handle it as normal DIGEST */
1408    data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
1409
1410    if(auth & CURLAUTH_DIGEST_IE) {
1411      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1412      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1413    }
1414    /* switch off bits we can't support */
1415#ifndef USE_NTLM
1416    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
1417    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1418#elif !defined(NTLM_WB_ENABLED)
1419    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
1420#endif
1421#ifndef USE_SPNEGO
1422    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
1423                                    GSS-API or SSPI */
1424#endif
1425
1426    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
1427    bitcheck = 0;
1428    authbits = FALSE;
1429    while(bitcheck < 31) {
1430      if(auth & (1UL << bitcheck++)) {
1431        authbits = TRUE;
1432        break;
1433      }
1434    }
1435    if(!authbits)
1436      return CURLE_NOT_BUILT_IN; /* no supported types left! */
1437
1438    data->set.proxyauth = auth;
1439  }
1440  break;
1441
1442  case CURLOPT_PROXY:
1443    /*
1444     * Set proxy server:port to use as HTTP proxy.
1445     *
1446     * If the proxy is set to "" we explicitly say that we don't want to use a
1447     * proxy (even though there might be environment variables saying so).
1448     *
1449     * Setting it to NULL, means no proxy but allows the environment variables
1450     * to decide for us.
1451     */
1452    result = setstropt(&data->set.str[STRING_PROXY],
1453                       va_arg(param, char *));
1454    break;
1455
1456  case CURLOPT_PROXYTYPE:
1457    /*
1458     * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1459     */
1460    data->set.proxytype = (curl_proxytype)va_arg(param, long);
1461    break;
1462
1463  case CURLOPT_PROXY_TRANSFER_MODE:
1464    /*
1465     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1466     */
1467    switch (va_arg(param, long)) {
1468    case 0:
1469      data->set.proxy_transfer_mode = FALSE;
1470      break;
1471    case 1:
1472      data->set.proxy_transfer_mode = TRUE;
1473      break;
1474    default:
1475      /* reserve other values for future use */
1476      result = CURLE_UNKNOWN_OPTION;
1477      break;
1478    }
1479    break;
1480#endif   /* CURL_DISABLE_PROXY */
1481
1482#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1483  case CURLOPT_SOCKS5_GSSAPI_NEC:
1484    /*
1485     * Set flag for NEC SOCK5 support
1486     */
1487    data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
1488    break;
1489
1490  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1491  case CURLOPT_PROXY_SERVICE_NAME:
1492    /*
1493     * Set proxy authentication service name for Kerberos 5 and SPNEGO
1494     */
1495    result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
1496                       va_arg(param, char *));
1497    break;
1498#endif
1499
1500#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
1501    defined(USE_SPNEGO)
1502  case CURLOPT_SERVICE_NAME:
1503    /*
1504     * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
1505     */
1506    result = setstropt(&data->set.str[STRING_SERVICE_NAME],
1507                       va_arg(param, char *));
1508    break;
1509
1510#endif
1511
1512  case CURLOPT_HEADERDATA:
1513    /*
1514     * Custom pointer to pass the header write callback function
1515     */
1516    data->set.writeheader = (void *)va_arg(param, void *);
1517    break;
1518  case CURLOPT_ERRORBUFFER:
1519    /*
1520     * Error buffer provided by the caller to get the human readable
1521     * error string in.
1522     */
1523    data->set.errorbuffer = va_arg(param, char *);
1524    break;
1525  case CURLOPT_WRITEDATA:
1526    /*
1527     * FILE pointer to write to. Or possibly
1528     * used as argument to the write callback.
1529     */
1530    data->set.out = va_arg(param, void *);
1531    break;
1532  case CURLOPT_FTPPORT:
1533    /*
1534     * Use FTP PORT, this also specifies which IP address to use
1535     */
1536    result = setstropt(&data->set.str[STRING_FTPPORT],
1537                       va_arg(param, char *));
1538    data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE;
1539    break;
1540
1541  case CURLOPT_FTP_USE_EPRT:
1542    data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE;
1543    break;
1544
1545  case CURLOPT_FTP_USE_EPSV:
1546    data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE;
1547    break;
1548
1549  case CURLOPT_FTP_USE_PRET:
1550    data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE;
1551    break;
1552
1553  case CURLOPT_FTP_SSL_CCC:
1554    data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1555    break;
1556
1557  case CURLOPT_FTP_SKIP_PASV_IP:
1558    /*
1559     * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1560     * bypass of the IP address in PASV responses.
1561     */
1562    data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
1563    break;
1564
1565  case CURLOPT_READDATA:
1566    /*
1567     * FILE pointer to read the file to be uploaded from. Or possibly
1568     * used as argument to the read callback.
1569     */
1570    data->set.in_set = va_arg(param, void *);
1571    break;
1572  case CURLOPT_INFILESIZE:
1573    /*
1574     * If known, this should inform curl about the file size of the
1575     * to-be-uploaded file.
1576     */
1577    data->set.filesize = va_arg(param, long);
1578    break;
1579  case CURLOPT_INFILESIZE_LARGE:
1580    /*
1581     * If known, this should inform curl about the file size of the
1582     * to-be-uploaded file.
1583     */
1584    data->set.filesize = va_arg(param, curl_off_t);
1585    break;
1586  case CURLOPT_LOW_SPEED_LIMIT:
1587    /*
1588     * The low speed limit that if transfers are below this for
1589     * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1590     */
1591    data->set.low_speed_limit=va_arg(param, long);
1592    break;
1593  case CURLOPT_MAX_SEND_SPEED_LARGE:
1594    /*
1595     * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1596     * bytes per second the transfer is throttled..
1597     */
1598    data->set.max_send_speed=va_arg(param, curl_off_t);
1599    break;
1600  case CURLOPT_MAX_RECV_SPEED_LARGE:
1601    /*
1602     * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1603     * second the transfer is throttled..
1604     */
1605    data->set.max_recv_speed=va_arg(param, curl_off_t);
1606    break;
1607  case CURLOPT_LOW_SPEED_TIME:
1608    /*
1609     * The low speed time that if transfers are below the set
1610     * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1611     */
1612    data->set.low_speed_time=va_arg(param, long);
1613    break;
1614  case CURLOPT_URL:
1615    /*
1616     * The URL to fetch.
1617     */
1618    if(data->change.url_alloc) {
1619      /* the already set URL is allocated, free it first! */
1620      Curl_safefree(data->change.url);
1621      data->change.url_alloc = FALSE;
1622    }
1623    result = setstropt(&data->set.str[STRING_SET_URL],
1624                       va_arg(param, char *));
1625    data->change.url = data->set.str[STRING_SET_URL];
1626    break;
1627  case CURLOPT_PORT:
1628    /*
1629     * The port number to use when getting the URL
1630     */
1631    data->set.use_port = va_arg(param, long);
1632    break;
1633  case CURLOPT_TIMEOUT:
1634    /*
1635     * The maximum time you allow curl to use for a single transfer
1636     * operation.
1637     */
1638    data->set.timeout = va_arg(param, long) * 1000L;
1639    break;
1640
1641  case CURLOPT_TIMEOUT_MS:
1642    data->set.timeout = va_arg(param, long);
1643    break;
1644
1645  case CURLOPT_CONNECTTIMEOUT:
1646    /*
1647     * The maximum time you allow curl to use to connect.
1648     */
1649    data->set.connecttimeout = va_arg(param, long) * 1000L;
1650    break;
1651
1652  case CURLOPT_CONNECTTIMEOUT_MS:
1653    data->set.connecttimeout = va_arg(param, long);
1654    break;
1655
1656  case CURLOPT_ACCEPTTIMEOUT_MS:
1657    /*
1658     * The maximum time you allow curl to wait for server connect
1659     */
1660    data->set.accepttimeout = va_arg(param, long);
1661    break;
1662
1663  case CURLOPT_USERPWD:
1664    /*
1665     * user:password to use in the operation
1666     */
1667    result = setstropt_userpwd(va_arg(param, char *),
1668                               &data->set.str[STRING_USERNAME],
1669                               &data->set.str[STRING_PASSWORD]);
1670    break;
1671
1672  case CURLOPT_USERNAME:
1673    /*
1674     * authentication user name to use in the operation
1675     */
1676    result = setstropt(&data->set.str[STRING_USERNAME],
1677                       va_arg(param, char *));
1678    break;
1679
1680  case CURLOPT_PASSWORD:
1681    /*
1682     * authentication password to use in the operation
1683     */
1684    result = setstropt(&data->set.str[STRING_PASSWORD],
1685                       va_arg(param, char *));
1686    break;
1687
1688  case CURLOPT_LOGIN_OPTIONS:
1689    /*
1690     * authentication options to use in the operation
1691     */
1692    result = setstropt(&data->set.str[STRING_OPTIONS],
1693                       va_arg(param, char *));
1694    break;
1695
1696  case CURLOPT_XOAUTH2_BEARER:
1697    /*
1698     * OAuth 2.0 bearer token to use in the operation
1699     */
1700    result = setstropt(&data->set.str[STRING_BEARER],
1701                       va_arg(param, char *));
1702    break;
1703
1704  case CURLOPT_POSTQUOTE:
1705    /*
1706     * List of RAW FTP commands to use after a transfer
1707     */
1708    data->set.postquote = va_arg(param, struct curl_slist *);
1709    break;
1710  case CURLOPT_PREQUOTE:
1711    /*
1712     * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1713     */
1714    data->set.prequote = va_arg(param, struct curl_slist *);
1715    break;
1716  case CURLOPT_QUOTE:
1717    /*
1718     * List of RAW FTP commands to use before a transfer
1719     */
1720    data->set.quote = va_arg(param, struct curl_slist *);
1721    break;
1722  case CURLOPT_RESOLVE:
1723    /*
1724     * List of NAME:[address] names to populate the DNS cache with
1725     * Prefix the NAME with dash (-) to _remove_ the name from the cache.
1726     *
1727     * Names added with this API will remain in the cache until explicitly
1728     * removed or the handle is cleaned up.
1729     *
1730     * This API can remove any name from the DNS cache, but only entries
1731     * that aren't actually in use right now will be pruned immediately.
1732     */
1733    data->set.resolve = va_arg(param, struct curl_slist *);
1734    data->change.resolve = data->set.resolve;
1735    break;
1736  case CURLOPT_PROGRESSFUNCTION:
1737    /*
1738     * Progress callback function
1739     */
1740    data->set.fprogress = va_arg(param, curl_progress_callback);
1741    if(data->set.fprogress)
1742      data->progress.callback = TRUE; /* no longer internal */
1743    else
1744      data->progress.callback = FALSE; /* NULL enforces internal */
1745    break;
1746
1747  case CURLOPT_XFERINFOFUNCTION:
1748    /*
1749     * Transfer info callback function
1750     */
1751    data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
1752    if(data->set.fxferinfo)
1753      data->progress.callback = TRUE; /* no longer internal */
1754    else
1755      data->progress.callback = FALSE; /* NULL enforces internal */
1756
1757    break;
1758
1759  case CURLOPT_PROGRESSDATA:
1760    /*
1761     * Custom client data to pass to the progress callback
1762     */
1763    data->set.progress_client = va_arg(param, void *);
1764    break;
1765
1766#ifndef CURL_DISABLE_PROXY
1767  case CURLOPT_PROXYUSERPWD:
1768    /*
1769     * user:password needed to use the proxy
1770     */
1771    result = setstropt_userpwd(va_arg(param, char *),
1772                               &data->set.str[STRING_PROXYUSERNAME],
1773                               &data->set.str[STRING_PROXYPASSWORD]);
1774    break;
1775  case CURLOPT_PROXYUSERNAME:
1776    /*
1777     * authentication user name to use in the operation
1778     */
1779    result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1780                       va_arg(param, char *));
1781    break;
1782  case CURLOPT_PROXYPASSWORD:
1783    /*
1784     * authentication password to use in the operation
1785     */
1786    result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1787                       va_arg(param, char *));
1788    break;
1789  case CURLOPT_NOPROXY:
1790    /*
1791     * proxy exception list
1792     */
1793    result = setstropt(&data->set.str[STRING_NOPROXY],
1794                       va_arg(param, char *));
1795    break;
1796#endif
1797
1798  case CURLOPT_RANGE:
1799    /*
1800     * What range of the file you want to transfer
1801     */
1802    result = setstropt(&data->set.str[STRING_SET_RANGE],
1803                       va_arg(param, char *));
1804    break;
1805  case CURLOPT_RESUME_FROM:
1806    /*
1807     * Resume transfer at the give file position
1808     */
1809    data->set.set_resume_from = va_arg(param, long);
1810    break;
1811  case CURLOPT_RESUME_FROM_LARGE:
1812    /*
1813     * Resume transfer at the give file position
1814     */
1815    data->set.set_resume_from = va_arg(param, curl_off_t);
1816    break;
1817  case CURLOPT_DEBUGFUNCTION:
1818    /*
1819     * stderr write callback.
1820     */
1821    data->set.fdebug = va_arg(param, curl_debug_callback);
1822    /*
1823     * if the callback provided is NULL, it'll use the default callback
1824     */
1825    break;
1826  case CURLOPT_DEBUGDATA:
1827    /*
1828     * Set to a void * that should receive all error writes. This
1829     * defaults to CURLOPT_STDERR for normal operations.
1830     */
1831    data->set.debugdata = va_arg(param, void *);
1832    break;
1833  case CURLOPT_STDERR:
1834    /*
1835     * Set to a FILE * that should receive all error writes. This
1836     * defaults to stderr for normal operations.
1837     */
1838    data->set.err = va_arg(param, FILE *);
1839    if(!data->set.err)
1840      data->set.err = stderr;
1841    break;
1842  case CURLOPT_HEADERFUNCTION:
1843    /*
1844     * Set header write callback
1845     */
1846    data->set.fwrite_header = va_arg(param, curl_write_callback);
1847    break;
1848  case CURLOPT_WRITEFUNCTION:
1849    /*
1850     * Set data write callback
1851     */
1852    data->set.fwrite_func = va_arg(param, curl_write_callback);
1853    if(!data->set.fwrite_func) {
1854      data->set.is_fwrite_set = 0;
1855      /* When set to NULL, reset to our internal default function */
1856      data->set.fwrite_func = (curl_write_callback)fwrite;
1857    }
1858    else
1859      data->set.is_fwrite_set = 1;
1860    break;
1861  case CURLOPT_READFUNCTION:
1862    /*
1863     * Read data callback
1864     */
1865    data->set.fread_func_set = va_arg(param, curl_read_callback);
1866    if(!data->set.fread_func_set) {
1867      data->set.is_fread_set = 0;
1868      /* When set to NULL, reset to our internal default function */
1869      data->set.fread_func_set = (curl_read_callback)fread;
1870    }
1871    else
1872      data->set.is_fread_set = 1;
1873    break;
1874  case CURLOPT_SEEKFUNCTION:
1875    /*
1876     * Seek callback. Might be NULL.
1877     */
1878    data->set.seek_func = va_arg(param, curl_seek_callback);
1879    break;
1880  case CURLOPT_SEEKDATA:
1881    /*
1882     * Seek control callback. Might be NULL.
1883     */
1884    data->set.seek_client = va_arg(param, void *);
1885    break;
1886  case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1887    /*
1888     * "Convert from network encoding" callback
1889     */
1890    data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1891    break;
1892  case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1893    /*
1894     * "Convert to network encoding" callback
1895     */
1896    data->set.convtonetwork = va_arg(param, curl_conv_callback);
1897    break;
1898  case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1899    /*
1900     * "Convert from UTF-8 encoding" callback
1901     */
1902    data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1903    break;
1904  case CURLOPT_IOCTLFUNCTION:
1905    /*
1906     * I/O control callback. Might be NULL.
1907     */
1908    data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1909    break;
1910  case CURLOPT_IOCTLDATA:
1911    /*
1912     * I/O control data pointer. Might be NULL.
1913     */
1914    data->set.ioctl_client = va_arg(param, void *);
1915    break;
1916  case CURLOPT_SSLCERT:
1917    /*
1918     * String that holds file name of the SSL certificate to use
1919     */
1920    result = setstropt(&data->set.str[STRING_CERT],
1921                       va_arg(param, char *));
1922    break;
1923  case CURLOPT_SSLCERTTYPE:
1924    /*
1925     * String that holds file type of the SSL certificate to use
1926     */
1927    result = setstropt(&data->set.str[STRING_CERT_TYPE],
1928                       va_arg(param, char *));
1929    break;
1930  case CURLOPT_SSLKEY:
1931    /*
1932     * String that holds file name of the SSL key to use
1933     */
1934    result = setstropt(&data->set.str[STRING_KEY],
1935                       va_arg(param, char *));
1936    break;
1937  case CURLOPT_SSLKEYTYPE:
1938    /*
1939     * String that holds file type of the SSL key to use
1940     */
1941    result = setstropt(&data->set.str[STRING_KEY_TYPE],
1942                       va_arg(param, char *));
1943    break;
1944  case CURLOPT_KEYPASSWD:
1945    /*
1946     * String that holds the SSL or SSH private key password.
1947     */
1948    result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1949                       va_arg(param, char *));
1950    break;
1951  case CURLOPT_SSLENGINE:
1952    /*
1953     * String that holds the SSL crypto engine.
1954     */
1955    argptr = va_arg(param, char *);
1956    if(argptr && argptr[0])
1957      result = Curl_ssl_set_engine(data, argptr);
1958    break;
1959
1960  case CURLOPT_SSLENGINE_DEFAULT:
1961    /*
1962     * flag to set engine as default.
1963     */
1964    result = Curl_ssl_set_engine_default(data);
1965    break;
1966  case CURLOPT_CRLF:
1967    /*
1968     * Kludgy option to enable CRLF conversions. Subject for removal.
1969     */
1970    data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
1971    break;
1972
1973  case CURLOPT_INTERFACE:
1974    /*
1975     * Set what interface or address/hostname to bind the socket to when
1976     * performing an operation and thus what from-IP your connection will use.
1977     */
1978    result = setstropt(&data->set.str[STRING_DEVICE],
1979                       va_arg(param, char *));
1980    break;
1981  case CURLOPT_LOCALPORT:
1982    /*
1983     * Set what local port to bind the socket to when performing an operation.
1984     */
1985    data->set.localport = curlx_sltous(va_arg(param, long));
1986    break;
1987  case CURLOPT_LOCALPORTRANGE:
1988    /*
1989     * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1990     */
1991    data->set.localportrange = curlx_sltosi(va_arg(param, long));
1992    break;
1993  case CURLOPT_KRBLEVEL:
1994    /*
1995     * A string that defines the kerberos security level.
1996     */
1997    result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1998                       va_arg(param, char *));
1999    data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
2000    break;
2001  case CURLOPT_GSSAPI_DELEGATION:
2002    /*
2003     * GSS-API credential delegation
2004     */
2005    data->set.gssapi_delegation = va_arg(param, long);
2006    break;
2007  case CURLOPT_SSL_VERIFYPEER:
2008    /*
2009     * Enable peer SSL verifying.
2010     */
2011    data->set.ssl.verifypeer = (0 != va_arg(param, long)) ? TRUE : FALSE;
2012    break;
2013  case CURLOPT_SSL_VERIFYHOST:
2014    /*
2015     * Enable verification of the host name in the peer certificate
2016     */
2017    arg = va_arg(param, long);
2018
2019    /* Obviously people are not reading documentation and too many thought
2020       this argument took a boolean when it wasn't and misused it. We thus ban
2021       1 as a sensible input and we warn about its use. Then we only have the
2022       2 action internally stored as TRUE. */
2023
2024    if(1 == arg) {
2025      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
2026      return CURLE_BAD_FUNCTION_ARGUMENT;
2027    }
2028
2029    data->set.ssl.verifyhost = (0 != arg) ? TRUE : FALSE;
2030    break;
2031  case CURLOPT_SSL_VERIFYSTATUS:
2032    /*
2033     * Enable certificate status verifying.
2034     */
2035    if(!Curl_ssl_cert_status_request()) {
2036      result = CURLE_NOT_BUILT_IN;
2037      break;
2038    }
2039
2040    data->set.ssl.verifystatus = (0 != va_arg(param, long)) ? TRUE : FALSE;
2041    break;
2042  case CURLOPT_SSL_CTX_FUNCTION:
2043#ifdef have_curlssl_ssl_ctx
2044    /*
2045     * Set a SSL_CTX callback
2046     */
2047    data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2048#else
2049    result = CURLE_NOT_BUILT_IN;
2050#endif
2051    break;
2052  case CURLOPT_SSL_CTX_DATA:
2053#ifdef have_curlssl_ssl_ctx
2054    /*
2055     * Set a SSL_CTX callback parameter pointer
2056     */
2057    data->set.ssl.fsslctxp = va_arg(param, void *);
2058#else
2059    result = CURLE_NOT_BUILT_IN;
2060#endif
2061    break;
2062  case CURLOPT_SSL_FALSESTART:
2063    /*
2064     * Enable TLS false start.
2065     */
2066    if(!Curl_ssl_false_start()) {
2067      result = CURLE_NOT_BUILT_IN;
2068      break;
2069    }
2070
2071    data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE;
2072    break;
2073  case CURLOPT_CERTINFO:
2074#ifdef have_curlssl_certinfo
2075    data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE;
2076#else
2077    result = CURLE_NOT_BUILT_IN;
2078#endif
2079    break;
2080  case CURLOPT_PINNEDPUBLICKEY:
2081#ifdef have_curlssl_pinnedpubkey /* only by supported backends */
2082    /*
2083     * Set pinned public key for SSL connection.
2084     * Specify file name of the public key in DER format.
2085     */
2086    result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
2087                       va_arg(param, char *));
2088#else
2089    result = CURLE_NOT_BUILT_IN;
2090#endif
2091    break;
2092  case CURLOPT_CAINFO:
2093    /*
2094     * Set CA info for SSL connection. Specify file name of the CA certificate
2095     */
2096    result = setstropt(&data->set.str[STRING_SSL_CAFILE],
2097                       va_arg(param, char *));
2098    break;
2099  case CURLOPT_CAPATH:
2100#ifdef have_curlssl_ca_path /* not supported by all backends */
2101    /*
2102     * Set CA path info for SSL connection. Specify directory name of the CA
2103     * certificates which have been prepared using openssl c_rehash utility.
2104     */
2105    /* This does not work on windows. */
2106    result = setstropt(&data->set.str[STRING_SSL_CAPATH],
2107                       va_arg(param, char *));
2108#else
2109    result = CURLE_NOT_BUILT_IN;
2110#endif
2111    break;
2112  case CURLOPT_CRLFILE:
2113    /*
2114     * Set CRL file info for SSL connection. Specify file name of the CRL
2115     * to check certificates revocation
2116     */
2117    result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
2118                       va_arg(param, char *));
2119    break;
2120  case CURLOPT_ISSUERCERT:
2121    /*
2122     * Set Issuer certificate file
2123     * to check certificates issuer
2124     */
2125    result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
2126                       va_arg(param, char *));
2127    break;
2128  case CURLOPT_TELNETOPTIONS:
2129    /*
2130     * Set a linked list of telnet options
2131     */
2132    data->set.telnet_options = va_arg(param, struct curl_slist *);
2133    break;
2134
2135  case CURLOPT_BUFFERSIZE:
2136    /*
2137     * The application kindly asks for a differently sized receive buffer.
2138     * If it seems reasonable, we'll use it.
2139     */
2140    data->set.buffer_size = va_arg(param, long);
2141
2142    if((data->set.buffer_size> (BUFSIZE -1)) ||
2143       (data->set.buffer_size < 1))
2144      data->set.buffer_size = 0; /* huge internal default */
2145
2146    break;
2147
2148  case CURLOPT_NOSIGNAL:
2149    /*
2150     * The application asks not to set any signal() or alarm() handlers,
2151     * even when using a timeout.
2152     */
2153    data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE;
2154    break;
2155
2156  case CURLOPT_SHARE:
2157  {
2158    struct Curl_share *set;
2159    set = va_arg(param, struct Curl_share *);
2160
2161    /* disconnect from old share, if any */
2162    if(data->share) {
2163      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2164
2165      if(data->dns.hostcachetype == HCACHE_SHARED) {
2166        data->dns.hostcache = NULL;
2167        data->dns.hostcachetype = HCACHE_NONE;
2168      }
2169
2170#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2171      if(data->share->cookies == data->cookies)
2172        data->cookies = NULL;
2173#endif
2174
2175      if(data->share->sslsession == data->state.session)
2176        data->state.session = NULL;
2177
2178      data->share->dirty--;
2179
2180      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2181      data->share = NULL;
2182    }
2183
2184    /* use new share if it set */
2185    data->share = set;
2186    if(data->share) {
2187
2188      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2189
2190      data->share->dirty++;
2191
2192      if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
2193        /* use shared host cache */
2194        data->dns.hostcache = &data->share->hostcache;
2195        data->dns.hostcachetype = HCACHE_SHARED;
2196      }
2197#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2198      if(data->share->cookies) {
2199        /* use shared cookie list, first free own one if any */
2200        Curl_cookie_cleanup(data->cookies);
2201        /* enable cookies since we now use a share that uses cookies! */
2202        data->cookies = data->share->cookies;
2203      }
2204#endif   /* CURL_DISABLE_HTTP */
2205      if(data->share->sslsession) {
2206        data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
2207        data->state.session = data->share->sslsession;
2208      }
2209      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2210
2211    }
2212    /* check for host cache not needed,
2213     * it will be done by curl_easy_perform */
2214  }
2215  break;
2216
2217  case CURLOPT_PRIVATE:
2218    /*
2219     * Set private data pointer.
2220     */
2221    data->set.private_data = va_arg(param, void *);
2222    break;
2223
2224  case CURLOPT_MAXFILESIZE:
2225    /*
2226     * Set the maximum size of a file to download.
2227     */
2228    data->set.max_filesize = va_arg(param, long);
2229    break;
2230
2231#ifdef USE_SSL
2232  case CURLOPT_USE_SSL:
2233    /*
2234     * Make transfers attempt to use SSL/TLS.
2235     */
2236    data->set.use_ssl = (curl_usessl)va_arg(param, long);
2237    break;
2238
2239  case CURLOPT_SSL_OPTIONS:
2240    arg = va_arg(param, long);
2241    data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
2242    data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
2243    break;
2244
2245#endif
2246  case CURLOPT_FTPSSLAUTH:
2247    /*
2248     * Set a specific auth for FTP-SSL transfers.
2249     */
2250    data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2251    break;
2252
2253  case CURLOPT_IPRESOLVE:
2254    data->set.ipver = va_arg(param, long);
2255    break;
2256
2257  case CURLOPT_MAXFILESIZE_LARGE:
2258    /*
2259     * Set the maximum size of a file to download.
2260     */
2261    data->set.max_filesize = va_arg(param, curl_off_t);
2262    break;
2263
2264  case CURLOPT_TCP_NODELAY:
2265    /*
2266     * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2267     * algorithm
2268     */
2269    data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
2270    break;
2271
2272  case CURLOPT_FTP_ACCOUNT:
2273    result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2274                       va_arg(param, char *));
2275    break;
2276
2277  case CURLOPT_IGNORE_CONTENT_LENGTH:
2278    data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
2279    break;
2280
2281  case CURLOPT_CONNECT_ONLY:
2282    /*
2283     * No data transfer, set up connection and let application use the socket
2284     */
2285    data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
2286    break;
2287
2288  case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2289    result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2290                       va_arg(param, char *));
2291    break;
2292
2293  case CURLOPT_SOCKOPTFUNCTION:
2294    /*
2295     * socket callback function: called after socket() but before connect()
2296     */
2297    data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2298    break;
2299
2300  case CURLOPT_SOCKOPTDATA:
2301    /*
2302     * socket callback data pointer. Might be NULL.
2303     */
2304    data->set.sockopt_client = va_arg(param, void *);
2305    break;
2306
2307  case CURLOPT_OPENSOCKETFUNCTION:
2308    /*
2309     * open/create socket callback function: called instead of socket(),
2310     * before connect()
2311     */
2312    data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2313    break;
2314
2315  case CURLOPT_OPENSOCKETDATA:
2316    /*
2317     * socket callback data pointer. Might be NULL.
2318     */
2319    data->set.opensocket_client = va_arg(param, void *);
2320    break;
2321
2322  case CURLOPT_CLOSESOCKETFUNCTION:
2323    /*
2324     * close socket callback function: called instead of close()
2325     * when shutting down a connection
2326     */
2327    data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
2328    break;
2329
2330  case CURLOPT_CLOSESOCKETDATA:
2331    /*
2332     * socket callback data pointer. Might be NULL.
2333     */
2334    data->set.closesocket_client = va_arg(param, void *);
2335    break;
2336
2337  case CURLOPT_SSL_SESSIONID_CACHE:
2338    data->set.ssl.sessionid = (0 != va_arg(param, long)) ? TRUE : FALSE;
2339    break;
2340
2341#ifdef USE_LIBSSH2
2342    /* we only include SSH options if explicitly built to support SSH */
2343  case CURLOPT_SSH_AUTH_TYPES:
2344    data->set.ssh_auth_types = va_arg(param, long);
2345    break;
2346
2347  case CURLOPT_SSH_PUBLIC_KEYFILE:
2348    /*
2349     * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2350     */
2351    result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2352                       va_arg(param, char *));
2353    break;
2354
2355  case CURLOPT_SSH_PRIVATE_KEYFILE:
2356    /*
2357     * Use this file instead of the $HOME/.ssh/id_dsa file
2358     */
2359    result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2360                       va_arg(param, char *));
2361    break;
2362  case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2363    /*
2364     * Option to allow for the MD5 of the host public key to be checked
2365     * for validation purposes.
2366     */
2367    result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2368                       va_arg(param, char *));
2369    break;
2370#ifdef HAVE_LIBSSH2_KNOWNHOST_API
2371  case CURLOPT_SSH_KNOWNHOSTS:
2372    /*
2373     * Store the file name to read known hosts from.
2374     */
2375    result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
2376                       va_arg(param, char *));
2377    break;
2378
2379  case CURLOPT_SSH_KEYFUNCTION:
2380    /* setting to NULL is fine since the ssh.c functions themselves will
2381       then rever to use the internal default */
2382    data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2383    break;
2384
2385  case CURLOPT_SSH_KEYDATA:
2386    /*
2387     * Custom client data to pass to the SSH keyfunc callback
2388     */
2389    data->set.ssh_keyfunc_userp = va_arg(param, void *);
2390    break;
2391#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
2392
2393#endif /* USE_LIBSSH2 */
2394
2395  case CURLOPT_HTTP_TRANSFER_DECODING:
2396    /*
2397     * disable libcurl transfer encoding is used
2398     */
2399    data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2400    break;
2401
2402  case CURLOPT_HTTP_CONTENT_DECODING:
2403    /*
2404     * raw data passed to the application when content encoding is used
2405     */
2406    data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
2407    break;
2408
2409  case CURLOPT_NEW_FILE_PERMS:
2410    /*
2411     * Uses these permissions instead of 0644
2412     */
2413    data->set.new_file_perms = va_arg(param, long);
2414    break;
2415
2416  case CURLOPT_NEW_DIRECTORY_PERMS:
2417    /*
2418     * Uses these permissions instead of 0755
2419     */
2420    data->set.new_directory_perms = va_arg(param, long);
2421    break;
2422
2423  case CURLOPT_ADDRESS_SCOPE:
2424    /*
2425     * We always get longs when passed plain numericals, but for this value we
2426     * know that an unsigned int will always hold the value so we blindly
2427     * typecast to this type
2428     */
2429    data->set.scope_id = curlx_sltoui(va_arg(param, long));
2430    break;
2431
2432  case CURLOPT_PROTOCOLS:
2433    /* set the bitmask for the protocols that are allowed to be used for the
2434       transfer, which thus helps the app which takes URLs from users or other
2435       external inputs and want to restrict what protocol(s) to deal
2436       with. Defaults to CURLPROTO_ALL. */
2437    data->set.allowed_protocols = va_arg(param, long);
2438    break;
2439
2440  case CURLOPT_REDIR_PROTOCOLS:
2441    /* set the bitmask for the protocols that libcurl is allowed to follow to,
2442       as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2443       to be set in both bitmasks to be allowed to get redirected to. Defaults
2444       to all protocols except FILE and SCP. */
2445    data->set.redir_protocols = va_arg(param, long);
2446    break;
2447
2448  case CURLOPT_DEFAULT_PROTOCOL:
2449    /* Set the protocol to use when the URL doesn't include any protocol */
2450    result = setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
2451                       va_arg(param, char *));
2452    break;
2453
2454  case CURLOPT_MAIL_FROM:
2455    /* Set the SMTP mail originator */
2456    result = setstropt(&data->set.str[STRING_MAIL_FROM],
2457                       va_arg(param, char *));
2458    break;
2459
2460  case CURLOPT_MAIL_AUTH:
2461    /* Set the SMTP auth originator */
2462    result = setstropt(&data->set.str[STRING_MAIL_AUTH],
2463                       va_arg(param, char *));
2464    break;
2465
2466  case CURLOPT_MAIL_RCPT:
2467    /* Set the list of mail recipients */
2468    data->set.mail_rcpt = va_arg(param, struct curl_slist *);
2469    break;
2470
2471  case CURLOPT_SASL_IR:
2472    /* Enable/disable SASL initial response */
2473    data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
2474    break;
2475
2476  case CURLOPT_RTSP_REQUEST:
2477    {
2478      /*
2479       * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
2480       * Would this be better if the RTSPREQ_* were just moved into here?
2481       */
2482      long curl_rtspreq = va_arg(param, long);
2483      Curl_RtspReq rtspreq = RTSPREQ_NONE;
2484      switch(curl_rtspreq) {
2485        case CURL_RTSPREQ_OPTIONS:
2486          rtspreq = RTSPREQ_OPTIONS;
2487          break;
2488
2489        case CURL_RTSPREQ_DESCRIBE:
2490          rtspreq = RTSPREQ_DESCRIBE;
2491          break;
2492
2493        case CURL_RTSPREQ_ANNOUNCE:
2494          rtspreq = RTSPREQ_ANNOUNCE;
2495          break;
2496
2497        case CURL_RTSPREQ_SETUP:
2498          rtspreq = RTSPREQ_SETUP;
2499          break;
2500
2501        case CURL_RTSPREQ_PLAY:
2502          rtspreq = RTSPREQ_PLAY;
2503          break;
2504
2505        case CURL_RTSPREQ_PAUSE:
2506          rtspreq = RTSPREQ_PAUSE;
2507          break;
2508
2509        case CURL_RTSPREQ_TEARDOWN:
2510          rtspreq = RTSPREQ_TEARDOWN;
2511          break;
2512
2513        case CURL_RTSPREQ_GET_PARAMETER:
2514          rtspreq = RTSPREQ_GET_PARAMETER;
2515          break;
2516
2517        case CURL_RTSPREQ_SET_PARAMETER:
2518          rtspreq = RTSPREQ_SET_PARAMETER;
2519          break;
2520
2521        case CURL_RTSPREQ_RECORD:
2522          rtspreq = RTSPREQ_RECORD;
2523          break;
2524
2525        case CURL_RTSPREQ_RECEIVE:
2526          rtspreq = RTSPREQ_RECEIVE;
2527          break;
2528        default:
2529          rtspreq = RTSPREQ_NONE;
2530      }
2531
2532      data->set.rtspreq = rtspreq;
2533    break;
2534    }
2535
2536
2537  case CURLOPT_RTSP_SESSION_ID:
2538    /*
2539     * Set the RTSP Session ID manually. Useful if the application is
2540     * resuming a previously established RTSP session
2541     */
2542    result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
2543                       va_arg(param, char *));
2544    break;
2545
2546  case CURLOPT_RTSP_STREAM_URI:
2547    /*
2548     * Set the Stream URI for the RTSP request. Unless the request is
2549     * for generic server options, the application will need to set this.
2550     */
2551    result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
2552                       va_arg(param, char *));
2553    break;
2554
2555  case CURLOPT_RTSP_TRANSPORT:
2556    /*
2557     * The content of the Transport: header for the RTSP request
2558     */
2559    result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
2560                       va_arg(param, char *));
2561    break;
2562
2563  case CURLOPT_RTSP_CLIENT_CSEQ:
2564    /*
2565     * Set the CSEQ number to issue for the next RTSP request. Useful if the
2566     * application is resuming a previously broken connection. The CSEQ
2567     * will increment from this new number henceforth.
2568     */
2569    data->state.rtsp_next_client_CSeq = va_arg(param, long);
2570    break;
2571
2572  case CURLOPT_RTSP_SERVER_CSEQ:
2573    /* Same as the above, but for server-initiated requests */
2574    data->state.rtsp_next_client_CSeq = va_arg(param, long);
2575    break;
2576
2577  case CURLOPT_INTERLEAVEDATA:
2578    data->set.rtp_out = va_arg(param, void *);
2579    break;
2580  case CURLOPT_INTERLEAVEFUNCTION:
2581    /* Set the user defined RTP write function */
2582    data->set.fwrite_rtp = va_arg(param, curl_write_callback);
2583    break;
2584
2585  case CURLOPT_WILDCARDMATCH:
2586    data->set.wildcardmatch = (0 != va_arg(param, long)) ? TRUE : FALSE;
2587    break;
2588  case CURLOPT_CHUNK_BGN_FUNCTION:
2589    data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2590    break;
2591  case CURLOPT_CHUNK_END_FUNCTION:
2592    data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
2593    break;
2594  case CURLOPT_FNMATCH_FUNCTION:
2595    data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
2596    break;
2597  case CURLOPT_CHUNK_DATA:
2598    data->wildcard.customptr = va_arg(param, void *);
2599    break;
2600  case CURLOPT_FNMATCH_DATA:
2601    data->set.fnmatch_data = va_arg(param, void *);
2602    break;
2603#ifdef USE_TLS_SRP
2604  case CURLOPT_TLSAUTH_USERNAME:
2605    result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
2606                       va_arg(param, char *));
2607    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2608      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2609    break;
2610  case CURLOPT_TLSAUTH_PASSWORD:
2611    result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
2612                       va_arg(param, char *));
2613    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
2614      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
2615    break;
2616  case CURLOPT_TLSAUTH_TYPE:
2617    if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
2618      data->set.ssl.authtype = CURL_TLSAUTH_SRP;
2619    else
2620      data->set.ssl.authtype = CURL_TLSAUTH_NONE;
2621    break;
2622#endif
2623  case CURLOPT_DNS_SERVERS:
2624    result = Curl_set_dns_servers(data, va_arg(param, char *));
2625    break;
2626  case CURLOPT_DNS_INTERFACE:
2627    result = Curl_set_dns_interface(data, va_arg(param, char *));
2628    break;
2629  case CURLOPT_DNS_LOCAL_IP4:
2630    result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
2631    break;
2632  case CURLOPT_DNS_LOCAL_IP6:
2633    result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
2634    break;
2635
2636  case CURLOPT_TCP_KEEPALIVE:
2637    data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
2638    break;
2639  case CURLOPT_TCP_KEEPIDLE:
2640    data->set.tcp_keepidle = va_arg(param, long);
2641    break;
2642  case CURLOPT_TCP_KEEPINTVL:
2643    data->set.tcp_keepintvl = va_arg(param, long);
2644    break;
2645  case CURLOPT_TCP_FASTOPEN:
2646#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN)
2647    data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
2648#else
2649    result = CURLE_NOT_BUILT_IN;
2650#endif
2651    break;
2652  case CURLOPT_SSL_ENABLE_NPN:
2653    data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2654    break;
2655  case CURLOPT_SSL_ENABLE_ALPN:
2656    data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
2657    break;
2658
2659#ifdef USE_UNIX_SOCKETS
2660  case CURLOPT_UNIX_SOCKET_PATH:
2661    result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
2662                       va_arg(param, char *));
2663    break;
2664#endif
2665
2666  case CURLOPT_PATH_AS_IS:
2667    data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE;
2668    break;
2669  case CURLOPT_PIPEWAIT:
2670    data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE;
2671    break;
2672  case CURLOPT_STREAM_WEIGHT:
2673#ifndef USE_NGHTTP2
2674    return CURLE_NOT_BUILT_IN;
2675#else
2676    arg = va_arg(param, long);
2677    if((arg>=1) && (arg <= 256))
2678      data->set.stream_weight = (int)arg;
2679    break;
2680#endif
2681  case CURLOPT_STREAM_DEPENDS:
2682  case CURLOPT_STREAM_DEPENDS_E:
2683  {
2684#ifndef USE_NGHTTP2
2685    return CURLE_NOT_BUILT_IN;
2686#else
2687    struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
2688    if(dep && GOOD_EASY_HANDLE(dep)) {
2689      data->set.stream_depends_on = dep;
2690      data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E);
2691    }
2692    break;
2693#endif
2694  }
2695  case CURLOPT_CONNECT_TO:
2696    data->set.connect_to = va_arg(param, struct curl_slist *);
2697    break;
2698  default:
2699    /* unknown tag and its companion, just ignore: */
2700    result = CURLE_UNKNOWN_OPTION;
2701    break;
2702  }
2703
2704  return result;
2705}
2706
2707#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
2708static void conn_reset_postponed_data(struct connectdata *conn, int num)
2709{
2710  struct postponed_data * const psnd = &(conn->postponed[num]);
2711  if(psnd->buffer) {
2712    DEBUGASSERT(psnd->allocated_size > 0);
2713    DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
2714    DEBUGASSERT(psnd->recv_size ?
2715                (psnd->recv_processed < psnd->recv_size) :
2716                (psnd->recv_processed == 0));
2717    DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD);
2718    free(psnd->buffer);
2719    psnd->buffer = NULL;
2720    psnd->allocated_size = 0;
2721    psnd->recv_size = 0;
2722    psnd->recv_processed = 0;
2723#ifdef DEBUGBUILD
2724    psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */
2725#endif /* DEBUGBUILD */
2726  }
2727  else {
2728    DEBUGASSERT (psnd->allocated_size == 0);
2729    DEBUGASSERT (psnd->recv_size == 0);
2730    DEBUGASSERT (psnd->recv_processed == 0);
2731    DEBUGASSERT (psnd->bindsock == CURL_SOCKET_BAD);
2732  }
2733}
2734
2735static void conn_reset_all_postponed_data(struct connectdata *conn)
2736{
2737  conn_reset_postponed_data(conn, 0);
2738  conn_reset_postponed_data(conn, 1);
2739}
2740#else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
2741/* Use "do-nothing" macros instead of functions when workaround not used */
2742#define conn_reset_postponed_data(c,n) do {} WHILE_FALSE
2743#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
2744#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
2745
2746static void conn_free(struct connectdata *conn)
2747{
2748  if(!conn)
2749    return;
2750
2751  /* possible left-overs from the async name resolvers */
2752  Curl_resolver_cancel(conn);
2753
2754  /* close the SSL stuff before we close any sockets since they will/may
2755     write to the sockets */
2756  Curl_ssl_close(conn, FIRSTSOCKET);
2757  Curl_ssl_close(conn, SECONDARYSOCKET);
2758
2759  /* close possibly still open sockets */
2760  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2761    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
2762  if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2763    Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
2764  if(CURL_SOCKET_BAD != conn->tempsock[0])
2765    Curl_closesocket(conn, conn->tempsock[0]);
2766  if(CURL_SOCKET_BAD != conn->tempsock[1])
2767    Curl_closesocket(conn, conn->tempsock[1]);
2768
2769#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
2770    defined(NTLM_WB_ENABLED)
2771  Curl_ntlm_wb_cleanup(conn);
2772#endif
2773
2774  Curl_safefree(conn->user);
2775  Curl_safefree(conn->passwd);
2776  Curl_safefree(conn->oauth_bearer);
2777  Curl_safefree(conn->options);
2778  Curl_safefree(conn->proxyuser);
2779  Curl_safefree(conn->proxypasswd);
2780  Curl_safefree(conn->allocptr.proxyuserpwd);
2781  Curl_safefree(conn->allocptr.uagent);
2782  Curl_safefree(conn->allocptr.userpwd);
2783  Curl_safefree(conn->allocptr.accept_encoding);
2784  Curl_safefree(conn->allocptr.te);
2785  Curl_safefree(conn->allocptr.rangeline);
2786  Curl_safefree(conn->allocptr.ref);
2787  Curl_safefree(conn->allocptr.host);
2788  Curl_safefree(conn->allocptr.cookiehost);
2789  Curl_safefree(conn->allocptr.rtsp_transport);
2790  Curl_safefree(conn->trailer);
2791  Curl_safefree(conn->host.rawalloc); /* host name buffer */
2792  Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
2793  Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2794  Curl_safefree(conn->master_buffer);
2795
2796  conn_reset_all_postponed_data(conn);
2797
2798  Curl_llist_destroy(conn->send_pipe, NULL);
2799  Curl_llist_destroy(conn->recv_pipe, NULL);
2800
2801  conn->send_pipe = NULL;
2802  conn->recv_pipe = NULL;
2803
2804  Curl_safefree(conn->localdev);
2805  Curl_free_ssl_config(&conn->ssl_config);
2806
2807  free(conn); /* free all the connection oriented data */
2808}
2809
2810/*
2811 * Disconnects the given connection. Note the connection may not be the
2812 * primary connection, like when freeing room in the connection cache or
2813 * killing of a dead old connection.
2814 *
2815 * This function MUST NOT reset state in the Curl_easy struct if that
2816 * isn't strictly bound to the life-time of *this* particular connection.
2817 *
2818 */
2819
2820CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
2821{
2822  struct Curl_easy *data;
2823  if(!conn)
2824    return CURLE_OK; /* this is closed and fine already */
2825  data = conn->data;
2826
2827  if(!data) {
2828    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
2829    return CURLE_OK;
2830  }
2831
2832  if(conn->dns_entry != NULL) {
2833    Curl_resolv_unlock(data, conn->dns_entry);
2834    conn->dns_entry = NULL;
2835  }
2836
2837  Curl_hostcache_prune(data); /* kill old DNS cache entries */
2838
2839#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
2840  /* Cleanup NTLM connection-related data */
2841  Curl_http_ntlm_cleanup(conn);
2842#endif
2843
2844  if(conn->handler->disconnect)
2845    /* This is set if protocol-specific cleanups should be made */
2846    conn->handler->disconnect(conn, dead_connection);
2847
2848    /* unlink ourselves! */
2849  infof(data, "Closing connection %ld\n", conn->connection_id);
2850  Curl_conncache_remove_conn(data->state.conn_cache, conn);
2851
2852  free_fixed_hostname(&conn->host);
2853  free_fixed_hostname(&conn->conn_to_host);
2854  free_fixed_hostname(&conn->proxy);
2855
2856  Curl_ssl_close(conn, FIRSTSOCKET);
2857
2858  /* Indicate to all handles on the pipe that we're dead */
2859  if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
2860    signalPipeClose(conn->send_pipe, TRUE);
2861    signalPipeClose(conn->recv_pipe, TRUE);
2862  }
2863
2864  conn_free(conn);
2865
2866  return CURLE_OK;
2867}
2868
2869/*
2870 * This function should return TRUE if the socket is to be assumed to
2871 * be dead. Most commonly this happens when the server has closed the
2872 * connection due to inactivity.
2873 */
2874static bool SocketIsDead(curl_socket_t sock)
2875{
2876  int sval;
2877  bool ret_val = TRUE;
2878
2879  sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
2880  if(sval == 0)
2881    /* timeout */
2882    ret_val = FALSE;
2883
2884  return ret_val;
2885}
2886
2887/*
2888 * IsPipeliningPossible() returns TRUE if the options set would allow
2889 * pipelining/multiplexing and the connection is using a HTTP protocol.
2890 */
2891static bool IsPipeliningPossible(const struct Curl_easy *handle,
2892                                 const struct connectdata *conn)
2893{
2894  /* If a HTTP protocol and pipelining is enabled */
2895  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
2896
2897    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
2898       (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
2899       (handle->set.httpreq == HTTPREQ_GET ||
2900        handle->set.httpreq == HTTPREQ_HEAD))
2901      /* didn't ask for HTTP/1.0 and a GET or HEAD */
2902      return TRUE;
2903
2904    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
2905       (handle->set.httpversion >= CURL_HTTP_VERSION_2))
2906      /* allows HTTP/2 */
2907      return TRUE;
2908  }
2909  return FALSE;
2910}
2911
2912int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
2913                                  struct curl_llist *pipeline)
2914{
2915  if(pipeline) {
2916    struct curl_llist_element *curr;
2917
2918    curr = pipeline->head;
2919    while(curr) {
2920      if(curr->ptr == handle) {
2921        Curl_llist_remove(pipeline, curr, NULL);
2922        return 1; /* we removed a handle */
2923      }
2924      curr = curr->next;
2925    }
2926  }
2927
2928  return 0;
2929}
2930
2931#if 0 /* this code is saved here as it is useful for debugging purposes */
2932static void Curl_printPipeline(struct curl_llist *pipeline)
2933{
2934  struct curl_llist_element *curr;
2935
2936  curr = pipeline->head;
2937  while(curr) {
2938    struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
2939    infof(data, "Handle in pipeline: %s\n", data->state.path);
2940    curr = curr->next;
2941  }
2942}
2943#endif
2944
2945static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
2946{
2947  struct curl_llist_element *curr = pipeline->head;
2948  if(curr) {
2949    return (struct Curl_easy *) curr->ptr;
2950  }
2951
2952  return NULL;
2953}
2954
2955/* remove the specified connection from all (possible) pipelines and related
2956   queues */
2957void Curl_getoff_all_pipelines(struct Curl_easy *data,
2958                               struct connectdata *conn)
2959{
2960  bool recv_head = (conn->readchannel_inuse &&
2961                    Curl_recvpipe_head(data, conn));
2962  bool send_head = (conn->writechannel_inuse &&
2963                    Curl_sendpipe_head(data, conn));
2964
2965  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
2966    Curl_pipeline_leave_read(conn);
2967  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
2968    Curl_pipeline_leave_write(conn);
2969}
2970
2971static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
2972{
2973  struct curl_llist_element *curr;
2974
2975  if(!pipeline)
2976    return;
2977
2978  curr = pipeline->head;
2979  while(curr) {
2980    struct curl_llist_element *next = curr->next;
2981    struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
2982
2983#ifdef DEBUGBUILD /* debug-only code */
2984    if(data->magic != CURLEASY_MAGIC_NUMBER) {
2985      /* MAJOR BADNESS */
2986      infof(data, "signalPipeClose() found BAAD easy handle\n");
2987    }
2988#endif
2989
2990    if(pipe_broke)
2991      data->state.pipe_broke = TRUE;
2992    Curl_multi_handlePipeBreak(data);
2993    Curl_llist_remove(pipeline, curr, NULL);
2994    curr = next;
2995  }
2996}
2997
2998/*
2999 * This function finds the connection in the connection
3000 * cache that has been unused for the longest time.
3001 *
3002 * Returns the pointer to the oldest idle connection, or NULL if none was
3003 * found.
3004 */
3005struct connectdata *
3006Curl_oldest_idle_connection(struct Curl_easy *data)
3007{
3008  struct conncache *bc = data->state.conn_cache;
3009  struct curl_hash_iterator iter;
3010  struct curl_llist_element *curr;
3011  struct curl_hash_element *he;
3012  long highscore=-1;
3013  long score;
3014  struct timeval now;
3015  struct connectdata *conn_candidate = NULL;
3016  struct connectbundle *bundle;
3017
3018  now = Curl_tvnow();
3019
3020  Curl_hash_start_iterate(&bc->hash, &iter);
3021
3022  he = Curl_hash_next_element(&iter);
3023  while(he) {
3024    struct connectdata *conn;
3025
3026    bundle = he->ptr;
3027
3028    curr = bundle->conn_list->head;
3029    while(curr) {
3030      conn = curr->ptr;
3031
3032      if(!conn->inuse) {
3033        /* Set higher score for the age passed since the connection was used */
3034        score = Curl_tvdiff(now, conn->now);
3035
3036        if(score > highscore) {
3037          highscore = score;
3038          conn_candidate = conn;
3039        }
3040      }
3041      curr = curr->next;
3042    }
3043
3044    he = Curl_hash_next_element(&iter);
3045  }
3046
3047  return conn_candidate;
3048}
3049
3050/*
3051 * This function finds the connection in the connection
3052 * bundle that has been unused for the longest time.
3053 *
3054 * Returns the pointer to the oldest idle connection, or NULL if none was
3055 * found.
3056 */
3057static struct connectdata *
3058find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
3059                                      struct connectbundle *bundle)
3060{
3061  struct curl_llist_element *curr;
3062  long highscore=-1;
3063  long score;
3064  struct timeval now;
3065  struct connectdata *conn_candidate = NULL;
3066  struct connectdata *conn;
3067
3068  (void)data;
3069
3070  now = Curl_tvnow();
3071
3072  curr = bundle->conn_list->head;
3073  while(curr) {
3074    conn = curr->ptr;
3075
3076    if(!conn->inuse) {
3077      /* Set higher score for the age passed since the connection was used */
3078      score = Curl_tvdiff(now, conn->now);
3079
3080      if(score > highscore) {
3081        highscore = score;
3082        conn_candidate = conn;
3083      }
3084    }
3085    curr = curr->next;
3086  }
3087
3088  return conn_candidate;
3089}
3090
3091/*
3092 * This function checks if given connection is dead and disconnects if so.
3093 * (That also removes it from the connection cache.)
3094 *
3095 * Returns TRUE if the connection actually was dead and disconnected.
3096 */
3097static bool disconnect_if_dead(struct connectdata *conn,
3098                               struct Curl_easy *data)
3099{
3100  size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
3101  if(!pipeLen && !conn->inuse) {
3102    /* The check for a dead socket makes sense only if there are no
3103       handles in pipeline and the connection isn't already marked in
3104       use */
3105    bool dead;
3106    if(conn->handler->protocol & CURLPROTO_RTSP)
3107      /* RTSP is a special case due to RTP interleaving */
3108      dead = Curl_rtsp_connisdead(conn);
3109    else
3110      dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
3111
3112    if(dead) {
3113      conn->data = data;
3114      infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
3115
3116      /* disconnect resources */
3117      Curl_disconnect(conn, /* dead_connection */TRUE);
3118      return TRUE;
3119    }
3120  }
3121  return FALSE;
3122}
3123
3124/*
3125 * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
3126 *
3127 * Returns always 0.
3128 */
3129static int call_disconnect_if_dead(struct connectdata *conn,
3130                                      void *param)
3131{
3132  struct Curl_easy* data = (struct Curl_easy*)param;
3133  disconnect_if_dead(conn, data);
3134  return 0; /* continue iteration */
3135}
3136
3137/*
3138 * This function scans the connection cache for half-open/dead connections,
3139 * closes and removes them.
3140 * The cleanup is done at most once per second.
3141 */
3142static void prune_dead_connections(struct Curl_easy *data)
3143{
3144  struct timeval now = Curl_tvnow();
3145  long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
3146
3147  if(elapsed >= 1000L) {
3148    Curl_conncache_foreach(data->state.conn_cache, data,
3149                           call_disconnect_if_dead);
3150    data->state.conn_cache->last_cleanup = now;
3151  }
3152}
3153
3154
3155static size_t max_pipeline_length(struct Curl_multi *multi)
3156{
3157  return multi ? multi->max_pipeline_length : 0;
3158}
3159
3160
3161/*
3162 * Given one filled in connection struct (named needle), this function should
3163 * detect if there already is one that has all the significant details
3164 * exactly the same and thus should be used instead.
3165 *
3166 * If there is a match, this function returns TRUE - and has marked the
3167 * connection as 'in-use'. It must later be called with ConnectionDone() to
3168 * return back to 'idle' (unused) state.
3169 *
3170 * The force_reuse flag is set if the connection must be used, even if
3171 * the pipelining strategy wants to open a new connection instead of reusing.
3172 */
3173static bool
3174ConnectionExists(struct Curl_easy *data,
3175                 struct connectdata *needle,
3176                 struct connectdata **usethis,
3177                 bool *force_reuse,
3178                 bool *waitpipe)
3179{
3180  struct connectdata *check;
3181  struct connectdata *chosen = 0;
3182  bool foundPendingCandidate = FALSE;
3183  bool canPipeline = IsPipeliningPossible(data, needle);
3184  struct connectbundle *bundle;
3185
3186#ifdef USE_NTLM
3187  bool wantNTLMhttp = ((data->state.authhost.want &
3188                      (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
3189                      (needle->handler->protocol & PROTO_FAMILY_HTTP));
3190  bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
3191                           ((data->state.authproxy.want &
3192                           (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
3193                           (needle->handler->protocol & PROTO_FAMILY_HTTP)));
3194#endif
3195
3196  *force_reuse = FALSE;
3197  *waitpipe = FALSE;
3198
3199  /* We can't pipe if the site is blacklisted */
3200  if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
3201    canPipeline = FALSE;
3202  }
3203
3204  /* Look up the bundle with all the connections to this
3205     particular host */
3206  bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
3207  if(bundle) {
3208    /* Max pipe length is zero (unlimited) for multiplexed connections */
3209    size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
3210      max_pipeline_length(data->multi):0;
3211    size_t best_pipe_len = max_pipe_len;
3212    struct curl_llist_element *curr;
3213    const char *hostname;
3214
3215    if(needle->bits.conn_to_host)
3216      hostname = needle->conn_to_host.name;
3217    else
3218      hostname = needle->host.name;
3219
3220    infof(data, "Found bundle for host %s: %p [%s]\n",
3221          hostname, (void *)bundle,
3222          (bundle->multiuse== BUNDLE_PIPELINING?
3223           "can pipeline":
3224           (bundle->multiuse== BUNDLE_MULTIPLEX?
3225            "can multiplex":"serially")));
3226
3227    /* We can't pipe if we don't know anything about the server */
3228    if(canPipeline) {
3229      if(bundle->multiuse <= BUNDLE_UNKNOWN) {
3230        if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
3231          infof(data, "Server doesn't support multi-use yet, wait\n");
3232          *waitpipe = TRUE;
3233          return FALSE; /* no re-use */
3234        }
3235
3236        infof(data, "Server doesn't support multi-use (yet)\n");
3237        canPipeline = FALSE;
3238      }
3239      if((bundle->multiuse == BUNDLE_PIPELINING) &&
3240         !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) {
3241        /* not asked for, switch off */
3242        infof(data, "Could pipeline, but not asked to!\n");
3243        canPipeline = FALSE;
3244      }
3245      else if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
3246              !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) {
3247        infof(data, "Could multiplex, but not asked to!\n");
3248        canPipeline = FALSE;
3249      }
3250    }
3251
3252    curr = bundle->conn_list->head;
3253    while(curr) {
3254      bool match = FALSE;
3255      size_t pipeLen;
3256
3257      /*
3258       * Note that if we use a HTTP proxy in normal mode (no tunneling), we
3259       * check connections to that proxy and not to the actual remote server.
3260       */
3261      check = curr->ptr;
3262      curr = curr->next;
3263
3264      if(disconnect_if_dead(check, data))
3265        continue;
3266
3267      pipeLen = check->send_pipe->size + check->recv_pipe->size;
3268
3269      if(canPipeline) {
3270
3271        if(!check->bits.multiplex) {
3272          /* If not multiplexing, make sure the pipe has only GET requests */
3273          struct Curl_easy* sh = gethandleathead(check->send_pipe);
3274          struct Curl_easy* rh = gethandleathead(check->recv_pipe);
3275          if(sh) {
3276            if(!IsPipeliningPossible(sh, check))
3277              continue;
3278          }
3279          else if(rh) {
3280            if(!IsPipeliningPossible(rh, check))
3281              continue;
3282          }
3283        }
3284      }
3285      else {
3286        if(pipeLen > 0) {
3287          /* can only happen within multi handles, and means that another easy
3288             handle is using this connection */
3289          continue;
3290        }
3291
3292        if(Curl_resolver_asynch()) {
3293          /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
3294             completed yet and until then we don't re-use this connection */
3295          if(!check->ip_addr_str[0]) {
3296            infof(data,
3297                  "Connection #%ld is still name resolving, can't reuse\n",
3298                  check->connection_id);
3299            continue;
3300          }
3301        }
3302
3303        if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
3304           check->bits.close) {
3305          if(!check->bits.close)
3306            foundPendingCandidate = TRUE;
3307          /* Don't pick a connection that hasn't connected yet or that is going
3308             to get closed. */
3309          infof(data, "Connection #%ld isn't open enough, can't reuse\n",
3310                check->connection_id);
3311#ifdef DEBUGBUILD
3312          if(check->recv_pipe->size > 0) {
3313            infof(data,
3314                  "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
3315                  check->connection_id);
3316          }
3317#endif
3318          continue;
3319        }
3320      }
3321
3322      if((needle->handler->flags&PROTOPT_SSL) !=
3323         (check->handler->flags&PROTOPT_SSL))
3324        /* don't do mixed SSL and non-SSL connections */
3325        if(get_protocol_family(check->handler->protocol) !=
3326           needle->handler->protocol || !check->tls_upgraded)
3327          /* except protocols that have been upgraded via TLS */
3328          continue;
3329
3330      if(needle->handler->flags&PROTOPT_SSL) {
3331        if((data->set.ssl.verifypeer != check->verifypeer) ||
3332           (data->set.ssl.verifyhost != check->verifyhost))
3333          continue;
3334      }
3335
3336      if(needle->bits.proxy != check->bits.proxy)
3337        /* don't do mixed proxy and non-proxy connections */
3338        continue;
3339
3340      if(needle->bits.proxy &&
3341         (needle->proxytype != check->proxytype ||
3342          needle->bits.httpproxy != check->bits.httpproxy ||
3343          needle->bits.tunnel_proxy != check->bits.tunnel_proxy ||
3344          !Curl_raw_equal(needle->proxy.name, check->proxy.name) ||
3345          needle->port != check->port))
3346        /* don't mix connections that use different proxies */
3347        continue;
3348
3349      if(needle->bits.conn_to_host != check->bits.conn_to_host)
3350        /* don't mix connections that use the "connect to host" feature and
3351         * connections that don't use this feature */
3352        continue;
3353
3354      if(needle->bits.conn_to_port != check->bits.conn_to_port)
3355        /* don't mix connections that use the "connect to port" feature and
3356         * connections that don't use this feature */
3357        continue;
3358
3359      if(!canPipeline && check->inuse)
3360        /* this request can't be pipelined but the checked connection is
3361           already in use so we skip it */
3362        continue;
3363
3364      if(needle->localdev || needle->localport) {
3365        /* If we are bound to a specific local end (IP+port), we must not
3366           re-use a random other one, although if we didn't ask for a
3367           particular one we can reuse one that was bound.
3368
3369           This comparison is a bit rough and too strict. Since the input
3370           parameters can be specified in numerous ways and still end up the
3371           same it would take a lot of processing to make it really accurate.
3372           Instead, this matching will assume that re-uses of bound connections
3373           will most likely also re-use the exact same binding parameters and
3374           missing out a few edge cases shouldn't hurt anyone very much.
3375        */
3376        if((check->localport != needle->localport) ||
3377           (check->localportrange != needle->localportrange) ||
3378           !check->localdev ||
3379           !needle->localdev ||
3380           strcmp(check->localdev, needle->localdev))
3381          continue;
3382      }
3383
3384      if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
3385        /* This protocol requires credentials per connection,
3386           so verify that we're using the same name and password as well */
3387        if(!strequal(needle->user, check->user) ||
3388           !strequal(needle->passwd, check->passwd)) {
3389          /* one of them was different */
3390          continue;
3391        }
3392      }
3393
3394      if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
3395         (needle->bits.httpproxy && needle->bits.tunnel_proxy)) {
3396        /* The requested connection does not use a HTTP proxy or it uses SSL or
3397           it is a non-SSL protocol tunneled over the same HTTP proxy name and
3398           port number */
3399        if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
3400            (get_protocol_family(check->handler->protocol) ==
3401             needle->handler->protocol && check->tls_upgraded)) &&
3402           (!needle->bits.conn_to_host || Curl_raw_equal(
3403            needle->conn_to_host.name, check->conn_to_host.name)) &&
3404           (!needle->bits.conn_to_port ||
3405             needle->conn_to_port == check->conn_to_port) &&
3406           Curl_raw_equal(needle->host.name, check->host.name) &&
3407           needle->remote_port == check->remote_port) {
3408          /* The schemes match or the the protocol family is the same and the
3409             previous connection was TLS upgraded, and the hostname and host
3410             port match */
3411          if(needle->handler->flags & PROTOPT_SSL) {
3412            /* This is a SSL connection so verify that we're using the same
3413               SSL options as well */
3414            if(!Curl_ssl_config_matches(&needle->ssl_config,
3415                                        &check->ssl_config)) {
3416              DEBUGF(infof(data,
3417                           "Connection #%ld has different SSL parameters, "
3418                           "can't reuse\n",
3419                           check->connection_id));
3420              continue;
3421            }
3422            else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
3423              foundPendingCandidate = TRUE;
3424              DEBUGF(infof(data,
3425                           "Connection #%ld has not started SSL connect, "
3426                           "can't reuse\n",
3427                           check->connection_id));
3428              continue;
3429            }
3430          }
3431          match = TRUE;
3432        }
3433      }
3434      else {
3435        /* The requested connection is using the same HTTP proxy in normal
3436           mode (no tunneling) */
3437        match = TRUE;
3438      }
3439
3440      if(match) {
3441#if defined(USE_NTLM)
3442        /* If we are looking for an HTTP+NTLM connection, check if this is
3443           already authenticating with the right credentials. If not, keep
3444           looking so that we can reuse NTLM connections if
3445           possible. (Especially we must not reuse the same connection if
3446           partway through a handshake!) */
3447        if(wantNTLMhttp) {
3448          if(!strequal(needle->user, check->user) ||
3449             !strequal(needle->passwd, check->passwd))
3450            continue;
3451        }
3452        else if(check->ntlm.state != NTLMSTATE_NONE) {
3453          /* Connection is using NTLM auth but we don't want NTLM */
3454          continue;
3455        }
3456
3457        /* Same for Proxy NTLM authentication */
3458        if(wantProxyNTLMhttp) {
3459          /* Both check->proxyuser and check->proxypasswd can be NULL */
3460          if(!check->proxyuser || !check->proxypasswd)
3461            continue;
3462
3463          if(!strequal(needle->proxyuser, check->proxyuser) ||
3464             !strequal(needle->proxypasswd, check->proxypasswd))
3465            continue;
3466        }
3467        else if(check->proxyntlm.state != NTLMSTATE_NONE) {
3468          /* Proxy connection is using NTLM auth but we don't want NTLM */
3469          continue;
3470        }
3471
3472        if(wantNTLMhttp || wantProxyNTLMhttp) {
3473          /* Credentials are already checked, we can use this connection */
3474          chosen = check;
3475
3476          if((wantNTLMhttp &&
3477             (check->ntlm.state != NTLMSTATE_NONE)) ||
3478              (wantProxyNTLMhttp &&
3479               (check->proxyntlm.state != NTLMSTATE_NONE))) {
3480            /* We must use this connection, no other */
3481            *force_reuse = TRUE;
3482            break;
3483          }
3484
3485          /* Continue look up for a better connection */
3486          continue;
3487        }
3488#endif
3489        if(canPipeline) {
3490          /* We can pipeline if we want to. Let's continue looking for
3491             the optimal connection to use, i.e the shortest pipe that is not
3492             blacklisted. */
3493
3494          if(pipeLen == 0) {
3495            /* We have the optimal connection. Let's stop looking. */
3496            chosen = check;
3497            break;
3498          }
3499
3500          /* We can't use the connection if the pipe is full */
3501          if(max_pipe_len && (pipeLen >= max_pipe_len)) {
3502            infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
3503            continue;
3504          }
3505#ifdef USE_NGHTTP2
3506          /* If multiplexed, make sure we don't go over concurrency limit */
3507          if(check->bits.multiplex) {
3508            /* Multiplexed connections can only be HTTP/2 for now */
3509            struct http_conn *httpc = &check->proto.httpc;
3510            if(pipeLen >= httpc->settings.max_concurrent_streams) {
3511              infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
3512                    pipeLen);
3513              continue;
3514            }
3515          }
3516#endif
3517          /* We can't use the connection if the pipe is penalized */
3518          if(Curl_pipeline_penalized(data, check)) {
3519            infof(data, "Penalized, skip\n");
3520            continue;
3521          }
3522
3523          if(max_pipe_len) {
3524            if(pipeLen < best_pipe_len) {
3525              /* This connection has a shorter pipe so far. We'll pick this
3526                 and continue searching */
3527              chosen = check;
3528              best_pipe_len = pipeLen;
3529              continue;
3530            }
3531          }
3532          else {
3533            /* When not pipelining (== multiplexed), we have a match here! */
3534            chosen = check;
3535            infof(data, "Multiplexed connection found!\n");
3536            break;
3537          }
3538        }
3539        else {
3540          /* We have found a connection. Let's stop searching. */
3541          chosen = check;
3542          break;
3543        }
3544      }
3545    }
3546  }
3547
3548  if(chosen) {
3549    *usethis = chosen;
3550    return TRUE; /* yes, we found one to use! */
3551  }
3552
3553  if(foundPendingCandidate && data->set.pipewait) {
3554    infof(data,
3555          "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n");
3556    *waitpipe = TRUE;
3557  }
3558
3559  return FALSE; /* no matching connecting exists */
3560}
3561
3562/* after a TCP connection to the proxy has been verified, this function does
3563   the next magic step.
3564
3565   Note: this function's sub-functions call failf()
3566
3567*/
3568CURLcode Curl_connected_proxy(struct connectdata *conn,
3569                              int sockindex)
3570{
3571  if(!conn->bits.proxy || sockindex)
3572    /* this magic only works for the primary socket as the secondary is used
3573       for FTP only and it has FTP specific magic in ftp.c */
3574    return CURLE_OK;
3575
3576  switch(conn->proxytype) {
3577#ifndef CURL_DISABLE_PROXY
3578  case CURLPROXY_SOCKS5:
3579  case CURLPROXY_SOCKS5_HOSTNAME:
3580    return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
3581                       conn->bits.conn_to_host ? conn->conn_to_host.name :
3582                       conn->host.name,
3583                       conn->bits.conn_to_port ? conn->conn_to_port :
3584                       conn->remote_port,
3585                       FIRSTSOCKET, conn);
3586
3587  case CURLPROXY_SOCKS4:
3588    return Curl_SOCKS4(conn->proxyuser,
3589                       conn->bits.conn_to_host ? conn->conn_to_host.name :
3590                       conn->host.name,
3591                       conn->bits.conn_to_port ? conn->conn_to_port :
3592                       conn->remote_port,
3593                       FIRSTSOCKET, conn, FALSE);
3594
3595  case CURLPROXY_SOCKS4A:
3596    return Curl_SOCKS4(conn->proxyuser,
3597                       conn->bits.conn_to_host ? conn->conn_to_host.name :
3598                       conn->host.name,
3599                       conn->bits.conn_to_port ? conn->conn_to_port :
3600                       conn->remote_port,
3601                       FIRSTSOCKET, conn, TRUE);
3602
3603#endif /* CURL_DISABLE_PROXY */
3604  case CURLPROXY_HTTP:
3605  case CURLPROXY_HTTP_1_0:
3606    /* do nothing here. handled later. */
3607    break;
3608  default:
3609    break;
3610  } /* switch proxytype */
3611
3612  return CURLE_OK;
3613}
3614
3615/*
3616 * verboseconnect() displays verbose information after a connect
3617 */
3618#ifndef CURL_DISABLE_VERBOSE_STRINGS
3619void Curl_verboseconnect(struct connectdata *conn)
3620{
3621  if(conn->data->set.verbose)
3622    infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
3623          conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
3624          conn->ip_addr_str, conn->port, conn->connection_id);
3625}
3626#endif
3627
3628int Curl_protocol_getsock(struct connectdata *conn,
3629                          curl_socket_t *socks,
3630                          int numsocks)
3631{
3632  if(conn->handler->proto_getsock)
3633    return conn->handler->proto_getsock(conn, socks, numsocks);
3634  return GETSOCK_BLANK;
3635}
3636
3637int Curl_doing_getsock(struct connectdata *conn,
3638                       curl_socket_t *socks,
3639                       int numsocks)
3640{
3641  if(conn && conn->handler->doing_getsock)
3642    return conn->handler->doing_getsock(conn, socks, numsocks);
3643  return GETSOCK_BLANK;
3644}
3645
3646/*
3647 * We are doing protocol-specific connecting and this is being called over and
3648 * over from the multi interface until the connection phase is done on
3649 * protocol layer.
3650 */
3651
3652CURLcode Curl_protocol_connecting(struct connectdata *conn,
3653                                  bool *done)
3654{
3655  CURLcode result=CURLE_OK;
3656
3657  if(conn && conn->handler->connecting) {
3658    *done = FALSE;
3659    result = conn->handler->connecting(conn, done);
3660  }
3661  else
3662    *done = TRUE;
3663
3664  return result;
3665}
3666
3667/*
3668 * We are DOING this is being called over and over from the multi interface
3669 * until the DOING phase is done on protocol layer.
3670 */
3671
3672CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
3673{
3674  CURLcode result=CURLE_OK;
3675
3676  if(conn && conn->handler->doing) {
3677    *done = FALSE;
3678    result = conn->handler->doing(conn, done);
3679  }
3680  else
3681    *done = TRUE;
3682
3683  return result;
3684}
3685
3686/*
3687 * We have discovered that the TCP connection has been successful, we can now
3688 * proceed with some action.
3689 *
3690 */
3691CURLcode Curl_protocol_connect(struct connectdata *conn,
3692                               bool *protocol_done)
3693{
3694  CURLcode result=CURLE_OK;
3695
3696  *protocol_done = FALSE;
3697
3698  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
3699    /* We already are connected, get back. This may happen when the connect
3700       worked fine in the first call, like when we connect to a local server
3701       or proxy. Note that we don't know if the protocol is actually done.
3702
3703       Unless this protocol doesn't have any protocol-connect callback, as
3704       then we know we're done. */
3705    if(!conn->handler->connecting)
3706      *protocol_done = TRUE;
3707
3708    return CURLE_OK;
3709  }
3710
3711  if(!conn->bits.protoconnstart) {
3712
3713    result = Curl_proxy_connect(conn);
3714    if(result)
3715      return result;
3716
3717    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
3718       (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
3719      /* when using an HTTP tunnel proxy, await complete tunnel establishment
3720         before proceeding further. Return CURLE_OK so we'll be called again */
3721      return CURLE_OK;
3722
3723    if(conn->handler->connect_it) {
3724      /* is there a protocol-specific connect() procedure? */
3725
3726      /* Call the protocol-specific connect function */
3727      result = conn->handler->connect_it(conn, protocol_done);
3728    }
3729    else
3730      *protocol_done = TRUE;
3731
3732    /* it has started, possibly even completed but that knowledge isn't stored
3733       in this bit! */
3734    if(!result)
3735      conn->bits.protoconnstart = TRUE;
3736  }
3737
3738  return result; /* pass back status */
3739}
3740
3741/*
3742 * Helpers for IDNA convertions.
3743 */
3744static bool is_ASCII_name(const char *hostname)
3745{
3746  const unsigned char *ch = (const unsigned char*)hostname;
3747
3748  while(*ch) {
3749    if(*ch++ & 0x80)
3750      return FALSE;
3751  }
3752  return TRUE;
3753}
3754
3755#ifdef USE_LIBIDN
3756/*
3757 * Check if characters in hostname is allowed in Top Level Domain.
3758 */
3759static bool tld_check_name(struct Curl_easy *data,
3760                           const char *ace_hostname)
3761{
3762  size_t err_pos;
3763  char *uc_name = NULL;
3764  int rc;
3765#ifndef CURL_DISABLE_VERBOSE_STRINGS
3766  const char *tld_errmsg = "<no msg>";
3767#else
3768  (void)data;
3769#endif
3770
3771  /* Convert (and downcase) ACE-name back into locale's character set */
3772  rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
3773  if(rc != IDNA_SUCCESS)
3774    return FALSE;
3775
3776  /* Warning: err_pos receives "the decoded character offset rather than the
3777     byte position in the string." And as of libidn 1.32 that character offset
3778     is for UTF-8, even if the passed in string is another locale. */
3779  rc = tld_check_lz(uc_name, &err_pos, NULL);
3780#ifndef CURL_DISABLE_VERBOSE_STRINGS
3781#ifdef HAVE_TLD_STRERROR
3782  if(rc != TLD_SUCCESS)
3783    tld_errmsg = tld_strerror((Tld_rc)rc);
3784#endif
3785  if(rc != TLD_SUCCESS)
3786    infof(data, "WARNING: TLD check for %s failed; %s\n",
3787          uc_name, tld_errmsg);
3788#endif /* CURL_DISABLE_VERBOSE_STRINGS */
3789  if(uc_name)
3790     idn_free(uc_name);
3791  if(rc != TLD_SUCCESS)
3792    return FALSE;
3793
3794  return TRUE;
3795}
3796#endif
3797
3798/*
3799 * Perform any necessary IDN conversion of hostname
3800 */
3801static void fix_hostname(struct Curl_easy *data,
3802                         struct connectdata *conn, struct hostname *host)
3803{
3804  size_t len;
3805
3806#ifndef USE_LIBIDN
3807  (void)data;
3808  (void)conn;
3809#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
3810  (void)conn;
3811#endif
3812
3813  /* set the name we use to display the host name */
3814  host->dispname = host->name;
3815
3816  len = strlen(host->name);
3817  if(len && (host->name[len-1] == '.'))
3818    /* strip off a single trailing dot if present, primarily for SNI but
3819       there's no use for it */
3820    host->name[len-1]=0;
3821
3822  /* Check name for non-ASCII and convert hostname to ACE form if we can */
3823  if(!is_ASCII_name(host->name)) {
3824#ifdef USE_LIBIDN
3825    if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
3826      char *ace_hostname = NULL;
3827
3828      int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
3829      infof(data, "Input domain encoded as `%s'\n",
3830            stringprep_locale_charset());
3831      if(rc == IDNA_SUCCESS) {
3832        /* tld_check_name() displays a warning if the host name contains
3833           "illegal" characters for this TLD */
3834        (void)tld_check_name(data, ace_hostname);
3835
3836        host->encalloc = ace_hostname;
3837        /* change the name pointer to point to the encoded hostname */
3838        host->name = host->encalloc;
3839      }
3840      else
3841        infof(data, "Failed to convert %s to ACE; %s\n", host->name,
3842              Curl_idn_strerror(conn, rc));
3843    }
3844#elif defined(USE_WIN32_IDN)
3845    char *ace_hostname = NULL;
3846
3847    if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
3848      host->encalloc = ace_hostname;
3849      /* change the name pointer to point to the encoded hostname */
3850      host->name = host->encalloc;
3851    }
3852    else
3853      infof(data, "Failed to convert %s to ACE;\n", host->name);
3854#else
3855    infof(data, "IDN support not present, can't parse Unicode domains\n");
3856#endif
3857  }
3858}
3859
3860/*
3861 * Frees data allocated by fix_hostname()
3862 */
3863static void free_fixed_hostname(struct hostname *host)
3864{
3865#if defined(USE_LIBIDN)
3866  if(host->encalloc) {
3867    idn_free(host->encalloc); /* must be freed with idn_free() since this was
3868                                 allocated by libidn */
3869    host->encalloc = NULL;
3870  }
3871#elif defined(USE_WIN32_IDN)
3872  free(host->encalloc); /* must be freed withidn_free() since this was
3873                           allocated by curl_win32_idn_to_ascii */
3874  host->encalloc = NULL;
3875#else
3876  (void)host;
3877#endif
3878}
3879
3880static void llist_dtor(void *user, void *element)
3881{
3882  (void)user;
3883  (void)element;
3884  /* Do nothing */
3885}
3886
3887/*
3888 * Allocate and initialize a new connectdata object.
3889 */
3890static struct connectdata *allocate_conn(struct Curl_easy *data)
3891{
3892  struct connectdata *conn = calloc(1, sizeof(struct connectdata));
3893  if(!conn)
3894    return NULL;
3895
3896  conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
3897                                           already from start to avoid NULL
3898                                           situations and checks */
3899
3900  /* and we setup a few fields in case we end up actually using this struct */
3901
3902  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
3903  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3904  conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
3905  conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
3906  conn->connection_id = -1;    /* no ID */
3907  conn->port = -1; /* unknown at this point */
3908  conn->remote_port = -1; /* unknown */
3909#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
3910  conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
3911  conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
3912#endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */
3913
3914  /* Default protocol-independent behavior doesn't support persistent
3915     connections, so we set this to force-close. Protocols that support
3916     this need to set this to FALSE in their "curl_do" functions. */
3917  connclose(conn, "Default to force-close");
3918
3919  /* Store creation time to help future close decision making */
3920  conn->created = Curl_tvnow();
3921
3922  conn->data = data; /* Setup the association between this connection
3923                        and the Curl_easy */
3924
3925  conn->proxytype = data->set.proxytype; /* type */
3926
3927#ifdef CURL_DISABLE_PROXY
3928
3929  conn->bits.proxy = FALSE;
3930  conn->bits.httpproxy = FALSE;
3931  conn->bits.proxy_user_passwd = FALSE;
3932  conn->bits.tunnel_proxy = FALSE;
3933
3934#else /* CURL_DISABLE_PROXY */
3935
3936  /* note that these two proxy bits are now just on what looks to be
3937     requested, they may be altered down the road */
3938  conn->bits.proxy = (data->set.str[STRING_PROXY] &&
3939                      *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
3940  conn->bits.httpproxy = (conn->bits.proxy &&
3941                          (conn->proxytype == CURLPROXY_HTTP ||
3942                           conn->proxytype == CURLPROXY_HTTP_1_0)) ?
3943                          TRUE : FALSE;
3944  conn->bits.proxy_user_passwd = (data->set.str[STRING_PROXYUSERNAME]) ?
3945                                 TRUE : FALSE;
3946  conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
3947
3948#endif /* CURL_DISABLE_PROXY */
3949
3950  conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE;
3951  conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
3952  conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
3953
3954  conn->verifypeer = data->set.ssl.verifypeer;
3955  conn->verifyhost = data->set.ssl.verifyhost;
3956
3957  conn->ip_version = data->set.ipver;
3958
3959#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
3960    defined(NTLM_WB_ENABLED)
3961  conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
3962  conn->ntlm_auth_hlpr_pid = 0;
3963  conn->challenge_header = NULL;
3964  conn->response_header = NULL;
3965#endif
3966
3967  if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
3968     !conn->master_buffer) {
3969    /* Allocate master_buffer to be used for HTTP/1 pipelining */
3970    conn->master_buffer = calloc(BUFSIZE, sizeof (char));
3971    if(!conn->master_buffer)
3972      goto error;
3973  }
3974
3975  /* Initialize the pipeline lists */
3976  conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3977  conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
3978  if(!conn->send_pipe || !conn->recv_pipe)
3979    goto error;
3980
3981#ifdef HAVE_GSSAPI
3982  conn->data_prot = PROT_CLEAR;
3983#endif
3984
3985  /* Store the local bind parameters that will be used for this connection */
3986  if(data->set.str[STRING_DEVICE]) {
3987    conn->localdev = strdup(data->set.str[STRING_DEVICE]);
3988    if(!conn->localdev)
3989      goto error;
3990  }
3991  conn->localportrange = data->set.localportrange;
3992  conn->localport = data->set.localport;
3993
3994  /* the close socket stuff needs to be copied to the connection struct as
3995     it may live on without (this specific) Curl_easy */
3996  conn->fclosesocket = data->set.fclosesocket;
3997  conn->closesocket_client = data->set.closesocket_client;
3998
3999  return conn;
4000  error:
4001
4002  Curl_llist_destroy(conn->send_pipe, NULL);
4003  Curl_llist_destroy(conn->recv_pipe, NULL);
4004
4005  conn->send_pipe = NULL;
4006  conn->recv_pipe = NULL;
4007
4008  free(conn->master_buffer);
4009  free(conn->localdev);
4010  free(conn);
4011  return NULL;
4012}
4013
4014static CURLcode findprotocol(struct Curl_easy *data,
4015                             struct connectdata *conn,
4016                             const char *protostr)
4017{
4018  const struct Curl_handler * const *pp;
4019  const struct Curl_handler *p;
4020
4021  /* Scan protocol handler table and match against 'protostr' to set a few
4022     variables based on the URL. Now that the handler may be changed later
4023     when the protocol specific setup function is called. */
4024  for(pp = protocols; (p = *pp) != NULL; pp++) {
4025    if(Curl_raw_equal(p->scheme, protostr)) {
4026      /* Protocol found in table. Check if allowed */
4027      if(!(data->set.allowed_protocols & p->protocol))
4028        /* nope, get out */
4029        break;
4030
4031      /* it is allowed for "normal" request, now do an extra check if this is
4032         the result of a redirect */
4033      if(data->state.this_is_a_follow &&
4034         !(data->set.redir_protocols & p->protocol))
4035        /* nope, get out */
4036        break;
4037
4038      /* Perform setup complement if some. */
4039      conn->handler = conn->given = p;
4040
4041      /* 'port' and 'remote_port' are set in setup_connection_internals() */
4042      return CURLE_OK;
4043    }
4044  }
4045
4046
4047  /* The protocol was not found in the table, but we don't have to assign it
4048     to anything since it is already assigned to a dummy-struct in the
4049     create_conn() function when the connectdata struct is allocated. */
4050  failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
4051        protostr);
4052
4053  return CURLE_UNSUPPORTED_PROTOCOL;
4054}
4055
4056/*
4057 * Parse URL and fill in the relevant members of the connection struct.
4058 */
4059static CURLcode parseurlandfillconn(struct Curl_easy *data,
4060                                    struct connectdata *conn,
4061                                    bool *prot_missing,
4062                                    char **userp, char **passwdp,
4063                                    char **optionsp)
4064{
4065  char *at;
4066  char *fragment;
4067  char *path = data->state.path;
4068  char *query;
4069  int rc;
4070  char protobuf[16] = "";
4071  const char *protop = "";
4072  CURLcode result;
4073  bool rebuild_url = FALSE;
4074
4075  *prot_missing = FALSE;
4076
4077  /* We might pass the entire URL into the request so we need to make sure
4078   * there are no bad characters in there.*/
4079  if(strpbrk(data->change.url, "\r\n")) {
4080    failf(data, "Illegal characters found in URL");
4081    return CURLE_URL_MALFORMAT;
4082  }
4083
4084  /*************************************************************
4085   * Parse the URL.
4086   *
4087   * We need to parse the url even when using the proxy, because we will need
4088   * the hostname and port in case we are trying to SSL connect through the
4089   * proxy -- and we don't know if we will need to use SSL until we parse the
4090   * url ...
4091   ************************************************************/
4092  if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
4093                  protobuf, path)) &&
4094     Curl_raw_equal(protobuf, "file")) {
4095    if(path[0] == '/' && path[1] == '/') {
4096      /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
4097       * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
4098       * file://localhost/<path> is similar to how other schemes treat missing
4099       * hostnames.  See RFC 1808. */
4100
4101      /* This cannot be done with strcpy() in a portable manner, since the
4102         memory areas overlap! */
4103      memmove(path, path + 2, strlen(path + 2)+1);
4104    }
4105    /*
4106     * we deal with file://<host>/<path> differently since it supports no
4107     * hostname other than "localhost" and "127.0.0.1", which is unique among
4108     * the URL protocols specified in RFC 1738
4109     */
4110    if(path[0] != '/') {
4111      /* the URL included a host name, we ignore host names in file:// URLs
4112         as the standards don't define what to do with them */
4113      char *ptr=strchr(path, '/');
4114      if(ptr) {
4115        /* there was a slash present
4116
4117           RFC1738 (section 3.1, page 5) says:
4118
4119           The rest of the locator consists of data specific to the scheme,
4120           and is known as the "url-path". It supplies the details of how the
4121           specified resource can be accessed. Note that the "/" between the
4122           host (or port) and the url-path is NOT part of the url-path.
4123
4124           As most agents use file://localhost/foo to get '/foo' although the
4125           slash preceding foo is a separator and not a slash for the path,
4126           a URL as file://localhost//foo must be valid as well, to refer to
4127           the same file with an absolute path.
4128        */
4129
4130        if(ptr[1] && ('/' == ptr[1]))
4131          /* if there was two slashes, we skip the first one as that is then
4132             used truly as a separator */
4133          ptr++;
4134
4135        /* This cannot be made with strcpy, as the memory chunks overlap! */
4136        memmove(path, ptr, strlen(ptr)+1);
4137      }
4138    }
4139
4140    protop = "file"; /* protocol string */
4141  }
4142  else {
4143    /* clear path */
4144    char slashbuf[4];
4145    path[0]=0;
4146
4147    rc = sscanf(data->change.url,
4148                "%15[^\n:]:%3[/]%[^\n/?]%[^\n]",
4149                protobuf, slashbuf, conn->host.name, path);
4150    if(2 == rc) {
4151      failf(data, "Bad URL");
4152      return CURLE_URL_MALFORMAT;
4153    }
4154    if(3 > rc) {
4155
4156      /*
4157       * The URL was badly formatted, let's try the browser-style _without_
4158       * protocol specified like 'http://'.
4159       */
4160      rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
4161      if(1 > rc) {
4162        /*
4163         * We couldn't even get this format.
4164         * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
4165         * assigned, but the return value is EOF!
4166         */
4167#if defined(__DJGPP__) && (DJGPP_MINOR == 4)
4168        if(!(rc == -1 && *conn->host.name))
4169#endif
4170        {
4171          failf(data, "<url> malformed");
4172          return CURLE_URL_MALFORMAT;
4173        }
4174      }
4175
4176      /*
4177       * Since there was no protocol part specified in the URL use the
4178       * user-specified default protocol. If we weren't given a default make a
4179       * guess by matching some protocols against the host's outermost
4180       * sub-domain name. Finally if there was no match use HTTP.
4181       */
4182
4183      protop = data->set.str[STRING_DEFAULT_PROTOCOL];
4184      if(!protop) {
4185        /* Note: if you add a new protocol, please update the list in
4186         * lib/version.c too! */
4187        if(checkprefix("FTP.", conn->host.name))
4188          protop = "ftp";
4189        else if(checkprefix("DICT.", conn->host.name))
4190          protop = "DICT";
4191        else if(checkprefix("LDAP.", conn->host.name))
4192          protop = "LDAP";
4193        else if(checkprefix("IMAP.", conn->host.name))
4194          protop = "IMAP";
4195        else if(checkprefix("SMTP.", conn->host.name))
4196          protop = "smtp";
4197        else if(checkprefix("POP3.", conn->host.name))
4198          protop = "pop3";
4199        else
4200          protop = "http";
4201      }
4202
4203      *prot_missing = TRUE; /* not given in URL */
4204    }
4205    else {
4206      size_t s = strlen(slashbuf);
4207      protop = protobuf;
4208      if(s != 2) {
4209        infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
4210              s, s>1?"es":"");
4211
4212        if(data->change.url_alloc)
4213          free(data->change.url);
4214        /* repair the URL to use two slashes */
4215        data->change.url = aprintf("%s://%s%s",
4216                                   protobuf, conn->host.name, path);
4217        if(!data->change.url)
4218          return CURLE_OUT_OF_MEMORY;
4219        data->change.url_alloc = TRUE;
4220      }
4221    }
4222  }
4223
4224  /* We search for '?' in the host name (but only on the right side of a
4225   * @-letter to allow ?-letters in username and password) to handle things
4226   * like http://example.com?param= (notice the missing '/').
4227   */
4228  at = strchr(conn->host.name, '@');
4229  if(at)
4230    query = strchr(at+1, '?');
4231  else
4232    query = strchr(conn->host.name, '?');
4233
4234  if(query) {
4235    /* We must insert a slash before the '?'-letter in the URL. If the URL had
4236       a slash after the '?', that is where the path currently begins and the
4237       '?string' is still part of the host name.
4238
4239       We must move the trailing part from the host name and put it first in
4240       the path. And have it all prefixed with a slash.
4241    */
4242
4243    size_t hostlen = strlen(query);
4244    size_t pathlen = strlen(path);
4245
4246    /* move the existing path plus the zero byte forward, to make room for
4247       the host-name part */
4248    memmove(path+hostlen+1, path, pathlen+1);
4249
4250     /* now copy the trailing host part in front of the existing path */
4251    memcpy(path+1, query, hostlen);
4252
4253    path[0]='/'; /* prepend the missing slash */
4254    rebuild_url = TRUE;
4255
4256    *query=0; /* now cut off the hostname at the ? */
4257  }
4258  else if(!path[0]) {
4259    /* if there's no path set, use a single slash */
4260    strcpy(path, "/");
4261    rebuild_url = TRUE;
4262  }
4263
4264  /* If the URL is malformatted (missing a '/' after hostname before path) we
4265   * insert a slash here. The only letter except '/' we accept to start a path
4266   * is '?'.
4267   */
4268  if(path[0] == '?') {
4269    /* We need this function to deal with overlapping memory areas. We know
4270       that the memory area 'path' points to is 'urllen' bytes big and that
4271       is bigger than the path. Use +1 to move the zero byte too. */
4272    memmove(&path[1], path, strlen(path)+1);
4273    path[0] = '/';
4274    rebuild_url = TRUE;
4275  }
4276  else if(!data->set.path_as_is) {
4277    /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
4278    char *newp = Curl_dedotdotify(path);
4279    if(!newp)
4280      return CURLE_OUT_OF_MEMORY;
4281
4282    if(strcmp(newp, path)) {
4283      rebuild_url = TRUE;
4284      free(data->state.pathbuffer);
4285      data->state.pathbuffer = newp;
4286      data->state.path = newp;
4287      path = newp;
4288    }
4289    else
4290      free(newp);
4291  }
4292
4293  /*
4294   * "rebuild_url" means that one or more URL components have been modified so
4295   * we need to generate an updated full version.  We need the corrected URL
4296   * when communicating over HTTP proxy and we don't know at this point if
4297   * we're using a proxy or not.
4298   */
4299  if(rebuild_url) {
4300    char *reurl;
4301
4302    size_t plen = strlen(path); /* new path, should be 1 byte longer than
4303                                   the original */
4304    size_t urllen = strlen(data->change.url); /* original URL length */
4305
4306    size_t prefixlen = strlen(conn->host.name);
4307
4308    if(!*prot_missing)
4309      prefixlen += strlen(protop) + strlen("://");
4310
4311    reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
4312    if(!reurl)
4313      return CURLE_OUT_OF_MEMORY;
4314
4315    /* copy the prefix */
4316    memcpy(reurl, data->change.url, prefixlen);
4317
4318    /* append the trailing piece + zerobyte */
4319    memcpy(&reurl[prefixlen], path, plen + 1);
4320
4321    /* possible free the old one */
4322    if(data->change.url_alloc) {
4323      Curl_safefree(data->change.url);
4324      data->change.url_alloc = FALSE;
4325    }
4326
4327    infof(data, "Rebuilt URL to: %s\n", reurl);
4328
4329    data->change.url = reurl;
4330    data->change.url_alloc = TRUE; /* free this later */
4331  }
4332
4333  /*
4334   * Parse the login details from the URL and strip them out of
4335   * the host name
4336   */
4337  result = parse_url_login(data, conn, userp, passwdp, optionsp);
4338  if(result)
4339    return result;
4340
4341  if(conn->host.name[0] == '[') {
4342    /* This looks like an IPv6 address literal.  See if there is an address
4343       scope if there is no location header */
4344    char *percent = strchr(conn->host.name, '%');
4345    if(percent) {
4346      unsigned int identifier_offset = 3;
4347      char *endp;
4348      unsigned long scope;
4349      if(strncmp("%25", percent, 3) != 0) {
4350        infof(data,
4351              "Please URL encode %% as %%25, see RFC 6874.\n");
4352        identifier_offset = 1;
4353      }
4354      scope = strtoul(percent + identifier_offset, &endp, 10);
4355      if(*endp == ']') {
4356        /* The address scope was well formed.  Knock it out of the
4357           hostname. */
4358        memmove(percent, endp, strlen(endp)+1);
4359        conn->scope_id = (unsigned int)scope;
4360      }
4361      else {
4362        /* Zone identifier is not numeric */
4363#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
4364        char ifname[IFNAMSIZ + 2];
4365        char *square_bracket;
4366        unsigned int scopeidx = 0;
4367        strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
4368        /* Ensure nullbyte termination */
4369        ifname[IFNAMSIZ + 1] = '\0';
4370        square_bracket = strchr(ifname, ']');
4371        if(square_bracket) {
4372          /* Remove ']' */
4373          *square_bracket = '\0';
4374          scopeidx = if_nametoindex(ifname);
4375          if(scopeidx == 0) {
4376            infof(data, "Invalid network interface: %s; %s\n", ifname,
4377                  strerror(errno));
4378          }
4379        }
4380        if(scopeidx > 0) {
4381          char *p = percent + identifier_offset + strlen(ifname);
4382
4383          /* Remove zone identifier from hostname */
4384          memmove(percent, p, strlen(p) + 1);
4385          conn->scope_id = scopeidx;
4386        }
4387        else
4388#endif /* HAVE_NET_IF_H && IFNAMSIZ */
4389          infof(data, "Invalid IPv6 address format\n");
4390      }
4391    }
4392  }
4393
4394  if(data->set.scope_id)
4395    /* Override any scope that was set above.  */
4396    conn->scope_id = data->set.scope_id;
4397
4398  /* Remove the fragment part of the path. Per RFC 2396, this is always the
4399     last part of the URI. We are looking for the first '#' so that we deal
4400     gracefully with non conformant URI such as http://example.com#foo#bar. */
4401  fragment = strchr(path, '#');
4402  if(fragment) {
4403    *fragment = 0;
4404
4405    /* we know the path part ended with a fragment, so we know the full URL
4406       string does too and we need to cut it off from there so it isn't used
4407       over proxy */
4408    fragment = strchr(data->change.url, '#');
4409    if(fragment)
4410      *fragment = 0;
4411  }
4412
4413  /*
4414   * So if the URL was A://B/C#D,
4415   *   protop is A
4416   *   conn->host.name is B
4417   *   data->state.path is /C
4418   */
4419
4420  return findprotocol(data, conn, protop);
4421}
4422
4423/*
4424 * If we're doing a resumed transfer, we need to setup our stuff
4425 * properly.
4426 */
4427static CURLcode setup_range(struct Curl_easy *data)
4428{
4429  struct UrlState *s = &data->state;
4430  s->resume_from = data->set.set_resume_from;
4431  if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
4432    if(s->rangestringalloc)
4433      free(s->range);
4434
4435    if(s->resume_from)
4436      s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
4437    else
4438      s->range = strdup(data->set.str[STRING_SET_RANGE]);
4439
4440    s->rangestringalloc = (s->range) ? TRUE : FALSE;
4441
4442    if(!s->range)
4443      return CURLE_OUT_OF_MEMORY;
4444
4445    /* tell ourselves to fetch this range */
4446    s->use_range = TRUE;        /* enable range download */
4447  }
4448  else
4449    s->use_range = FALSE; /* disable range download */
4450
4451  return CURLE_OK;
4452}
4453
4454
4455/*
4456 * setup_connection_internals() -
4457 *
4458 * Setup connection internals specific to the requested protocol in the
4459 * Curl_easy. This is inited and setup before the connection is made but
4460 * is about the particular protocol that is to be used.
4461 *
4462 * This MUST get called after proxy magic has been figured out.
4463 */
4464static CURLcode setup_connection_internals(struct connectdata *conn)
4465{
4466  const struct Curl_handler * p;
4467  CURLcode result;
4468  struct Curl_easy *data = conn->data;
4469
4470  /* in some case in the multi state-machine, we go back to the CONNECT state
4471     and then a second (or third or...) call to this function will be made
4472     without doing a DISCONNECT or DONE in between (since the connection is
4473     yet in place) and therefore this function needs to first make sure
4474     there's no lingering previous data allocated. */
4475  Curl_free_request_state(data);
4476
4477  memset(&data->req, 0, sizeof(struct SingleRequest));
4478  data->req.maxdownload = -1;
4479
4480  conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
4481
4482  /* Perform setup complement if some. */
4483  p = conn->handler;
4484
4485  if(p->setup_connection) {
4486    result = (*p->setup_connection)(conn);
4487
4488    if(result)
4489      return result;
4490
4491    p = conn->handler;              /* May have changed. */
4492  }
4493
4494  if(conn->port < 0)
4495    /* we check for -1 here since if proxy was detected already, this
4496       was very likely already set to the proxy port */
4497    conn->port = p->defport;
4498
4499  return CURLE_OK;
4500}
4501
4502/*
4503 * Curl_free_request_state() should free temp data that was allocated in the
4504 * Curl_easy for this single request.
4505 */
4506
4507void Curl_free_request_state(struct Curl_easy *data)
4508{
4509  Curl_safefree(data->req.protop);
4510  Curl_safefree(data->req.newurl);
4511}
4512
4513
4514#ifndef CURL_DISABLE_PROXY
4515/****************************************************************
4516* Checks if the host is in the noproxy list. returns true if it matches
4517* and therefore the proxy should NOT be used.
4518****************************************************************/
4519static bool check_noproxy(const char* name, const char* no_proxy)
4520{
4521  /* no_proxy=domain1.dom,host.domain2.dom
4522   *   (a comma-separated list of hosts which should
4523   *   not be proxied, or an asterisk to override
4524   *   all proxy variables)
4525   */
4526  size_t tok_start;
4527  size_t tok_end;
4528  const char* separator = ", ";
4529  size_t no_proxy_len;
4530  size_t namelen;
4531  char *endptr;
4532
4533  if(no_proxy && no_proxy[0]) {
4534    if(Curl_raw_equal("*", no_proxy)) {
4535      return TRUE;
4536    }
4537
4538    /* NO_PROXY was specified and it wasn't just an asterisk */
4539
4540    no_proxy_len = strlen(no_proxy);
4541    endptr = strchr(name, ':');
4542    if(endptr)
4543      namelen = endptr - name;
4544    else
4545      namelen = strlen(name);
4546
4547    for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
4548      while(tok_start < no_proxy_len &&
4549            strchr(separator, no_proxy[tok_start]) != NULL) {
4550        /* Look for the beginning of the token. */
4551        ++tok_start;
4552      }
4553
4554      if(tok_start == no_proxy_len)
4555        break; /* It was all trailing separator chars, no more tokens. */
4556
4557      for(tok_end = tok_start; tok_end < no_proxy_len &&
4558            strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
4559        /* Look for the end of the token. */
4560        ;
4561
4562      /* To match previous behaviour, where it was necessary to specify
4563       * ".local.com" to prevent matching "notlocal.com", we will leave
4564       * the '.' off.
4565       */
4566      if(no_proxy[tok_start] == '.')
4567        ++tok_start;
4568
4569      if((tok_end - tok_start) <= namelen) {
4570        /* Match the last part of the name to the domain we are checking. */
4571        const char *checkn = name + namelen - (tok_end - tok_start);
4572        if(Curl_raw_nequal(no_proxy + tok_start, checkn,
4573                           tok_end - tok_start)) {
4574          if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
4575            /* We either have an exact match, or the previous character is a .
4576             * so it is within the same domain, so no proxy for this host.
4577             */
4578            return TRUE;
4579          }
4580        }
4581      } /* if((tok_end - tok_start) <= namelen) */
4582    } /* for(tok_start = 0; tok_start < no_proxy_len;
4583         tok_start = tok_end + 1) */
4584  } /* NO_PROXY was specified and it wasn't just an asterisk */
4585
4586  return FALSE;
4587}
4588
4589/****************************************************************
4590* Detect what (if any) proxy to use. Remember that this selects a host
4591* name and is not limited to HTTP proxies only.
4592* The returned pointer must be freed by the caller (unless NULL)
4593****************************************************************/
4594static char *detect_proxy(struct connectdata *conn)
4595{
4596  char *proxy = NULL;
4597
4598#ifndef CURL_DISABLE_HTTP
4599  /* If proxy was not specified, we check for default proxy environment
4600   * variables, to enable i.e Lynx compliance:
4601   *
4602   * http_proxy=http://some.server.dom:port/
4603   * https_proxy=http://some.server.dom:port/
4604   * ftp_proxy=http://some.server.dom:port/
4605   * no_proxy=domain1.dom,host.domain2.dom
4606   *   (a comma-separated list of hosts which should
4607   *   not be proxied, or an asterisk to override
4608   *   all proxy variables)
4609   * all_proxy=http://some.server.dom:port/
4610   *   (seems to exist for the CERN www lib. Probably
4611   *   the first to check for.)
4612   *
4613   * For compatibility, the all-uppercase versions of these variables are
4614   * checked if the lowercase versions don't exist.
4615   */
4616  char *no_proxy=NULL;
4617  char proxy_env[128];
4618
4619  no_proxy=curl_getenv("no_proxy");
4620  if(!no_proxy)
4621    no_proxy=curl_getenv("NO_PROXY");
4622
4623  if(!check_noproxy(conn->host.name, no_proxy)) {
4624    /* It was not listed as without proxy */
4625    const char *protop = conn->handler->scheme;
4626    char *envp = proxy_env;
4627    char *prox;
4628
4629    /* Now, build <protocol>_proxy and check for such a one to use */
4630    while(*protop)
4631      *envp++ = (char)tolower((int)*protop++);
4632
4633    /* append _proxy */
4634    strcpy(envp, "_proxy");
4635
4636    /* read the protocol proxy: */
4637    prox=curl_getenv(proxy_env);
4638
4639    /*
4640     * We don't try the uppercase version of HTTP_PROXY because of
4641     * security reasons:
4642     *
4643     * When curl is used in a webserver application
4644     * environment (cgi or php), this environment variable can
4645     * be controlled by the web server user by setting the
4646     * http header 'Proxy:' to some value.
4647     *
4648     * This can cause 'internal' http/ftp requests to be
4649     * arbitrarily redirected by any external attacker.
4650     */
4651    if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
4652      /* There was no lowercase variable, try the uppercase version: */
4653      Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
4654      prox=curl_getenv(proxy_env);
4655    }
4656
4657    if(prox)
4658      proxy = prox; /* use this */
4659    else {
4660      proxy = curl_getenv("all_proxy"); /* default proxy to use */
4661      if(!proxy)
4662        proxy=curl_getenv("ALL_PROXY");
4663    }
4664  } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
4665       non-proxy */
4666  free(no_proxy);
4667
4668#else /* !CURL_DISABLE_HTTP */
4669
4670  (void)conn;
4671#endif /* CURL_DISABLE_HTTP */
4672
4673  return proxy;
4674}
4675
4676/*
4677 * If this is supposed to use a proxy, we need to figure out the proxy
4678 * host name, so that we can re-use an existing connection
4679 * that may exist registered to the same proxy host.
4680 */
4681static CURLcode parse_proxy(struct Curl_easy *data,
4682                            struct connectdata *conn, char *proxy)
4683{
4684  char *prox_portno;
4685  char *endofprot;
4686
4687  /* We use 'proxyptr' to point to the proxy name from now on... */
4688  char *proxyptr;
4689  char *portptr;
4690  char *atsign;
4691
4692  /* We do the proxy host string parsing here. We want the host name and the
4693   * port name. Accept a protocol:// prefix
4694   */
4695
4696  /* Parse the protocol part if present */
4697  endofprot = strstr(proxy, "://");
4698  if(endofprot) {
4699    proxyptr = endofprot+3;
4700    if(checkprefix("socks5h", proxy))
4701      conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
4702    else if(checkprefix("socks5", proxy))
4703      conn->proxytype = CURLPROXY_SOCKS5;
4704    else if(checkprefix("socks4a", proxy))
4705      conn->proxytype = CURLPROXY_SOCKS4A;
4706    else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
4707      conn->proxytype = CURLPROXY_SOCKS4;
4708    /* Any other xxx:// : change to http proxy */
4709  }
4710  else
4711    proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
4712
4713  /* Is there a username and password given in this proxy url? */
4714  atsign = strchr(proxyptr, '@');
4715  if(atsign) {
4716    char *proxyuser = NULL;
4717    char *proxypasswd = NULL;
4718    CURLcode result =
4719      parse_login_details(proxyptr, atsign - proxyptr,
4720                          &proxyuser, &proxypasswd, NULL);
4721    if(!result) {
4722      /* found user and password, rip them out.  note that we are
4723         unescaping them, as there is otherwise no way to have a
4724         username or password with reserved characters like ':' in
4725         them. */
4726      Curl_safefree(conn->proxyuser);
4727      if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
4728        conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4729      else
4730        conn->proxyuser = strdup("");
4731
4732      if(!conn->proxyuser)
4733        result = CURLE_OUT_OF_MEMORY;
4734      else {
4735        Curl_safefree(conn->proxypasswd);
4736        if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
4737          conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4738        else
4739          conn->proxypasswd = strdup("");
4740
4741        if(!conn->proxypasswd)
4742          result = CURLE_OUT_OF_MEMORY;
4743      }
4744
4745      if(!result) {
4746        conn->bits.proxy_user_passwd = TRUE; /* enable it */
4747        atsign++; /* the right side of the @-letter */
4748
4749        proxyptr = atsign; /* now use this instead */
4750      }
4751    }
4752
4753    free(proxyuser);
4754    free(proxypasswd);
4755
4756    if(result)
4757      return result;
4758  }
4759
4760  /* start scanning for port number at this point */
4761  portptr = proxyptr;
4762
4763  /* detect and extract RFC6874-style IPv6-addresses */
4764  if(*proxyptr == '[') {
4765    char *ptr = ++proxyptr; /* advance beyond the initial bracket */
4766    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
4767      ptr++;
4768    if(*ptr == '%') {
4769      /* There might be a zone identifier */
4770      if(strncmp("%25", ptr, 3))
4771        infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
4772      ptr++;
4773      /* Allow unreserved characters as defined in RFC 3986 */
4774      while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
4775                     (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
4776        ptr++;
4777    }
4778    if(*ptr == ']')
4779      /* yeps, it ended nicely with a bracket as well */
4780      *ptr++ = 0;
4781    else
4782      infof(data, "Invalid IPv6 address format\n");
4783    portptr = ptr;
4784    /* Note that if this didn't end with a bracket, we still advanced the
4785     * proxyptr first, but I can't see anything wrong with that as no host
4786     * name nor a numeric can legally start with a bracket.
4787     */
4788  }
4789
4790  /* Get port number off proxy.server.com:1080 */
4791  prox_portno = strchr(portptr, ':');
4792  if(prox_portno) {
4793    char *endp = NULL;
4794    long port = 0;
4795    *prox_portno = 0x0; /* cut off number from host name */
4796    prox_portno ++;
4797    /* now set the local port number */
4798    port = strtol(prox_portno, &endp, 10);
4799    if((endp && *endp && (*endp != '/') && (*endp != ' ')) ||
4800       (port < 0) || (port > 65535)) {
4801      /* meant to detect for example invalid IPv6 numerical addresses without
4802         brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only
4803         because we then allow "URL style" with the number followed by a
4804         slash, used in curl test cases already. Space is also an acceptable
4805         terminating symbol. */
4806      infof(data, "No valid port number in proxy string (%s)\n",
4807            prox_portno);
4808    }
4809    else
4810      conn->port = port;
4811  }
4812  else {
4813    if(proxyptr[0]=='/')
4814      /* If the first character in the proxy string is a slash, fail
4815         immediately. The following code will otherwise clear the string which
4816         will lead to code running as if no proxy was set! */
4817      return CURLE_COULDNT_RESOLVE_PROXY;
4818
4819    /* without a port number after the host name, some people seem to use
4820       a slash so we strip everything from the first slash */
4821    atsign = strchr(proxyptr, '/');
4822    if(atsign)
4823      *atsign = '\0'; /* cut off path part from host name */
4824
4825    if(data->set.proxyport)
4826      /* None given in the proxy string, then get the default one if it is
4827         given */
4828      conn->port = data->set.proxyport;
4829  }
4830
4831  /* now, clone the cleaned proxy host name */
4832  conn->proxy.rawalloc = strdup(proxyptr);
4833  conn->proxy.name = conn->proxy.rawalloc;
4834
4835  if(!conn->proxy.rawalloc)
4836    return CURLE_OUT_OF_MEMORY;
4837
4838  return CURLE_OK;
4839}
4840
4841/*
4842 * Extract the user and password from the authentication string
4843 */
4844static CURLcode parse_proxy_auth(struct Curl_easy *data,
4845                                 struct connectdata *conn)
4846{
4847  char proxyuser[MAX_CURL_USER_LENGTH]="";
4848  char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
4849
4850  if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
4851    strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
4852            MAX_CURL_USER_LENGTH);
4853    proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
4854  }
4855  if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
4856    strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
4857            MAX_CURL_PASSWORD_LENGTH);
4858    proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
4859  }
4860
4861  conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
4862  if(!conn->proxyuser)
4863    return CURLE_OUT_OF_MEMORY;
4864
4865  conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
4866  if(!conn->proxypasswd)
4867    return CURLE_OUT_OF_MEMORY;
4868
4869  return CURLE_OK;
4870}
4871#endif /* CURL_DISABLE_PROXY */
4872
4873/*
4874 * parse_url_login()
4875 *
4876 * Parse the login details (user name, password and options) from the URL and
4877 * strip them out of the host name
4878 *
4879 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
4880 *         conn->host.name
4881 *
4882 * Outputs: (almost :- all currently undefined)
4883 *          conn->bits.user_passwd  - non-zero if non-default passwords exist
4884 *          user                    - non-zero length if defined
4885 *          passwd                  - non-zero length if defined
4886 *          options                 - non-zero length if defined
4887 *          conn->host.name         - remove user name and password
4888 */
4889static CURLcode parse_url_login(struct Curl_easy *data,
4890                                struct connectdata *conn,
4891                                char **user, char **passwd, char **options)
4892{
4893  CURLcode result = CURLE_OK;
4894  char *userp = NULL;
4895  char *passwdp = NULL;
4896  char *optionsp = NULL;
4897
4898  /* At this point, we're hoping all the other special cases have
4899   * been taken care of, so conn->host.name is at most
4900   *    [user[:password][;options]]@]hostname
4901   *
4902   * We need somewhere to put the embedded details, so do that first.
4903   */
4904
4905  char *ptr = strchr(conn->host.name, '@');
4906  char *login = conn->host.name;
4907
4908  DEBUGASSERT(!**user);
4909  DEBUGASSERT(!**passwd);
4910  DEBUGASSERT(!**options);
4911
4912  if(!ptr)
4913    goto out;
4914
4915  /* We will now try to extract the
4916   * possible login information in a string like:
4917   * ftp://user:password@ftp.my.site:8021/README */
4918  conn->host.name = ++ptr;
4919
4920  /* So the hostname is sane.  Only bother interpreting the
4921   * results if we could care.  It could still be wasted
4922   * work because it might be overtaken by the programmatically
4923   * set user/passwd, but doing that first adds more cases here :-(
4924   */
4925
4926  if(data->set.use_netrc == CURL_NETRC_REQUIRED)
4927    goto out;
4928
4929  /* We could use the login information in the URL so extract it */
4930  result = parse_login_details(login, ptr - login - 1,
4931                               &userp, &passwdp, &optionsp);
4932  if(result)
4933    goto out;
4934
4935  if(userp) {
4936    char *newname;
4937
4938    /* We have a user in the URL */
4939    conn->bits.userpwd_in_url = TRUE;
4940    conn->bits.user_passwd = TRUE; /* enable user+password */
4941
4942    /* Decode the user */
4943    newname = curl_easy_unescape(data, userp, 0, NULL);
4944    if(!newname) {
4945      result = CURLE_OUT_OF_MEMORY;
4946      goto out;
4947    }
4948
4949    free(*user);
4950    *user = newname;
4951  }
4952
4953  if(passwdp) {
4954    /* We have a password in the URL so decode it */
4955    char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
4956    if(!newpasswd) {
4957      result = CURLE_OUT_OF_MEMORY;
4958      goto out;
4959    }
4960
4961    free(*passwd);
4962    *passwd = newpasswd;
4963  }
4964
4965  if(optionsp) {
4966    /* We have an options list in the URL so decode it */
4967    char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
4968    if(!newoptions) {
4969      result = CURLE_OUT_OF_MEMORY;
4970      goto out;
4971    }
4972
4973    free(*options);
4974    *options = newoptions;
4975  }
4976
4977
4978  out:
4979
4980  free(userp);
4981  free(passwdp);
4982  free(optionsp);
4983
4984  return result;
4985}
4986
4987/*
4988 * parse_login_details()
4989 *
4990 * This is used to parse a login string for user name, password and options in
4991 * the following formats:
4992 *
4993 *   user
4994 *   user:password
4995 *   user:password;options
4996 *   user;options
4997 *   user;options:password
4998 *   :password
4999 *   :password;options
5000 *   ;options
5001 *   ;options:password
5002 *
5003 * Parameters:
5004 *
5005 * login    [in]     - The login string.
5006 * len      [in]     - The length of the login string.
5007 * userp    [in/out] - The address where a pointer to newly allocated memory
5008 *                     holding the user will be stored upon completion.
5009 * passdwp  [in/out] - The address where a pointer to newly allocated memory
5010 *                     holding the password will be stored upon completion.
5011 * optionsp [in/out] - The address where a pointer to newly allocated memory
5012 *                     holding the options will be stored upon completion.
5013 *
5014 * Returns CURLE_OK on success.
5015 */
5016static CURLcode parse_login_details(const char *login, const size_t len,
5017                                    char **userp, char **passwdp,
5018                                    char **optionsp)
5019{
5020  CURLcode result = CURLE_OK;
5021  char *ubuf = NULL;
5022  char *pbuf = NULL;
5023  char *obuf = NULL;
5024  const char *psep = NULL;
5025  const char *osep = NULL;
5026  size_t ulen;
5027  size_t plen;
5028  size_t olen;
5029
5030  /* Attempt to find the password separator */
5031  if(passwdp) {
5032    psep = strchr(login, ':');
5033
5034    /* Within the constraint of the login string */
5035    if(psep >= login + len)
5036      psep = NULL;
5037  }
5038
5039  /* Attempt to find the options separator */
5040  if(optionsp) {
5041    osep = strchr(login, ';');
5042
5043    /* Within the constraint of the login string */
5044    if(osep >= login + len)
5045      osep = NULL;
5046  }
5047
5048  /* Calculate the portion lengths */
5049  ulen = (psep ?
5050          (size_t)(osep && psep > osep ? osep - login : psep - login) :
5051          (osep ? (size_t)(osep - login) : len));
5052  plen = (psep ?
5053          (osep && osep > psep ? (size_t)(osep - psep) :
5054                                 (size_t)(login + len - psep)) - 1 : 0);
5055  olen = (osep ?
5056          (psep && psep > osep ? (size_t)(psep - osep) :
5057                                 (size_t)(login + len - osep)) - 1 : 0);
5058
5059  /* Allocate the user portion buffer */
5060  if(userp && ulen) {
5061    ubuf = malloc(ulen + 1);
5062    if(!ubuf)
5063      result = CURLE_OUT_OF_MEMORY;
5064  }
5065
5066  /* Allocate the password portion buffer */
5067  if(!result && passwdp && plen) {
5068    pbuf = malloc(plen + 1);
5069    if(!pbuf) {
5070      free(ubuf);
5071      result = CURLE_OUT_OF_MEMORY;
5072    }
5073  }
5074
5075  /* Allocate the options portion buffer */
5076  if(!result && optionsp && olen) {
5077    obuf = malloc(olen + 1);
5078    if(!obuf) {
5079      free(pbuf);
5080      free(ubuf);
5081      result = CURLE_OUT_OF_MEMORY;
5082    }
5083  }
5084
5085  if(!result) {
5086    /* Store the user portion if necessary */
5087    if(ubuf) {
5088      memcpy(ubuf, login, ulen);
5089      ubuf[ulen] = '\0';
5090      Curl_safefree(*userp);
5091      *userp = ubuf;
5092    }
5093
5094    /* Store the password portion if necessary */
5095    if(pbuf) {
5096      memcpy(pbuf, psep + 1, plen);
5097      pbuf[plen] = '\0';
5098      Curl_safefree(*passwdp);
5099      *passwdp = pbuf;
5100    }
5101
5102    /* Store the options portion if necessary */
5103    if(obuf) {
5104      memcpy(obuf, osep + 1, olen);
5105      obuf[olen] = '\0';
5106      Curl_safefree(*optionsp);
5107      *optionsp = obuf;
5108    }
5109  }
5110
5111  return result;
5112}
5113
5114/*************************************************************
5115 * Figure out the remote port number and fix it in the URL
5116 *
5117 * No matter if we use a proxy or not, we have to figure out the remote
5118 * port number of various reasons.
5119 *
5120 * To be able to detect port number flawlessly, we must not confuse them
5121 * IPv6-specified addresses in the [0::1] style. (RFC2732)
5122 *
5123 * The conn->host.name is currently [user:passwd@]host[:port] where host
5124 * could be a hostname, IPv4 address or IPv6 address.
5125 *
5126 * The port number embedded in the URL is replaced, if necessary.
5127 *************************************************************/
5128static CURLcode parse_remote_port(struct Curl_easy *data,
5129                                  struct connectdata *conn)
5130{
5131  char *portptr;
5132  char endbracket;
5133
5134  /* Note that at this point, the IPv6 address cannot contain any scope
5135     suffix as that has already been removed in the parseurlandfillconn()
5136     function */
5137  if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
5138                  &endbracket)) &&
5139     (']' == endbracket)) {
5140    /* this is a RFC2732-style specified IP-address */
5141    conn->bits.ipv6_ip = TRUE;
5142
5143    conn->host.name++; /* skip over the starting bracket */
5144    portptr = strchr(conn->host.name, ']');
5145    if(portptr) {
5146      *portptr++ = '\0'; /* zero terminate, killing the bracket */
5147      if(':' != *portptr)
5148        portptr = NULL; /* no port number available */
5149    }
5150  }
5151  else {
5152#ifdef ENABLE_IPV6
5153    struct in6_addr in6;
5154    if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
5155      /* This is a numerical IPv6 address, meaning this is a wrongly formatted
5156         URL */
5157      failf(data, "IPv6 numerical address used in URL without brackets");
5158      return CURLE_URL_MALFORMAT;
5159    }
5160#endif
5161
5162    portptr = strrchr(conn->host.name, ':');
5163  }
5164
5165  if(data->set.use_port && data->state.allow_port) {
5166    /* if set, we use this and ignore the port possibly given in the URL */
5167    conn->remote_port = (unsigned short)data->set.use_port;
5168    if(portptr)
5169      *portptr = '\0'; /* cut off the name there anyway - if there was a port
5170                      number - since the port number is to be ignored! */
5171    if(conn->bits.httpproxy) {
5172      /* we need to create new URL with the new port number */
5173      char *url;
5174      char type[12]="";
5175
5176      if(conn->bits.type_set)
5177        snprintf(type, sizeof(type), ";type=%c",
5178                 data->set.prefer_ascii?'A':
5179                 (data->set.ftp_list_only?'D':'I'));
5180
5181      /*
5182       * This synthesized URL isn't always right--suffixes like ;type=A are
5183       * stripped off. It would be better to work directly from the original
5184       * URL and simply replace the port part of it.
5185       */
5186      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
5187                    conn->bits.ipv6_ip?"[":"", conn->host.name,
5188                    conn->bits.ipv6_ip?"]":"", conn->remote_port,
5189                    data->state.slash_removed?"/":"", data->state.path,
5190                    type);
5191      if(!url)
5192        return CURLE_OUT_OF_MEMORY;
5193
5194      if(data->change.url_alloc) {
5195        Curl_safefree(data->change.url);
5196        data->change.url_alloc = FALSE;
5197      }
5198
5199      data->change.url = url;
5200      data->change.url_alloc = TRUE;
5201    }
5202  }
5203  else if(portptr) {
5204    /* no CURLOPT_PORT given, extract the one from the URL */
5205
5206    char *rest;
5207    long port;
5208
5209    port=strtol(portptr+1, &rest, 10);  /* Port number must be decimal */
5210
5211    if((port < 0) || (port > 0xffff)) {
5212      /* Single unix standard says port numbers are 16 bits long */
5213      failf(data, "Port number out of range");
5214      return CURLE_URL_MALFORMAT;
5215    }
5216
5217    else if(rest != &portptr[1]) {
5218      *portptr = '\0'; /* cut off the name there */
5219      conn->remote_port = curlx_ultous(port);
5220    }
5221    else
5222      /* Browser behavior adaptation. If there's a colon with no digits after,
5223         just cut off the name there which makes us ignore the colon and just
5224         use the default port. Firefox and Chrome both do that. */
5225      *portptr = '\0';
5226  }
5227
5228  /* only if remote_port was not already parsed off the URL we use the
5229     default port number */
5230  if(conn->remote_port < 0)
5231    conn->remote_port = (unsigned short)conn->given->defport;
5232
5233  return CURLE_OK;
5234}
5235
5236/*
5237 * Override the login details from the URL with that in the CURLOPT_USERPWD
5238 * option or a .netrc file, if applicable.
5239 */
5240static CURLcode override_login(struct Curl_easy *data,
5241                               struct connectdata *conn,
5242                               char **userp, char **passwdp, char **optionsp)
5243{
5244  if(data->set.str[STRING_USERNAME]) {
5245    free(*userp);
5246    *userp = strdup(data->set.str[STRING_USERNAME]);
5247    if(!*userp)
5248      return CURLE_OUT_OF_MEMORY;
5249  }
5250
5251  if(data->set.str[STRING_PASSWORD]) {
5252    free(*passwdp);
5253    *passwdp = strdup(data->set.str[STRING_PASSWORD]);
5254    if(!*passwdp)
5255      return CURLE_OUT_OF_MEMORY;
5256  }
5257
5258  if(data->set.str[STRING_OPTIONS]) {
5259    free(*optionsp);
5260    *optionsp = strdup(data->set.str[STRING_OPTIONS]);
5261    if(!*optionsp)
5262      return CURLE_OUT_OF_MEMORY;
5263  }
5264
5265  conn->bits.netrc = FALSE;
5266  if(data->set.use_netrc != CURL_NETRC_IGNORED) {
5267    int ret = Curl_parsenetrc(conn->host.name,
5268                              userp, passwdp,
5269                              data->set.str[STRING_NETRC_FILE]);
5270    if(ret > 0) {
5271      infof(data, "Couldn't find host %s in the "
5272            DOT_CHAR "netrc file; using defaults\n",
5273            conn->host.name);
5274    }
5275    else if(ret < 0) {
5276      return CURLE_OUT_OF_MEMORY;
5277    }
5278    else {
5279      /* set bits.netrc TRUE to remember that we got the name from a .netrc
5280         file, so that it is safe to use even if we followed a Location: to a
5281         different host or similar. */
5282      conn->bits.netrc = TRUE;
5283
5284      conn->bits.user_passwd = TRUE; /* enable user+password */
5285    }
5286  }
5287
5288  return CURLE_OK;
5289}
5290
5291/*
5292 * Set the login details so they're available in the connection
5293 */
5294static CURLcode set_login(struct connectdata *conn,
5295                          const char *user, const char *passwd,
5296                          const char *options)
5297{
5298  CURLcode result = CURLE_OK;
5299
5300  /* If our protocol needs a password and we have none, use the defaults */
5301  if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
5302    /* Store the default user */
5303    conn->user = strdup(CURL_DEFAULT_USER);
5304
5305    /* Store the default password */
5306    if(conn->user)
5307      conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
5308    else
5309      conn->passwd = NULL;
5310
5311    /* This is the default password, so DON'T set conn->bits.user_passwd */
5312  }
5313  else {
5314    /* Store the user, zero-length if not set */
5315    conn->user = strdup(user);
5316
5317    /* Store the password (only if user is present), zero-length if not set */
5318    if(conn->user)
5319      conn->passwd = strdup(passwd);
5320    else
5321      conn->passwd = NULL;
5322  }
5323
5324  if(!conn->user || !conn->passwd)
5325    result = CURLE_OUT_OF_MEMORY;
5326
5327  /* Store the options, null if not set */
5328  if(!result && options[0]) {
5329    conn->options = strdup(options);
5330
5331    if(!conn->options)
5332      result = CURLE_OUT_OF_MEMORY;
5333  }
5334
5335  return result;
5336}
5337
5338/*
5339 * Parses a "host:port" string to connect to.
5340 * The hostname and the port may be empty; in this case, NULL is returned for
5341 * the hostname and -1 for the port.
5342 */
5343static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
5344                                           const char *host,
5345                                           char **hostname_result,
5346                                           int *port_result)
5347{
5348  char *host_dup;
5349  char *hostptr;
5350  char *host_portno;
5351  char *portptr;
5352  int port = -1;
5353
5354  *hostname_result = NULL;
5355  *port_result = -1;
5356
5357  if(!host || !*host)
5358    return CURLE_OK;
5359
5360  host_dup = strdup(host);
5361  if(!host_dup)
5362    return CURLE_OUT_OF_MEMORY;
5363
5364  hostptr = host_dup;
5365
5366  /* start scanning for port number at this point */
5367  portptr = hostptr;
5368
5369  /* detect and extract RFC6874-style IPv6-addresses */
5370  if(*hostptr == '[') {
5371    char *ptr = ++hostptr; /* advance beyond the initial bracket */
5372    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
5373      ptr++;
5374    if(*ptr == '%') {
5375      /* There might be a zone identifier */
5376      if(strncmp("%25", ptr, 3))
5377        infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
5378      ptr++;
5379      /* Allow unreserved characters as defined in RFC 3986 */
5380      while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
5381                     (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
5382        ptr++;
5383    }
5384    if(*ptr == ']')
5385      /* yeps, it ended nicely with a bracket as well */
5386      *ptr++ = '\0';
5387    else
5388      infof(data, "Invalid IPv6 address format\n");
5389    portptr = ptr;
5390    /* Note that if this didn't end with a bracket, we still advanced the
5391     * hostptr first, but I can't see anything wrong with that as no host
5392     * name nor a numeric can legally start with a bracket.
5393     */
5394  }
5395
5396  /* Get port number off server.com:1080 */
5397  host_portno = strchr(portptr, ':');
5398  if(host_portno) {
5399    char *endp = NULL;
5400    *host_portno = '\0'; /* cut off number from host name */
5401    host_portno++;
5402    if(*host_portno) {
5403      long portparse = strtol(host_portno, &endp, 10);
5404      if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
5405        infof(data, "No valid port number in connect to host string (%s)\n",
5406              host_portno);
5407        hostptr = NULL;
5408        port = -1;
5409      }
5410      else
5411        port = (int)portparse; /* we know it will fit */
5412    }
5413  }
5414
5415  /* now, clone the cleaned host name */
5416  if(hostptr) {
5417    *hostname_result = strdup(hostptr);
5418    if(!*hostname_result) {
5419      free(host_dup);
5420      return CURLE_OUT_OF_MEMORY;
5421    }
5422  }
5423
5424  *port_result = port;
5425
5426  free(host_dup);
5427  return CURLE_OK;
5428}
5429
5430/*
5431 * Parses one "connect to" string in the form:
5432 * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT".
5433 */
5434static CURLcode parse_connect_to_string(struct Curl_easy *data,
5435                                        struct connectdata *conn,
5436                                        const char *conn_to_host,
5437                                        char **host_result,
5438                                        int *port_result)
5439{
5440  CURLcode result = CURLE_OK;
5441  const char *ptr = conn_to_host;
5442  int host_match = FALSE;
5443  int port_match = FALSE;
5444
5445  if(*ptr == ':') {
5446    /* an empty hostname always matches */
5447    host_match = TRUE;
5448    ptr++;
5449  }
5450  else {
5451    /* check whether the URL's hostname matches */
5452    size_t hostname_to_match_len;
5453    char *hostname_to_match = aprintf("%s%s%s",
5454                                      conn->bits.ipv6_ip ? "[" : "",
5455                                      conn->host.name,
5456                                      conn->bits.ipv6_ip ? "]" : "");
5457    if(!hostname_to_match)
5458      return CURLE_OUT_OF_MEMORY;
5459    hostname_to_match_len = strlen(hostname_to_match);
5460    host_match = curl_strnequal(ptr, hostname_to_match, hostname_to_match_len);
5461    free(hostname_to_match);
5462    ptr += hostname_to_match_len;
5463
5464    host_match = host_match && *ptr == ':';
5465    ptr++;
5466  }
5467
5468  if(host_match) {
5469    if(*ptr == ':') {
5470      /* an empty port always matches */
5471      port_match = TRUE;
5472      ptr++;
5473    }
5474    else {
5475      /* check whether the URL's port matches */
5476      char *ptr_next = strchr(ptr, ':');
5477      if(ptr_next) {
5478        char *endp = NULL;
5479        long port_to_match = strtol(ptr, &endp, 10);
5480        if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
5481          port_match = TRUE;
5482          ptr = ptr_next + 1;
5483        }
5484      }
5485    }
5486  }
5487
5488  if(host_match && port_match) {
5489    /* parse the hostname and port to connect to */
5490    result = parse_connect_to_host_port(data, ptr, host_result, port_result);
5491  }
5492
5493  return result;
5494}
5495
5496/*
5497 * Processes all strings in the "connect to" slist, and uses the "connect
5498 * to host" and "connect to port" of the first string that matches.
5499 */
5500static CURLcode parse_connect_to_slist(struct Curl_easy *data,
5501                                       struct connectdata *conn,
5502                                       struct curl_slist *conn_to_host)
5503{
5504  CURLcode result = CURLE_OK;
5505  char *host = NULL;
5506  int port = 0;
5507
5508  while(conn_to_host && !host) {
5509    result = parse_connect_to_string(data, conn, conn_to_host->data,
5510                                     &host, &port);
5511    if(result)
5512      return result;
5513
5514    if(host && *host) {
5515      bool ipv6host;
5516      conn->conn_to_host.rawalloc = host;
5517      conn->conn_to_host.name = host;
5518      conn->bits.conn_to_host = TRUE;
5519
5520      ipv6host = strchr(host, ':') != NULL;
5521      infof(data, "Connecting to hostname: %s%s%s\n",
5522            ipv6host ? "[" : "", host, ipv6host ? "]" : "");
5523    }
5524    else {
5525      /* no "connect to host" */
5526      conn->bits.conn_to_host = FALSE;
5527      free(host);
5528    }
5529
5530    if(port >= 0) {
5531      conn->conn_to_port = port;
5532      conn->bits.conn_to_port = TRUE;
5533      infof(data, "Connecting to port: %d\n", port);
5534    }
5535    else {
5536      /* no "connect to port" */
5537      conn->bits.conn_to_port = FALSE;
5538    }
5539
5540    conn_to_host = conn_to_host->next;
5541  }
5542
5543  return result;
5544}
5545
5546/*************************************************************
5547 * Resolve the address of the server or proxy
5548 *************************************************************/
5549static CURLcode resolve_server(struct Curl_easy *data,
5550                               struct connectdata *conn,
5551                               bool *async)
5552{
5553  CURLcode result=CURLE_OK;
5554  long timeout_ms = Curl_timeleft(data, NULL, TRUE);
5555
5556  /*************************************************************
5557   * Resolve the name of the server or proxy
5558   *************************************************************/
5559  if(conn->bits.reuse)
5560    /* We're reusing the connection - no need to resolve anything, and
5561       fix_hostname() was called already in create_conn() for the re-use
5562       case. */
5563    *async = FALSE;
5564
5565  else {
5566    /* this is a fresh connect */
5567    int rc;
5568    struct Curl_dns_entry *hostaddr;
5569
5570#ifdef USE_UNIX_SOCKETS
5571    if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
5572      /* Unix domain sockets are local. The host gets ignored, just use the
5573       * specified domain socket address. Do not cache "DNS entries". There is
5574       * no DNS involved and we already have the filesystem path available */
5575      const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
5576
5577      hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
5578      if(!hostaddr)
5579        result = CURLE_OUT_OF_MEMORY;
5580      else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
5581        hostaddr->inuse++;
5582      else {
5583        /* Long paths are not supported for now */
5584        if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
5585          failf(data, "Unix socket path too long: '%s'", path);
5586          result = CURLE_COULDNT_RESOLVE_HOST;
5587        }
5588        else
5589          result = CURLE_OUT_OF_MEMORY;
5590        free(hostaddr);
5591        hostaddr = NULL;
5592      }
5593    }
5594    else
5595#endif
5596    if(!conn->proxy.name || !*conn->proxy.name) {
5597      struct hostname *connhost;
5598      if(conn->bits.conn_to_host)
5599        connhost = &conn->conn_to_host;
5600      else
5601        connhost = &conn->host;
5602
5603      /* If not connecting via a proxy, extract the port from the URL, if it is
5604       * there, thus overriding any defaults that might have been set above. */
5605      if(conn->bits.conn_to_port)
5606        conn->port = conn->conn_to_port;
5607      else
5608        conn->port = conn->remote_port; /* it is the same port */
5609
5610      /* Resolve target host right on */
5611      rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
5612                               &hostaddr, timeout_ms);
5613      if(rc == CURLRESOLV_PENDING)
5614        *async = TRUE;
5615
5616      else if(rc == CURLRESOLV_TIMEDOUT)
5617        result = CURLE_OPERATION_TIMEDOUT;
5618
5619      else if(!hostaddr) {
5620        failf(data, "Couldn't resolve host '%s'", connhost->dispname);
5621        result =  CURLE_COULDNT_RESOLVE_HOST;
5622        /* don't return yet, we need to clean up the timeout first */
5623      }
5624    }
5625    else {
5626      /* This is a proxy that hasn't been resolved yet. */
5627
5628      /* resolve proxy */
5629      rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
5630                               &hostaddr, timeout_ms);
5631
5632      if(rc == CURLRESOLV_PENDING)
5633        *async = TRUE;
5634
5635      else if(rc == CURLRESOLV_TIMEDOUT)
5636        result = CURLE_OPERATION_TIMEDOUT;
5637
5638      else if(!hostaddr) {
5639        failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
5640        result = CURLE_COULDNT_RESOLVE_PROXY;
5641        /* don't return yet, we need to clean up the timeout first */
5642      }
5643    }
5644    DEBUGASSERT(conn->dns_entry == NULL);
5645    conn->dns_entry = hostaddr;
5646  }
5647
5648  return result;
5649}
5650
5651/*
5652 * Cleanup the connection just allocated before we can move along and use the
5653 * previously existing one.  All relevant data is copied over and old_conn is
5654 * ready for freeing once this function returns.
5655 */
5656static void reuse_conn(struct connectdata *old_conn,
5657                       struct connectdata *conn)
5658{
5659  free_fixed_hostname(&old_conn->proxy);
5660  free(old_conn->proxy.rawalloc);
5661
5662  /* free the SSL config struct from this connection struct as this was
5663     allocated in vain and is targeted for destruction */
5664  Curl_free_ssl_config(&old_conn->ssl_config);
5665
5666  conn->data = old_conn->data;
5667
5668  /* get the user+password information from the old_conn struct since it may
5669   * be new for this request even when we re-use an existing connection */
5670  conn->bits.user_passwd = old_conn->bits.user_passwd;
5671  if(conn->bits.user_passwd) {
5672    /* use the new user name and password though */
5673    Curl_safefree(conn->user);
5674    Curl_safefree(conn->passwd);
5675    conn->user = old_conn->user;
5676    conn->passwd = old_conn->passwd;
5677    old_conn->user = NULL;
5678    old_conn->passwd = NULL;
5679  }
5680
5681  conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
5682  if(conn->bits.proxy_user_passwd) {
5683    /* use the new proxy user name and proxy password though */
5684    Curl_safefree(conn->proxyuser);
5685    Curl_safefree(conn->proxypasswd);
5686    conn->proxyuser = old_conn->proxyuser;
5687    conn->proxypasswd = old_conn->proxypasswd;
5688    old_conn->proxyuser = NULL;
5689    old_conn->proxypasswd = NULL;
5690  }
5691
5692  /* host can change, when doing keepalive with a proxy or if the case is
5693     different this time etc */
5694  free_fixed_hostname(&conn->host);
5695  free_fixed_hostname(&conn->conn_to_host);
5696  Curl_safefree(conn->host.rawalloc);
5697  Curl_safefree(conn->conn_to_host.rawalloc);
5698  conn->host=old_conn->host;
5699  conn->bits.conn_to_host = old_conn->bits.conn_to_host;
5700  conn->conn_to_host = old_conn->conn_to_host;
5701  conn->bits.conn_to_port = old_conn->bits.conn_to_port;
5702  conn->conn_to_port = old_conn->conn_to_port;
5703
5704  /* persist connection info in session handle */
5705  Curl_persistconninfo(conn);
5706
5707  conn_reset_all_postponed_data(old_conn); /* free buffers */
5708  conn_reset_all_postponed_data(conn);     /* reset unprocessed data */
5709
5710  /* re-use init */
5711  conn->bits.reuse = TRUE; /* yes, we're re-using here */
5712
5713  Curl_safefree(old_conn->user);
5714  Curl_safefree(old_conn->passwd);
5715  Curl_safefree(old_conn->proxyuser);
5716  Curl_safefree(old_conn->proxypasswd);
5717  Curl_safefree(old_conn->localdev);
5718
5719  Curl_llist_destroy(old_conn->send_pipe, NULL);
5720  Curl_llist_destroy(old_conn->recv_pipe, NULL);
5721
5722  old_conn->send_pipe = NULL;
5723  old_conn->recv_pipe = NULL;
5724
5725  Curl_safefree(old_conn->master_buffer);
5726}
5727
5728/**
5729 * create_conn() sets up a new connectdata struct, or re-uses an already
5730 * existing one, and resolves host name.
5731 *
5732 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
5733 * response will be coming asynchronously. If *async is FALSE, the name is
5734 * already resolved.
5735 *
5736 * @param data The sessionhandle pointer
5737 * @param in_connect is set to the next connection data pointer
5738 * @param async is set TRUE when an async DNS resolution is pending
5739 * @see Curl_setup_conn()
5740 *
5741 * *NOTE* this function assigns the conn->data pointer!
5742 */
5743
5744static CURLcode create_conn(struct Curl_easy *data,
5745                            struct connectdata **in_connect,
5746                            bool *async)
5747{
5748  CURLcode result = CURLE_OK;
5749  struct connectdata *conn;
5750  struct connectdata *conn_temp = NULL;
5751  size_t urllen;
5752  char *user = NULL;
5753  char *passwd = NULL;
5754  char *options = NULL;
5755  bool reuse;
5756  char *proxy = NULL;
5757  bool prot_missing = FALSE;
5758  bool connections_available = TRUE;
5759  bool force_reuse = FALSE;
5760  bool waitpipe = FALSE;
5761  size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
5762  size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
5763
5764  *async = FALSE;
5765
5766  /*************************************************************
5767   * Check input data
5768   *************************************************************/
5769
5770  if(!data->change.url) {
5771    result = CURLE_URL_MALFORMAT;
5772    goto out;
5773  }
5774
5775  /* First, split up the current URL in parts so that we can use the
5776     parts for checking against the already present connections. In order
5777     to not have to modify everything at once, we allocate a temporary
5778     connection data struct and fill in for comparison purposes. */
5779  conn = allocate_conn(data);
5780
5781  if(!conn) {
5782    result = CURLE_OUT_OF_MEMORY;
5783    goto out;
5784  }
5785
5786  /* We must set the return variable as soon as possible, so that our
5787     parent can cleanup any possible allocs we may have done before
5788     any failure */
5789  *in_connect = conn;
5790
5791  /* This initing continues below, see the comment "Continue connectdata
5792   * initialization here" */
5793
5794  /***********************************************************
5795   * We need to allocate memory to store the path in. We get the size of the
5796   * full URL to be sure, and we need to make it at least 256 bytes since
5797   * other parts of the code will rely on this fact
5798   ***********************************************************/
5799#define LEAST_PATH_ALLOC 256
5800  urllen=strlen(data->change.url);
5801  if(urllen < LEAST_PATH_ALLOC)
5802    urllen=LEAST_PATH_ALLOC;
5803
5804  /*
5805   * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
5806   * 1 - an extra terminating zero
5807   * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
5808   */
5809
5810  Curl_safefree(data->state.pathbuffer);
5811  data->state.path = NULL;
5812
5813  data->state.pathbuffer = malloc(urllen+2);
5814  if(NULL == data->state.pathbuffer) {
5815    result = CURLE_OUT_OF_MEMORY; /* really bad error */
5816    goto out;
5817  }
5818  data->state.path = data->state.pathbuffer;
5819
5820  conn->host.rawalloc = malloc(urllen+2);
5821  if(NULL == conn->host.rawalloc) {
5822    Curl_safefree(data->state.pathbuffer);
5823    data->state.path = NULL;
5824    result = CURLE_OUT_OF_MEMORY;
5825    goto out;
5826  }
5827
5828  conn->host.name = conn->host.rawalloc;
5829  conn->host.name[0] = 0;
5830
5831  user = strdup("");
5832  passwd = strdup("");
5833  options = strdup("");
5834  if(!user || !passwd || !options) {
5835    result = CURLE_OUT_OF_MEMORY;
5836    goto out;
5837  }
5838
5839  result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
5840                               &options);
5841  if(result)
5842    goto out;
5843
5844  /*************************************************************
5845   * No protocol part in URL was used, add it!
5846   *************************************************************/
5847  if(prot_missing) {
5848    /* We're guessing prefixes here and if we're told to use a proxy or if
5849       we're gonna follow a Location: later or... then we need the protocol
5850       part added so that we have a valid URL. */
5851    char *reurl;
5852    char *ch_lower;
5853
5854    reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
5855
5856    if(!reurl) {
5857      result = CURLE_OUT_OF_MEMORY;
5858      goto out;
5859    }
5860
5861    /* Change protocol prefix to lower-case */
5862    for(ch_lower = reurl; *ch_lower != ':'; ch_lower++)
5863      *ch_lower = (char)TOLOWER(*ch_lower);
5864
5865    if(data->change.url_alloc) {
5866      Curl_safefree(data->change.url);
5867      data->change.url_alloc = FALSE;
5868    }
5869
5870    data->change.url = reurl;
5871    data->change.url_alloc = TRUE; /* free this later */
5872  }
5873
5874  /*************************************************************
5875   * If the protocol can't handle url query strings, then cut
5876   * off the unhandable part
5877   *************************************************************/
5878  if((conn->given->flags&PROTOPT_NOURLQUERY)) {
5879    char *path_q_sep = strchr(conn->data->state.path, '?');
5880    if(path_q_sep) {
5881      /* according to rfc3986, allow the query (?foo=bar)
5882         also on protocols that can't handle it.
5883
5884         cut the string-part after '?'
5885      */
5886
5887      /* terminate the string */
5888      path_q_sep[0] = 0;
5889    }
5890  }
5891
5892  if(data->set.str[STRING_BEARER]) {
5893    conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
5894    if(!conn->oauth_bearer) {
5895      result = CURLE_OUT_OF_MEMORY;
5896      goto out;
5897    }
5898  }
5899
5900#ifndef CURL_DISABLE_PROXY
5901  /*************************************************************
5902   * Extract the user and password from the authentication string
5903   *************************************************************/
5904  if(conn->bits.proxy_user_passwd) {
5905    result = parse_proxy_auth(data, conn);
5906    if(result)
5907      goto out;
5908  }
5909
5910  /*************************************************************
5911   * Detect what (if any) proxy to use
5912   *************************************************************/
5913  if(data->set.str[STRING_PROXY]) {
5914    proxy = strdup(data->set.str[STRING_PROXY]);
5915    /* if global proxy is set, this is it */
5916    if(NULL == proxy) {
5917      failf(data, "memory shortage");
5918      result = CURLE_OUT_OF_MEMORY;
5919      goto out;
5920    }
5921  }
5922
5923  if(data->set.str[STRING_NOPROXY] &&
5924     check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
5925    free(proxy);  /* proxy is in exception list */
5926    proxy = NULL;
5927  }
5928  else if(!proxy)
5929    proxy = detect_proxy(conn);
5930
5931#ifdef USE_UNIX_SOCKETS
5932  if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
5933    free(proxy);  /* Unix domain sockets cannot be proxied, so disable it */
5934    proxy = NULL;
5935  }
5936#endif
5937
5938  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
5939    free(proxy);  /* Don't bother with an empty proxy string or if the
5940                     protocol doesn't work with network */
5941    proxy = NULL;
5942  }
5943
5944  /***********************************************************************
5945   * If this is supposed to use a proxy, we need to figure out the proxy host
5946   * name, proxy type and port number, so that we can re-use an existing
5947   * connection that may exist registered to the same proxy host.
5948   ***********************************************************************/
5949  if(proxy) {
5950    result = parse_proxy(data, conn, proxy);
5951
5952    free(proxy); /* parse_proxy copies the proxy string */
5953    proxy = NULL;
5954
5955    if(result)
5956      goto out;
5957
5958    if((conn->proxytype == CURLPROXY_HTTP) ||
5959       (conn->proxytype == CURLPROXY_HTTP_1_0)) {
5960#ifdef CURL_DISABLE_HTTP
5961      /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
5962      result = CURLE_UNSUPPORTED_PROTOCOL;
5963      goto out;
5964#else
5965      /* force this connection's protocol to become HTTP if not already
5966         compatible - if it isn't tunneling through */
5967      if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
5968         !conn->bits.tunnel_proxy)
5969        conn->handler = &Curl_handler_http;
5970
5971      conn->bits.httpproxy = TRUE;
5972#endif
5973    }
5974    else {
5975      conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
5976      conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
5977    }
5978    conn->bits.proxy = TRUE;
5979  }
5980  else {
5981    /* we aren't using the proxy after all... */
5982    conn->bits.proxy = FALSE;
5983    conn->bits.httpproxy = FALSE;
5984    conn->bits.proxy_user_passwd = FALSE;
5985    conn->bits.tunnel_proxy = FALSE;
5986  }
5987
5988#endif /* CURL_DISABLE_PROXY */
5989
5990  /*************************************************************
5991   * If the protocol is using SSL and HTTP proxy is used, we set
5992   * the tunnel_proxy bit.
5993   *************************************************************/
5994  if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
5995    conn->bits.tunnel_proxy = TRUE;
5996
5997  /*************************************************************
5998   * Figure out the remote port number and fix it in the URL
5999   *************************************************************/
6000  result = parse_remote_port(data, conn);
6001  if(result)
6002    goto out;
6003
6004  /* Check for overridden login details and set them accordingly so they
6005     they are known when protocol->setup_connection is called! */
6006  result = override_login(data, conn, &user, &passwd, &options);
6007  if(result)
6008    goto out;
6009  result = set_login(conn, user, passwd, options);
6010  if(result)
6011    goto out;
6012
6013  /*************************************************************
6014   * Process the "connect to" linked list of hostname/port mappings.
6015   * Do this after the remote port number has been fixed in the URL.
6016   *************************************************************/
6017  result = parse_connect_to_slist(data, conn, data->set.connect_to);
6018  if(result)
6019    goto out;
6020
6021  /*************************************************************
6022   * IDN-fix the hostnames
6023   *************************************************************/
6024  fix_hostname(data, conn, &conn->host);
6025  if(conn->bits.conn_to_host)
6026    fix_hostname(data, conn, &conn->conn_to_host);
6027  if(conn->proxy.name && *conn->proxy.name)
6028    fix_hostname(data, conn, &conn->proxy);
6029
6030  /*************************************************************
6031   * Check whether the host and the "connect to host" are equal.
6032   * Do this after the hostnames have been IDN-fixed .
6033   *************************************************************/
6034  if(conn->bits.conn_to_host &&
6035      Curl_raw_equal(conn->conn_to_host.name, conn->host.name)) {
6036    conn->bits.conn_to_host = FALSE;
6037  }
6038
6039  /*************************************************************
6040   * Check whether the port and the "connect to port" are equal.
6041   * Do this after the remote port number has been fixed in the URL.
6042   *************************************************************/
6043  if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) {
6044    conn->bits.conn_to_port = FALSE;
6045  }
6046
6047  /*************************************************************
6048   * If the "connect to" feature is used with an HTTP proxy,
6049   * we set the tunnel_proxy bit.
6050   *************************************************************/
6051  if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
6052      conn->bits.httpproxy)
6053    conn->bits.tunnel_proxy = TRUE;
6054
6055  /*************************************************************
6056   * Setup internals depending on protocol. Needs to be done after
6057   * we figured out what/if proxy to use.
6058   *************************************************************/
6059  result = setup_connection_internals(conn);
6060  if(result)
6061    goto out;
6062
6063  conn->recv[FIRSTSOCKET] = Curl_recv_plain;
6064  conn->send[FIRSTSOCKET] = Curl_send_plain;
6065  conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
6066  conn->send[SECONDARYSOCKET] = Curl_send_plain;
6067
6068  conn->bits.tcp_fastopen = data->set.tcp_fastopen;
6069
6070  /***********************************************************************
6071   * file: is a special case in that it doesn't need a network connection
6072   ***********************************************************************/
6073#ifndef CURL_DISABLE_FILE
6074  if(conn->handler->flags & PROTOPT_NONETWORK) {
6075    bool done;
6076    /* this is supposed to be the connect function so we better at least check
6077       that the file is present here! */
6078    DEBUGASSERT(conn->handler->connect_it);
6079    result = conn->handler->connect_it(conn, &done);
6080
6081    /* Setup a "faked" transfer that'll do nothing */
6082    if(!result) {
6083      conn->data = data;
6084      conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
6085
6086      Curl_conncache_add_conn(data->state.conn_cache, conn);
6087
6088      /*
6089       * Setup whatever necessary for a resumed transfer
6090       */
6091      result = setup_range(data);
6092      if(result) {
6093        DEBUGASSERT(conn->handler->done);
6094        /* we ignore the return code for the protocol-specific DONE */
6095        (void)conn->handler->done(conn, result, FALSE);
6096        goto out;
6097      }
6098
6099      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
6100                          -1, NULL); /* no upload */
6101    }
6102
6103    /* since we skip do_init() */
6104    Curl_init_do(data, conn);
6105
6106    goto out;
6107  }
6108#endif
6109
6110  /* Get a cloned copy of the SSL config situation stored in the
6111     connection struct. But to get this going nicely, we must first make
6112     sure that the strings in the master copy are pointing to the correct
6113     strings in the session handle strings array!
6114
6115     Keep in mind that the pointers in the master copy are pointing to strings
6116     that will be freed as part of the Curl_easy struct, but all cloned
6117     copies will be separately allocated.
6118  */
6119  data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
6120  data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
6121  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
6122  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
6123  data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
6124  data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
6125  data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
6126  data->set.ssl.clientcert = data->set.str[STRING_CERT];
6127#ifdef USE_TLS_SRP
6128  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
6129  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
6130#endif
6131
6132  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
6133    result = CURLE_OUT_OF_MEMORY;
6134    goto out;
6135  }
6136
6137  prune_dead_connections(data);
6138
6139  /*************************************************************
6140   * Check the current list of connections to see if we can
6141   * re-use an already existing one or if we have to create a
6142   * new one.
6143   *************************************************************/
6144
6145  /* reuse_fresh is TRUE if we are told to use a new connection by force, but
6146     we only acknowledge this option if this is not a re-used connection
6147     already (which happens due to follow-location or during a HTTP
6148     authentication phase). */
6149  if(data->set.reuse_fresh && !data->state.this_is_a_follow)
6150    reuse = FALSE;
6151  else
6152    reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
6153
6154  /* If we found a reusable connection, we may still want to
6155     open a new connection if we are pipelining. */
6156  if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
6157    size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
6158    if(pipelen > 0) {
6159      infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
6160            conn_temp->connection_id, pipelen);
6161
6162      if(conn_temp->bundle->num_connections < max_host_connections &&
6163         data->state.conn_cache->num_connections < max_total_connections) {
6164        /* We want a new connection anyway */
6165        reuse = FALSE;
6166
6167        infof(data, "We can reuse, but we want a new connection anyway\n");
6168      }
6169    }
6170  }
6171
6172  if(reuse) {
6173    /*
6174     * We already have a connection for this, we got the former connection
6175     * in the conn_temp variable and thus we need to cleanup the one we
6176     * just allocated before we can move along and use the previously
6177     * existing one.
6178     */
6179    conn_temp->inuse = TRUE; /* mark this as being in use so that no other
6180                                handle in a multi stack may nick it */
6181    reuse_conn(conn, conn_temp);
6182    free(conn);          /* we don't need this anymore */
6183    conn = conn_temp;
6184    *in_connect = conn;
6185
6186    infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
6187          conn->connection_id,
6188          conn->bits.proxy?"proxy":"host",
6189          conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
6190  }
6191  else {
6192    /* We have decided that we want a new connection. However, we may not
6193       be able to do that if we have reached the limit of how many
6194       connections we are allowed to open. */
6195    struct connectbundle *bundle = NULL;
6196
6197    if(conn->handler->flags & PROTOPT_ALPN_NPN) {
6198      /* The protocol wants it, so set the bits if enabled in the easy handle
6199         (default) */
6200      if(data->set.ssl_enable_alpn)
6201        conn->bits.tls_enable_alpn = TRUE;
6202      if(data->set.ssl_enable_npn)
6203        conn->bits.tls_enable_npn = TRUE;
6204    }
6205
6206    if(waitpipe)
6207      /* There is a connection that *might* become usable for pipelining
6208         "soon", and we wait for that */
6209      connections_available = FALSE;
6210    else
6211      bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
6212
6213    if(max_host_connections > 0 && bundle &&
6214       (bundle->num_connections >= max_host_connections)) {
6215      struct connectdata *conn_candidate;
6216
6217      /* The bundle is full. Let's see if we can kill a connection. */
6218      conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
6219
6220      if(conn_candidate) {
6221        /* Set the connection's owner correctly, then kill it */
6222        conn_candidate->data = data;
6223        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
6224      }
6225      else {
6226        infof(data, "No more connections allowed to host: %d\n",
6227              max_host_connections);
6228        connections_available = FALSE;
6229      }
6230    }
6231
6232    if(connections_available &&
6233       (max_total_connections > 0) &&
6234       (data->state.conn_cache->num_connections >= max_total_connections)) {
6235      struct connectdata *conn_candidate;
6236
6237      /* The cache is full. Let's see if we can kill a connection. */
6238      conn_candidate = Curl_oldest_idle_connection(data);
6239
6240      if(conn_candidate) {
6241        /* Set the connection's owner correctly, then kill it */
6242        conn_candidate->data = data;
6243        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
6244      }
6245      else {
6246        infof(data, "No connections available in cache\n");
6247        connections_available = FALSE;
6248      }
6249    }
6250
6251    if(!connections_available) {
6252      infof(data, "No connections available.\n");
6253
6254      conn_free(conn);
6255      *in_connect = NULL;
6256
6257      result = CURLE_NO_CONNECTION_AVAILABLE;
6258      goto out;
6259    }
6260    else {
6261      /*
6262       * This is a brand new connection, so let's store it in the connection
6263       * cache of ours!
6264       */
6265      Curl_conncache_add_conn(data->state.conn_cache, conn);
6266    }
6267
6268#if defined(USE_NTLM)
6269    /* If NTLM is requested in a part of this connection, make sure we don't
6270       assume the state is fine as this is a fresh connection and NTLM is
6271       connection based. */
6272    if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6273       data->state.authhost.done) {
6274      infof(data, "NTLM picked AND auth done set, clear picked!\n");
6275      data->state.authhost.picked = CURLAUTH_NONE;
6276      data->state.authhost.done = FALSE;
6277    }
6278
6279    if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
6280       data->state.authproxy.done) {
6281      infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
6282      data->state.authproxy.picked = CURLAUTH_NONE;
6283      data->state.authproxy.done = FALSE;
6284    }
6285#endif
6286  }
6287
6288  /* Mark the connection as used */
6289  conn->inuse = TRUE;
6290
6291  /* Setup and init stuff before DO starts, in preparing for the transfer. */
6292  Curl_init_do(data, conn);
6293
6294  /*
6295   * Setup whatever necessary for a resumed transfer
6296   */
6297  result = setup_range(data);
6298  if(result)
6299    goto out;
6300
6301  /* Continue connectdata initialization here. */
6302
6303  /*
6304   * Inherit the proper values from the urldata struct AFTER we have arranged
6305   * the persistent connection stuff
6306   */
6307  conn->seek_func = data->set.seek_func;
6308  conn->seek_client = data->set.seek_client;
6309
6310  /*************************************************************
6311   * Resolve the address of the server or proxy
6312   *************************************************************/
6313  result = resolve_server(data, conn, async);
6314
6315  out:
6316
6317  free(options);
6318  free(passwd);
6319  free(user);
6320  free(proxy);
6321  return result;
6322}
6323
6324/* Curl_setup_conn() is called after the name resolve initiated in
6325 * create_conn() is all done.
6326 *
6327 * Curl_setup_conn() also handles reused connections
6328 *
6329 * conn->data MUST already have been setup fine (in create_conn)
6330 */
6331
6332CURLcode Curl_setup_conn(struct connectdata *conn,
6333                         bool *protocol_done)
6334{
6335  CURLcode result = CURLE_OK;
6336  struct Curl_easy *data = conn->data;
6337
6338  Curl_pgrsTime(data, TIMER_NAMELOOKUP);
6339
6340  if(conn->handler->flags & PROTOPT_NONETWORK) {
6341    /* nothing to setup when not using a network */
6342    *protocol_done = TRUE;
6343    return result;
6344  }
6345  *protocol_done = FALSE; /* default to not done */
6346
6347  /* set proxy_connect_closed to false unconditionally already here since it
6348     is used strictly to provide extra information to a parent function in the
6349     case of proxy CONNECT failures and we must make sure we don't have it
6350     lingering set from a previous invoke */
6351  conn->bits.proxy_connect_closed = FALSE;
6352
6353  /*
6354   * Set user-agent. Used for HTTP, but since we can attempt to tunnel
6355   * basically anything through a http proxy we can't limit this based on
6356   * protocol.
6357   */
6358  if(data->set.str[STRING_USERAGENT]) {
6359    Curl_safefree(conn->allocptr.uagent);
6360    conn->allocptr.uagent =
6361      aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
6362    if(!conn->allocptr.uagent)
6363      return CURLE_OUT_OF_MEMORY;
6364  }
6365
6366  data->req.headerbytecount = 0;
6367
6368#ifdef CURL_DO_LINEEND_CONV
6369  data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
6370#endif /* CURL_DO_LINEEND_CONV */
6371
6372  /* set start time here for timeout purposes in the connect procedure, it
6373     is later set again for the progress meter purpose */
6374  conn->now = Curl_tvnow();
6375
6376  if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
6377    conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
6378    result = Curl_connecthost(conn, conn->dns_entry);
6379    if(result)
6380      return result;
6381  }
6382  else {
6383    Curl_pgrsTime(data, TIMER_CONNECT);    /* we're connected already */
6384    Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
6385    conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
6386    *protocol_done = TRUE;
6387    Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
6388    Curl_verboseconnect(conn);
6389  }
6390
6391  conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
6392                               set this here perhaps a second time */
6393
6394#ifdef __EMX__
6395  /*
6396   * This check is quite a hack. We're calling _fsetmode to fix the problem
6397   * with fwrite converting newline characters (you get mangled text files,
6398   * and corrupted binary files when you download to stdout and redirect it to
6399   * a file).
6400   */
6401
6402  if((data->set.out)->_handle == NULL) {
6403    _fsetmode(stdout, "b");
6404  }
6405#endif
6406
6407  return result;
6408}
6409
6410CURLcode Curl_connect(struct Curl_easy *data,
6411                      struct connectdata **in_connect,
6412                      bool *asyncp,
6413                      bool *protocol_done)
6414{
6415  CURLcode result;
6416
6417  *asyncp = FALSE; /* assume synchronous resolves by default */
6418
6419  /* call the stuff that needs to be called */
6420  result = create_conn(data, in_connect, asyncp);
6421
6422  if(!result) {
6423    /* no error */
6424    if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
6425      /* pipelining */
6426      *protocol_done = TRUE;
6427    else if(!*asyncp) {
6428      /* DNS resolution is done: that's either because this is a reused
6429         connection, in which case DNS was unnecessary, or because DNS
6430         really did finish already (synch resolver/fast async resolve) */
6431      result = Curl_setup_conn(*in_connect, protocol_done);
6432    }
6433  }
6434
6435  if(result == CURLE_NO_CONNECTION_AVAILABLE) {
6436    *in_connect = NULL;
6437    return result;
6438  }
6439
6440  if(result && *in_connect) {
6441    /* We're not allowed to return failure with memory left allocated
6442       in the connectdata struct, free those here */
6443    Curl_disconnect(*in_connect, FALSE); /* close the connection */
6444    *in_connect = NULL;           /* return a NULL */
6445  }
6446
6447  return result;
6448}
6449
6450/*
6451 * Curl_init_do() inits the readwrite session. This is inited each time (in
6452 * the DO function before the protocol-specific DO functions are invoked) for
6453 * a transfer, sometimes multiple times on the same Curl_easy. Make sure
6454 * nothing in here depends on stuff that are setup dynamically for the
6455 * transfer.
6456 *
6457 * Allow this function to get called with 'conn' set to NULL.
6458 */
6459
6460CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
6461{
6462  struct SingleRequest *k = &data->req;
6463
6464  if(conn)
6465    conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
6466                                 * use */
6467
6468  data->state.done = FALSE; /* *_done() is not called yet */
6469  data->state.expect100header = FALSE;
6470
6471  if(data->set.opt_no_body)
6472    /* in HTTP lingo, no body means using the HEAD request... */
6473    data->set.httpreq = HTTPREQ_HEAD;
6474  else if(HTTPREQ_HEAD == data->set.httpreq)
6475    /* ... but if unset there really is no perfect method that is the
6476       "opposite" of HEAD but in reality most people probably think GET
6477       then. The important thing is that we can't let it remain HEAD if the
6478       opt_no_body is set FALSE since then we'll behave wrong when getting
6479       HTTP. */
6480    data->set.httpreq = HTTPREQ_GET;
6481
6482  k->start = Curl_tvnow(); /* start time */
6483  k->now = k->start;   /* current time is now */
6484  k->header = TRUE; /* assume header */
6485
6486  k->bytecount = 0;
6487
6488  k->buf = data->state.buffer;
6489  k->uploadbuf = data->state.uploadbuffer;
6490  k->hbufp = data->state.headerbuff;
6491  k->ignorebody=FALSE;
6492
6493  Curl_speedinit(data);
6494
6495  Curl_pgrsSetUploadCounter(data, 0);
6496  Curl_pgrsSetDownloadCounter(data, 0);
6497
6498  return CURLE_OK;
6499}
6500
6501/*
6502* get_protocol_family()
6503*
6504* This is used to return the protocol family for a given protocol.
6505*
6506* Parameters:
6507*
6508* protocol  [in]  - A single bit protocol identifier such as HTTP or HTTPS.
6509*
6510* Returns the family as a single bit protocol identifier.
6511*/
6512
6513unsigned int get_protocol_family(unsigned int protocol)
6514{
6515  unsigned int family;
6516
6517  switch(protocol) {
6518  case CURLPROTO_HTTP:
6519  case CURLPROTO_HTTPS:
6520    family = CURLPROTO_HTTP;
6521    break;
6522
6523  case CURLPROTO_FTP:
6524  case CURLPROTO_FTPS:
6525    family = CURLPROTO_FTP;
6526    break;
6527
6528  case CURLPROTO_SCP:
6529    family = CURLPROTO_SCP;
6530    break;
6531
6532  case CURLPROTO_SFTP:
6533    family = CURLPROTO_SFTP;
6534    break;
6535
6536  case CURLPROTO_TELNET:
6537    family = CURLPROTO_TELNET;
6538    break;
6539
6540  case CURLPROTO_LDAP:
6541  case CURLPROTO_LDAPS:
6542    family = CURLPROTO_LDAP;
6543    break;
6544
6545  case CURLPROTO_DICT:
6546    family = CURLPROTO_DICT;
6547    break;
6548
6549  case CURLPROTO_FILE:
6550    family = CURLPROTO_FILE;
6551    break;
6552
6553  case CURLPROTO_TFTP:
6554    family = CURLPROTO_TFTP;
6555    break;
6556
6557  case CURLPROTO_IMAP:
6558  case CURLPROTO_IMAPS:
6559    family = CURLPROTO_IMAP;
6560    break;
6561
6562  case CURLPROTO_POP3:
6563  case CURLPROTO_POP3S:
6564    family = CURLPROTO_POP3;
6565    break;
6566
6567  case CURLPROTO_SMTP:
6568  case CURLPROTO_SMTPS:
6569      family = CURLPROTO_SMTP;
6570      break;
6571
6572  case CURLPROTO_RTSP:
6573    family = CURLPROTO_RTSP;
6574    break;
6575
6576  case CURLPROTO_RTMP:
6577  case CURLPROTO_RTMPS:
6578    family = CURLPROTO_RTMP;
6579    break;
6580
6581  case CURLPROTO_RTMPT:
6582  case CURLPROTO_RTMPTS:
6583    family = CURLPROTO_RTMPT;
6584    break;
6585
6586  case CURLPROTO_RTMPE:
6587    family = CURLPROTO_RTMPE;
6588    break;
6589
6590  case CURLPROTO_RTMPTE:
6591    family = CURLPROTO_RTMPTE;
6592    break;
6593
6594  case CURLPROTO_GOPHER:
6595    family = CURLPROTO_GOPHER;
6596    break;
6597
6598  case CURLPROTO_SMB:
6599  case CURLPROTO_SMBS:
6600    family = CURLPROTO_SMB;
6601    break;
6602
6603  default:
6604      family = 0;
6605      break;
6606  }
6607
6608  return family;
6609}
6610