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