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