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