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