Annotation of embedaddon/curl/lib/url.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>