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