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