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