1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 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.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 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25#include "curl_setup.h" 26 27#ifdef HAVE_NETINET_IN_H 28#include <netinet/in.h> 29#endif 30#ifdef HAVE_NETDB_H 31#include <netdb.h> 32#endif 33#ifdef HAVE_ARPA_INET_H 34#include <arpa/inet.h> 35#endif 36#ifdef HAVE_NET_IF_H 37#include <net/if.h> 38#endif 39#ifdef HAVE_SYS_IOCTL_H 40#include <sys/ioctl.h> 41#endif 42 43#ifdef HAVE_SYS_PARAM_H 44#include <sys/param.h> 45#endif 46 47#include "urldata.h" 48#include <curl/curl.h> 49#include "transfer.h" 50#include "vtls/vtls.h" 51#include "url.h" 52#include "getinfo.h" 53#include "hostip.h" 54#include "share.h" 55#include "strdup.h" 56#include "progress.h" 57#include "easyif.h" 58#include "multiif.h" 59#include "select.h" 60#include "cfilters.h" 61#include "sendf.h" /* for failf function prototype */ 62#include "connect.h" /* for Curl_getconnectinfo */ 63#include "slist.h" 64#include "mime.h" 65#include "amigaos.h" 66#include "macos.h" 67#include "warnless.h" 68#include "sigpipe.h" 69#include "vssh/ssh.h" 70#include "setopt.h" 71#include "http_digest.h" 72#include "system_win32.h" 73#include "http2.h" 74#include "dynbuf.h" 75#include "altsvc.h" 76#include "hsts.h" 77 78#include "easy_lock.h" 79 80/* The last 3 #include files should be in this order */ 81#include "curl_printf.h" 82#include "curl_memory.h" 83#include "memdebug.h" 84 85/* true globals -- for curl_global_init() and curl_global_cleanup() */ 86static unsigned int initialized; 87static long easy_init_flags; 88 89#ifdef GLOBAL_INIT_IS_THREADSAFE 90 91static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT; 92#define global_init_lock() curl_simple_lock_lock(&s_lock) 93#define global_init_unlock() curl_simple_lock_unlock(&s_lock) 94 95#else 96 97#define global_init_lock() 98#define global_init_unlock() 99 100#endif 101 102/* 103 * strdup (and other memory functions) is redefined in complicated 104 * ways, but at this point it must be defined as the system-supplied strdup 105 * so the callback pointer is initialized correctly. 106 */ 107#if defined(_WIN32_WCE) 108#define system_strdup _strdup 109#elif !defined(HAVE_STRDUP) 110#define system_strdup Curl_strdup 111#else 112#define system_strdup strdup 113#endif 114 115#if defined(_MSC_VER) && defined(_DLL) 116# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ 117#endif 118 119/* 120 * If a memory-using function (like curl_getenv) is used before 121 * curl_global_init() is called, we need to have these pointers set already. 122 */ 123curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; 124curl_free_callback Curl_cfree = (curl_free_callback)free; 125curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; 126curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; 127curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; 128#if defined(_WIN32) && defined(UNICODE) 129curl_wcsdup_callback Curl_cwcsdup = Curl_wcsdup; 130#endif 131 132#if defined(_MSC_VER) && defined(_DLL) 133# pragma warning(default:4232) /* MSVC extension, dllimport identity */ 134#endif 135 136#ifdef DEBUGBUILD 137static char *leakpointer; 138#endif 139 140/** 141 * curl_global_init() globally initializes curl given a bitwise set of the 142 * different features of what to initialize. 143 */ 144static CURLcode global_init(long flags, bool memoryfuncs) 145{ 146 if(initialized++) 147 return CURLE_OK; 148 149 if(memoryfuncs) { 150 /* Setup the default memory functions here (again) */ 151 Curl_cmalloc = (curl_malloc_callback)malloc; 152 Curl_cfree = (curl_free_callback)free; 153 Curl_crealloc = (curl_realloc_callback)realloc; 154 Curl_cstrdup = (curl_strdup_callback)system_strdup; 155 Curl_ccalloc = (curl_calloc_callback)calloc; 156#if defined(_WIN32) && defined(UNICODE) 157 Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; 158#endif 159 } 160 161 if(Curl_trc_init()) { 162 DEBUGF(fprintf(stderr, "Error: Curl_trc_init failed\n")); 163 goto fail; 164 } 165 166 if(!Curl_ssl_init()) { 167 DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); 168 goto fail; 169 } 170 171 if(Curl_win32_init(flags)) { 172 DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); 173 goto fail; 174 } 175 176 if(Curl_amiga_init()) { 177 DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); 178 goto fail; 179 } 180 181 if(Curl_macos_init()) { 182 DEBUGF(fprintf(stderr, "Error: Curl_macos_init failed\n")); 183 goto fail; 184 } 185 186 if(Curl_resolver_global_init()) { 187 DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); 188 goto fail; 189 } 190 191 if(Curl_ssh_init()) { 192 DEBUGF(fprintf(stderr, "Error: Curl_ssh_init failed\n")); 193 goto fail; 194 } 195 196 easy_init_flags = flags; 197 198#ifdef DEBUGBUILD 199 if(getenv("CURL_GLOBAL_INIT")) 200 /* alloc data that will leak if *cleanup() is not called! */ 201 leakpointer = malloc(1); 202#endif 203 204 return CURLE_OK; 205 206fail: 207 initialized--; /* undo the increase */ 208 return CURLE_FAILED_INIT; 209} 210 211 212/** 213 * curl_global_init() globally initializes curl given a bitwise set of the 214 * different features of what to initialize. 215 */ 216CURLcode curl_global_init(long flags) 217{ 218 CURLcode result; 219 global_init_lock(); 220 221 result = global_init(flags, TRUE); 222 223 global_init_unlock(); 224 225 return result; 226} 227 228/* 229 * curl_global_init_mem() globally initializes curl and also registers the 230 * user provided callback routines. 231 */ 232CURLcode curl_global_init_mem(long flags, curl_malloc_callback m, 233 curl_free_callback f, curl_realloc_callback r, 234 curl_strdup_callback s, curl_calloc_callback c) 235{ 236 CURLcode result; 237 238 /* Invalid input, return immediately */ 239 if(!m || !f || !r || !s || !c) 240 return CURLE_FAILED_INIT; 241 242 global_init_lock(); 243 244 if(initialized) { 245 /* Already initialized, don't do it again, but bump the variable anyway to 246 work like curl_global_init() and require the same amount of cleanup 247 calls. */ 248 initialized++; 249 global_init_unlock(); 250 return CURLE_OK; 251 } 252 253 /* set memory functions before global_init() in case it wants memory 254 functions */ 255 Curl_cmalloc = m; 256 Curl_cfree = f; 257 Curl_cstrdup = s; 258 Curl_crealloc = r; 259 Curl_ccalloc = c; 260 261 /* Call the actual init function, but without setting */ 262 result = global_init(flags, FALSE); 263 264 global_init_unlock(); 265 266 return result; 267} 268 269/** 270 * curl_global_cleanup() globally cleanups curl, uses the value of 271 * "easy_init_flags" to determine what needs to be cleaned up and what doesn't. 272 */ 273void curl_global_cleanup(void) 274{ 275 global_init_lock(); 276 277 if(!initialized) { 278 global_init_unlock(); 279 return; 280 } 281 282 if(--initialized) { 283 global_init_unlock(); 284 return; 285 } 286 287 Curl_ssl_cleanup(); 288 Curl_resolver_global_cleanup(); 289 290#ifdef _WIN32 291 Curl_win32_cleanup(easy_init_flags); 292#endif 293 294 Curl_amiga_cleanup(); 295 296 Curl_ssh_cleanup(); 297 298#ifdef DEBUGBUILD 299 free(leakpointer); 300#endif 301 302 easy_init_flags = 0; 303 304 global_init_unlock(); 305} 306 307/** 308 * curl_global_trace() globally initializes curl logging. 309 */ 310CURLcode curl_global_trace(const char *config) 311{ 312#ifndef CURL_DISABLE_VERBOSE_STRINGS 313 CURLcode result; 314 global_init_lock(); 315 316 result = Curl_trc_opt(config); 317 318 global_init_unlock(); 319 320 return result; 321#else 322 (void)config; 323 return CURLE_OK; 324#endif 325} 326 327/* 328 * curl_global_sslset() globally initializes the SSL backend to use. 329 */ 330CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, 331 const curl_ssl_backend ***avail) 332{ 333 CURLsslset rc; 334 335 global_init_lock(); 336 337 rc = Curl_init_sslset_nolock(id, name, avail); 338 339 global_init_unlock(); 340 341 return rc; 342} 343 344/* 345 * curl_easy_init() is the external interface to alloc, setup and init an 346 * easy handle that is returned. If anything goes wrong, NULL is returned. 347 */ 348struct Curl_easy *curl_easy_init(void) 349{ 350 CURLcode result; 351 struct Curl_easy *data; 352 353 /* Make sure we inited the global SSL stuff */ 354 global_init_lock(); 355 356 if(!initialized) { 357 result = global_init(CURL_GLOBAL_DEFAULT, TRUE); 358 if(result) { 359 /* something in the global init failed, return nothing */ 360 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n")); 361 global_init_unlock(); 362 return NULL; 363 } 364 } 365 global_init_unlock(); 366 367 /* We use curl_open() with undefined URL so far */ 368 result = Curl_open(&data); 369 if(result) { 370 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n")); 371 return NULL; 372 } 373 374 return data; 375} 376 377#ifdef CURLDEBUG 378 379struct socketmonitor { 380 struct socketmonitor *next; /* the next node in the list or NULL */ 381 struct pollfd socket; /* socket info of what to monitor */ 382}; 383 384struct events { 385 long ms; /* timeout, run the timeout function when reached */ 386 bool msbump; /* set TRUE when timeout is set by callback */ 387 int num_sockets; /* number of nodes in the monitor list */ 388 struct socketmonitor *list; /* list of sockets to monitor */ 389 int running_handles; /* store the returned number */ 390}; 391 392/* events_timer 393 * 394 * Callback that gets called with a new value when the timeout should be 395 * updated. 396 */ 397 398static int events_timer(struct Curl_multi *multi, /* multi handle */ 399 long timeout_ms, /* see above */ 400 void *userp) /* private callback pointer */ 401{ 402 struct events *ev = userp; 403 (void)multi; 404 if(timeout_ms == -1) 405 /* timeout removed */ 406 timeout_ms = 0; 407 else if(timeout_ms == 0) 408 /* timeout is already reached! */ 409 timeout_ms = 1; /* trigger asap */ 410 411 ev->ms = timeout_ms; 412 ev->msbump = TRUE; 413 return 0; 414} 415 416 417/* poll2cselect 418 * 419 * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones 420 */ 421static int poll2cselect(int pollmask) 422{ 423 int omask = 0; 424 if(pollmask & POLLIN) 425 omask |= CURL_CSELECT_IN; 426 if(pollmask & POLLOUT) 427 omask |= CURL_CSELECT_OUT; 428 if(pollmask & POLLERR) 429 omask |= CURL_CSELECT_ERR; 430 return omask; 431} 432 433 434/* socketcb2poll 435 * 436 * convert from libcurl' CURL_POLL_* bit definitions to poll()'s 437 */ 438static short socketcb2poll(int pollmask) 439{ 440 short omask = 0; 441 if(pollmask & CURL_POLL_IN) 442 omask |= POLLIN; 443 if(pollmask & CURL_POLL_OUT) 444 omask |= POLLOUT; 445 return omask; 446} 447 448/* events_socket 449 * 450 * Callback that gets called with information about socket activity to 451 * monitor. 452 */ 453static int events_socket(struct Curl_easy *easy, /* easy handle */ 454 curl_socket_t s, /* socket */ 455 int what, /* see above */ 456 void *userp, /* private callback 457 pointer */ 458 void *socketp) /* private socket 459 pointer */ 460{ 461 struct events *ev = userp; 462 struct socketmonitor *m; 463 struct socketmonitor *prev = NULL; 464 465#if defined(CURL_DISABLE_VERBOSE_STRINGS) 466 (void) easy; 467#endif 468 (void)socketp; 469 470 m = ev->list; 471 while(m) { 472 if(m->socket.fd == s) { 473 474 if(what == CURL_POLL_REMOVE) { 475 struct socketmonitor *nxt = m->next; 476 /* remove this node from the list of monitored sockets */ 477 if(prev) 478 prev->next = nxt; 479 else 480 ev->list = nxt; 481 free(m); 482 m = nxt; 483 infof(easy, "socket cb: socket %" CURL_FORMAT_SOCKET_T 484 " REMOVED", s); 485 } 486 else { 487 /* The socket 's' is already being monitored, update the activity 488 mask. Convert from libcurl bitmask to the poll one. */ 489 m->socket.events = socketcb2poll(what); 490 infof(easy, "socket cb: socket %" CURL_FORMAT_SOCKET_T 491 " UPDATED as %s%s", s, 492 (what&CURL_POLL_IN)?"IN":"", 493 (what&CURL_POLL_OUT)?"OUT":""); 494 } 495 break; 496 } 497 prev = m; 498 m = m->next; /* move to next node */ 499 } 500 if(!m) { 501 if(what == CURL_POLL_REMOVE) { 502 /* this happens a bit too often, libcurl fix perhaps? */ 503 /* fprintf(stderr, 504 "%s: socket %d asked to be REMOVED but not present!\n", 505 __func__, s); */ 506 } 507 else { 508 m = malloc(sizeof(struct socketmonitor)); 509 if(m) { 510 m->next = ev->list; 511 m->socket.fd = s; 512 m->socket.events = socketcb2poll(what); 513 m->socket.revents = 0; 514 ev->list = m; 515 infof(easy, "socket cb: socket %" CURL_FORMAT_SOCKET_T 516 " ADDED as %s%s", s, 517 (what&CURL_POLL_IN)?"IN":"", 518 (what&CURL_POLL_OUT)?"OUT":""); 519 } 520 else 521 return CURLE_OUT_OF_MEMORY; 522 } 523 } 524 525 return 0; 526} 527 528 529/* 530 * events_setup() 531 * 532 * Do the multi handle setups that only event-based transfers need. 533 */ 534static void events_setup(struct Curl_multi *multi, struct events *ev) 535{ 536 /* timer callback */ 537 curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer); 538 curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev); 539 540 /* socket callback */ 541 curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket); 542 curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev); 543} 544 545 546/* wait_or_timeout() 547 * 548 * waits for activity on any of the given sockets, or the timeout to trigger. 549 */ 550 551static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) 552{ 553 bool done = FALSE; 554 CURLMcode mcode = CURLM_OK; 555 CURLcode result = CURLE_OK; 556 557 while(!done) { 558 CURLMsg *msg; 559 struct socketmonitor *m; 560 struct pollfd *f; 561 struct pollfd fds[4]; 562 int numfds = 0; 563 int pollrc; 564 int i; 565 struct curltime before; 566 struct curltime after; 567 568 /* populate the fds[] array */ 569 for(m = ev->list, f = &fds[0]; m; m = m->next) { 570 f->fd = m->socket.fd; 571 f->events = m->socket.events; 572 f->revents = 0; 573 /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */ 574 f++; 575 numfds++; 576 } 577 578 /* get the time stamp to use to figure out how long poll takes */ 579 before = Curl_now(); 580 581 /* wait for activity or timeout */ 582 pollrc = Curl_poll(fds, numfds, ev->ms); 583 if(pollrc < 0) 584 return CURLE_UNRECOVERABLE_POLL; 585 586 after = Curl_now(); 587 588 ev->msbump = FALSE; /* reset here */ 589 590 if(!pollrc) { 591 /* timeout! */ 592 ev->ms = 0; 593 /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */ 594 mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, 595 &ev->running_handles); 596 } 597 else { 598 /* here pollrc is > 0 */ 599 600 /* loop over the monitored sockets to see which ones had activity */ 601 for(i = 0; i< numfds; i++) { 602 if(fds[i].revents) { 603 /* socket activity, tell libcurl */ 604 int act = poll2cselect(fds[i].revents); /* convert */ 605 infof(multi->easyp, 606 "call curl_multi_socket_action(socket " 607 "%" CURL_FORMAT_SOCKET_T ")", fds[i].fd); 608 mcode = curl_multi_socket_action(multi, fds[i].fd, act, 609 &ev->running_handles); 610 } 611 } 612 613 if(!ev->msbump) { 614 /* If nothing updated the timeout, we decrease it by the spent time. 615 * If it was updated, it has the new timeout time stored already. 616 */ 617 timediff_t timediff = Curl_timediff(after, before); 618 if(timediff > 0) { 619 if(timediff > ev->ms) 620 ev->ms = 0; 621 else 622 ev->ms -= (long)timediff; 623 } 624 } 625 } 626 627 if(mcode) 628 return CURLE_URL_MALFORMAT; 629 630 /* we don't really care about the "msgs_in_queue" value returned in the 631 second argument */ 632 msg = curl_multi_info_read(multi, &pollrc); 633 if(msg) { 634 result = msg->data.result; 635 done = TRUE; 636 } 637 } 638 639 return result; 640} 641 642 643/* easy_events() 644 * 645 * Runs a transfer in a blocking manner using the events-based API 646 */ 647static CURLcode easy_events(struct Curl_multi *multi) 648{ 649 /* this struct is made static to allow it to be used after this function 650 returns and curl_multi_remove_handle() is called */ 651 static struct events evs = {2, FALSE, 0, NULL, 0}; 652 653 /* if running event-based, do some further multi inits */ 654 events_setup(multi, &evs); 655 656 return wait_or_timeout(multi, &evs); 657} 658#else /* CURLDEBUG */ 659/* when not built with debug, this function doesn't exist */ 660#define easy_events(x) CURLE_NOT_BUILT_IN 661#endif 662 663static CURLcode easy_transfer(struct Curl_multi *multi) 664{ 665 bool done = FALSE; 666 CURLMcode mcode = CURLM_OK; 667 CURLcode result = CURLE_OK; 668 669 while(!done && !mcode) { 670 int still_running = 0; 671 672 mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); 673 674 if(!mcode) 675 mcode = curl_multi_perform(multi, &still_running); 676 677 /* only read 'still_running' if curl_multi_perform() return OK */ 678 if(!mcode && !still_running) { 679 int rc; 680 CURLMsg *msg = curl_multi_info_read(multi, &rc); 681 if(msg) { 682 result = msg->data.result; 683 done = TRUE; 684 } 685 } 686 } 687 688 /* Make sure to return some kind of error if there was a multi problem */ 689 if(mcode) { 690 result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : 691 /* The other multi errors should never happen, so return 692 something suitably generic */ 693 CURLE_BAD_FUNCTION_ARGUMENT; 694 } 695 696 return result; 697} 698 699 700/* 701 * easy_perform() is the external interface that performs a blocking 702 * transfer as previously setup. 703 * 704 * CONCEPT: This function creates a multi handle, adds the easy handle to it, 705 * runs curl_multi_perform() until the transfer is done, then detaches the 706 * easy handle, destroys the multi handle and returns the easy handle's return 707 * code. 708 * 709 * REALITY: it can't just create and destroy the multi handle that easily. It 710 * needs to keep it around since if this easy handle is used again by this 711 * function, the same multi handle must be reused so that the same pools and 712 * caches can be used. 713 * 714 * DEBUG: if 'events' is set TRUE, this function will use a replacement engine 715 * instead of curl_multi_perform() and use curl_multi_socket_action(). 716 */ 717static CURLcode easy_perform(struct Curl_easy *data, bool events) 718{ 719 struct Curl_multi *multi; 720 CURLMcode mcode; 721 CURLcode result = CURLE_OK; 722 SIGPIPE_VARIABLE(pipe_st); 723 724 if(!data) 725 return CURLE_BAD_FUNCTION_ARGUMENT; 726 727 if(data->set.errorbuffer) 728 /* clear this as early as possible */ 729 data->set.errorbuffer[0] = 0; 730 731 if(data->multi) { 732 failf(data, "easy handle already used in multi handle"); 733 return CURLE_FAILED_INIT; 734 } 735 736 if(data->multi_easy) 737 multi = data->multi_easy; 738 else { 739 /* this multi handle will only ever have a single easy handled attached 740 to it, so make it use minimal hashes */ 741 multi = Curl_multi_handle(1, 3, 7); 742 if(!multi) 743 return CURLE_OUT_OF_MEMORY; 744 data->multi_easy = multi; 745 } 746 747 if(multi->in_callback) 748 return CURLE_RECURSIVE_API_CALL; 749 750 /* Copy the MAXCONNECTS option to the multi handle */ 751 curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, (long)data->set.maxconnects); 752 753 mcode = curl_multi_add_handle(multi, data); 754 if(mcode) { 755 curl_multi_cleanup(multi); 756 data->multi_easy = NULL; 757 if(mcode == CURLM_OUT_OF_MEMORY) 758 return CURLE_OUT_OF_MEMORY; 759 return CURLE_FAILED_INIT; 760 } 761 762 sigpipe_ignore(data, &pipe_st); 763 764 /* run the transfer */ 765 result = events ? easy_events(multi) : easy_transfer(multi); 766 767 /* ignoring the return code isn't nice, but atm we can't really handle 768 a failure here, room for future improvement! */ 769 (void)curl_multi_remove_handle(multi, data); 770 771 sigpipe_restore(&pipe_st); 772 773 /* The multi handle is kept alive, owned by the easy handle */ 774 return result; 775} 776 777 778/* 779 * curl_easy_perform() is the external interface that performs a blocking 780 * transfer as previously setup. 781 */ 782CURLcode curl_easy_perform(struct Curl_easy *data) 783{ 784 return easy_perform(data, FALSE); 785} 786 787#ifdef CURLDEBUG 788/* 789 * curl_easy_perform_ev() is the external interface that performs a blocking 790 * transfer using the event-based API internally. 791 */ 792CURLcode curl_easy_perform_ev(struct Curl_easy *data) 793{ 794 return easy_perform(data, TRUE); 795} 796 797#endif 798 799/* 800 * curl_easy_cleanup() is the external interface to cleaning/freeing the given 801 * easy handle. 802 */ 803void curl_easy_cleanup(struct Curl_easy *data) 804{ 805 if(GOOD_EASY_HANDLE(data)) { 806 SIGPIPE_VARIABLE(pipe_st); 807 sigpipe_ignore(data, &pipe_st); 808 Curl_close(&data); 809 sigpipe_restore(&pipe_st); 810 } 811} 812 813/* 814 * curl_easy_getinfo() is an external interface that allows an app to retrieve 815 * information from a performed transfer and similar. 816 */ 817#undef curl_easy_getinfo 818CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...) 819{ 820 va_list arg; 821 void *paramp; 822 CURLcode result; 823 824 va_start(arg, info); 825 paramp = va_arg(arg, void *); 826 827 result = Curl_getinfo(data, info, paramp); 828 829 va_end(arg); 830 return result; 831} 832 833static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) 834{ 835 CURLcode result = CURLE_OK; 836 enum dupstring i; 837 enum dupblob j; 838 839 /* Copy src->set into dst->set first, then deal with the strings 840 afterwards */ 841 dst->set = src->set; 842 Curl_mime_initpart(&dst->set.mimepost); 843 844 /* clear all dest string and blob pointers first, in case we error out 845 mid-function */ 846 memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); 847 memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *)); 848 849 /* duplicate all strings */ 850 for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { 851 result = Curl_setstropt(&dst->set.str[i], src->set.str[i]); 852 if(result) 853 return result; 854 } 855 856 /* duplicate all blobs */ 857 for(j = (enum dupblob)0; j < BLOB_LAST; j++) { 858 result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]); 859 if(result) 860 return result; 861 } 862 863 /* duplicate memory areas pointed to */ 864 i = STRING_COPYPOSTFIELDS; 865 if(src->set.str[i]) { 866 if(src->set.postfieldsize == -1) 867 dst->set.str[i] = strdup(src->set.str[i]); 868 else 869 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ 870 dst->set.str[i] = Curl_memdup(src->set.str[i], 871 curlx_sotouz(src->set.postfieldsize)); 872 if(!dst->set.str[i]) 873 return CURLE_OUT_OF_MEMORY; 874 /* point to the new copy */ 875 dst->set.postfields = dst->set.str[i]; 876 } 877 878 /* Duplicate mime data. */ 879 result = Curl_mime_duppart(dst, &dst->set.mimepost, &src->set.mimepost); 880 881 if(src->set.resolve) 882 dst->state.resolve = dst->set.resolve; 883 884 return result; 885} 886 887/* 888 * curl_easy_duphandle() is an external interface to allow duplication of a 889 * given input easy handle. The returned handle will be a new working handle 890 * with all options set exactly as the input source handle. 891 */ 892struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) 893{ 894 struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy)); 895 if(!outcurl) 896 goto fail; 897 898 /* 899 * We setup a few buffers we need. We should probably make them 900 * get setup on-demand in the code, as that would probably decrease 901 * the likeliness of us forgetting to init a buffer here in the future. 902 */ 903 outcurl->set.buffer_size = data->set.buffer_size; 904 905 /* copy all userdefined values */ 906 if(dupset(outcurl, data)) 907 goto fail; 908 909 Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER); 910 911 /* the connection cache is setup on demand */ 912 outcurl->state.conn_cache = NULL; 913 outcurl->state.lastconnect_id = -1; 914 outcurl->state.recent_conn_id = -1; 915 outcurl->id = -1; 916 917 outcurl->progress.flags = data->progress.flags; 918 outcurl->progress.callback = data->progress.callback; 919 920#ifndef CURL_DISABLE_COOKIES 921 outcurl->state.cookielist = NULL; 922 if(data->cookies && data->state.cookie_engine) { 923 /* If cookies are enabled in the parent handle, we enable them 924 in the clone as well! */ 925 outcurl->cookies = Curl_cookie_init(outcurl, NULL, outcurl->cookies, 926 data->set.cookiesession); 927 if(!outcurl->cookies) 928 goto fail; 929 } 930 931 if(data->state.cookielist) { 932 outcurl->state.cookielist = Curl_slist_duplicate(data->state.cookielist); 933 if(!outcurl->state.cookielist) 934 goto fail; 935 } 936#endif 937 938 if(data->state.url) { 939 outcurl->state.url = strdup(data->state.url); 940 if(!outcurl->state.url) 941 goto fail; 942 outcurl->state.url_alloc = TRUE; 943 } 944 945 if(data->state.referer) { 946 outcurl->state.referer = strdup(data->state.referer); 947 if(!outcurl->state.referer) 948 goto fail; 949 outcurl->state.referer_alloc = TRUE; 950 } 951 952 /* Reinitialize an SSL engine for the new handle 953 * note: the engine name has already been copied by dupset */ 954 if(outcurl->set.str[STRING_SSL_ENGINE]) { 955 if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE])) 956 goto fail; 957 } 958 959#ifndef CURL_DISABLE_ALTSVC 960 if(data->asi) { 961 outcurl->asi = Curl_altsvc_init(); 962 if(!outcurl->asi) 963 goto fail; 964 if(outcurl->set.str[STRING_ALTSVC]) 965 (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]); 966 } 967#endif 968#ifndef CURL_DISABLE_HSTS 969 if(data->hsts) { 970 outcurl->hsts = Curl_hsts_init(); 971 if(!outcurl->hsts) 972 goto fail; 973 if(outcurl->set.str[STRING_HSTS]) 974 (void)Curl_hsts_loadfile(outcurl, 975 outcurl->hsts, outcurl->set.str[STRING_HSTS]); 976 (void)Curl_hsts_loadcb(outcurl, outcurl->hsts); 977 } 978#endif 979 980#ifdef CURLRES_ASYNCH 981 /* Clone the resolver handle, if present, for the new handle */ 982 if(Curl_resolver_duphandle(outcurl, 983 &outcurl->state.async.resolver, 984 data->state.async.resolver)) 985 goto fail; 986#endif 987 988#ifdef USE_ARES 989 { 990 CURLcode rc; 991 992 rc = Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]); 993 if(rc && rc != CURLE_NOT_BUILT_IN) 994 goto fail; 995 996 rc = Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]); 997 if(rc && rc != CURLE_NOT_BUILT_IN) 998 goto fail; 999 1000 rc = Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]); 1001 if(rc && rc != CURLE_NOT_BUILT_IN) 1002 goto fail; 1003 1004 rc = Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]); 1005 if(rc && rc != CURLE_NOT_BUILT_IN) 1006 goto fail; 1007 } 1008#endif /* USE_ARES */ 1009 1010 Curl_initinfo(outcurl); 1011 1012 outcurl->magic = CURLEASY_MAGIC_NUMBER; 1013 1014 /* we reach this point and thus we are OK */ 1015 1016 return outcurl; 1017 1018fail: 1019 1020 if(outcurl) { 1021#ifndef CURL_DISABLE_COOKIES 1022 free(outcurl->cookies); 1023#endif 1024 free(outcurl->state.buffer); 1025 Curl_dyn_free(&outcurl->state.headerb); 1026 Curl_altsvc_cleanup(&outcurl->asi); 1027 Curl_hsts_cleanup(&outcurl->hsts); 1028 Curl_freeset(outcurl); 1029 free(outcurl); 1030 } 1031 1032 return NULL; 1033} 1034 1035/* 1036 * curl_easy_reset() is an external interface that allows an app to re- 1037 * initialize a session handle to the default values. 1038 */ 1039void curl_easy_reset(struct Curl_easy *data) 1040{ 1041 Curl_free_request_state(data); 1042 1043 /* zero out UserDefined data: */ 1044 Curl_freeset(data); 1045 memset(&data->set, 0, sizeof(struct UserDefined)); 1046 (void)Curl_init_userdefined(data); 1047 1048 /* zero out Progress data: */ 1049 memset(&data->progress, 0, sizeof(struct Progress)); 1050 1051 /* zero out PureInfo data: */ 1052 Curl_initinfo(data); 1053 1054 data->progress.flags |= PGRS_HIDE; 1055 data->state.current_speed = -1; /* init to negative == impossible */ 1056 data->state.retrycount = 0; /* reset the retry counter */ 1057 1058 /* zero out authentication data: */ 1059 memset(&data->state.authhost, 0, sizeof(struct auth)); 1060 memset(&data->state.authproxy, 0, sizeof(struct auth)); 1061 1062#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) 1063 Curl_http_auth_cleanup_digest(data); 1064#endif 1065} 1066 1067/* 1068 * curl_easy_pause() allows an application to pause or unpause a specific 1069 * transfer and direction. This function sets the full new state for the 1070 * current connection this easy handle operates on. 1071 * 1072 * NOTE: if you have the receiving paused and you call this function to remove 1073 * the pausing, you may get your write callback called at this point. 1074 * 1075 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h 1076 * 1077 * NOTE: This is one of few API functions that are allowed to be called from 1078 * within a callback. 1079 */ 1080CURLcode curl_easy_pause(struct Curl_easy *data, int action) 1081{ 1082 struct SingleRequest *k; 1083 CURLcode result = CURLE_OK; 1084 int oldstate; 1085 int newstate; 1086 bool recursive = FALSE; 1087 1088 if(!GOOD_EASY_HANDLE(data) || !data->conn) 1089 /* crazy input, don't continue */ 1090 return CURLE_BAD_FUNCTION_ARGUMENT; 1091 1092 if(Curl_is_in_callback(data)) 1093 recursive = TRUE; 1094 k = &data->req; 1095 oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); 1096 1097 /* first switch off both pause bits then set the new pause bits */ 1098 newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) | 1099 ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | 1100 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0); 1101 1102 if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) { 1103 /* Not changing any pause state, return */ 1104 DEBUGF(infof(data, "pause: no change, early return")); 1105 return CURLE_OK; 1106 } 1107 1108 /* Unpause parts in active mime tree. */ 1109 if((k->keepon & ~newstate & KEEP_SEND_PAUSE) && 1110 (data->mstate == MSTATE_PERFORMING || 1111 data->mstate == MSTATE_RATELIMITING) && 1112 data->state.fread_func == (curl_read_callback) Curl_mime_read) { 1113 Curl_mime_unpause(data->state.in); 1114 } 1115 1116 /* put it back in the keepon */ 1117 k->keepon = newstate; 1118 1119 if(!(newstate & KEEP_RECV_PAUSE)) { 1120 Curl_conn_ev_data_pause(data, FALSE); 1121 result = Curl_client_unpause(data); 1122 if(result) 1123 return result; 1124 } 1125 1126#ifdef USE_HYPER 1127 if(!(newstate & KEEP_SEND_PAUSE)) { 1128 /* need to wake the send body waker */ 1129 if(data->hyp.send_body_waker) { 1130 hyper_waker_wake(data->hyp.send_body_waker); 1131 data->hyp.send_body_waker = NULL; 1132 } 1133 } 1134#endif 1135 1136 /* if there's no error and we're not pausing both directions, we want 1137 to have this handle checked soon */ 1138 if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != 1139 (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) { 1140 Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ 1141 1142 /* reset the too-slow time keeper */ 1143 data->state.keeps_speed.tv_sec = 0; 1144 1145 if(!data->state.tempcount) 1146 /* if not pausing again, force a recv/send check of this connection as 1147 the data might've been read off the socket already */ 1148 data->state.select_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT; 1149 if(data->multi) { 1150 if(Curl_update_timer(data->multi)) 1151 return CURLE_ABORTED_BY_CALLBACK; 1152 } 1153 } 1154 1155 if(!data->state.done) 1156 /* This transfer may have been moved in or out of the bundle, update the 1157 corresponding socket callback, if used */ 1158 result = Curl_updatesocket(data); 1159 1160 if(recursive) 1161 /* this might have called a callback recursively which might have set this 1162 to false again on exit */ 1163 Curl_set_in_callback(data, TRUE); 1164 1165 return result; 1166} 1167 1168 1169static CURLcode easy_connection(struct Curl_easy *data, curl_socket_t *sfd, 1170 struct connectdata **connp) 1171{ 1172 if(!data) 1173 return CURLE_BAD_FUNCTION_ARGUMENT; 1174 1175 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */ 1176 if(!data->set.connect_only) { 1177 failf(data, "CONNECT_ONLY is required"); 1178 return CURLE_UNSUPPORTED_PROTOCOL; 1179 } 1180 1181 *sfd = Curl_getconnectinfo(data, connp); 1182 1183 if(*sfd == CURL_SOCKET_BAD) { 1184 failf(data, "Failed to get recent socket"); 1185 return CURLE_UNSUPPORTED_PROTOCOL; 1186 } 1187 1188 return CURLE_OK; 1189} 1190 1191/* 1192 * Receives data from the connected socket. Use after successful 1193 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 1194 * Returns CURLE_OK on success, error code on error. 1195 */ 1196CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen, 1197 size_t *n) 1198{ 1199 curl_socket_t sfd; 1200 CURLcode result; 1201 ssize_t n1; 1202 struct connectdata *c; 1203 1204 if(Curl_is_in_callback(data)) 1205 return CURLE_RECURSIVE_API_CALL; 1206 1207 result = easy_connection(data, &sfd, &c); 1208 if(result) 1209 return result; 1210 1211 if(!data->conn) 1212 /* on first invoke, the transfer has been detached from the connection and 1213 needs to be reattached */ 1214 Curl_attach_connection(data, c); 1215 1216 *n = 0; 1217 result = Curl_read(data, sfd, buffer, buflen, &n1); 1218 1219 if(result) 1220 return result; 1221 1222 *n = (size_t)n1; 1223 return CURLE_OK; 1224} 1225 1226#ifdef USE_WEBSOCKETS 1227CURLcode Curl_connect_only_attach(struct Curl_easy *data) 1228{ 1229 curl_socket_t sfd; 1230 CURLcode result; 1231 struct connectdata *c = NULL; 1232 1233 result = easy_connection(data, &sfd, &c); 1234 if(result) 1235 return result; 1236 1237 if(!data->conn) 1238 /* on first invoke, the transfer has been detached from the connection and 1239 needs to be reattached */ 1240 Curl_attach_connection(data, c); 1241 1242 return CURLE_OK; 1243} 1244#endif /* USE_WEBSOCKETS */ 1245 1246/* 1247 * Sends data over the connected socket. 1248 * 1249 * This is the private internal version of curl_easy_send() 1250 */ 1251CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer, 1252 size_t buflen, ssize_t *n) 1253{ 1254 curl_socket_t sfd; 1255 CURLcode result; 1256 ssize_t n1; 1257 struct connectdata *c = NULL; 1258 SIGPIPE_VARIABLE(pipe_st); 1259 1260 result = easy_connection(data, &sfd, &c); 1261 if(result) 1262 return result; 1263 1264 if(!data->conn) 1265 /* on first invoke, the transfer has been detached from the connection and 1266 needs to be reattached */ 1267 Curl_attach_connection(data, c); 1268 1269 *n = 0; 1270 sigpipe_ignore(data, &pipe_st); 1271 result = Curl_write(data, sfd, buffer, buflen, &n1); 1272 sigpipe_restore(&pipe_st); 1273 1274 if(n1 == -1) 1275 return CURLE_SEND_ERROR; 1276 1277 /* detect EAGAIN */ 1278 if(!result && !n1) 1279 return CURLE_AGAIN; 1280 1281 *n = n1; 1282 1283 return result; 1284} 1285 1286/* 1287 * Sends data over the connected socket. Use after successful 1288 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 1289 */ 1290CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, 1291 size_t buflen, size_t *n) 1292{ 1293 ssize_t written = 0; 1294 CURLcode result; 1295 if(Curl_is_in_callback(data)) 1296 return CURLE_RECURSIVE_API_CALL; 1297 1298 result = Curl_senddata(data, buffer, buflen, &written); 1299 *n = (size_t)written; 1300 return result; 1301} 1302 1303/* 1304 * Wrapper to call functions in Curl_conncache_foreach() 1305 * 1306 * Returns always 0. 1307 */ 1308static int conn_upkeep(struct Curl_easy *data, 1309 struct connectdata *conn, 1310 void *param) 1311{ 1312 struct curltime *now = param; 1313 1314 if(Curl_timediff(*now, conn->keepalive) <= data->set.upkeep_interval_ms) 1315 return 0; 1316 1317 /* briefly attach for action */ 1318 Curl_attach_connection(data, conn); 1319 if(conn->handler->connection_check) { 1320 /* Do a protocol-specific keepalive check on the connection. */ 1321 conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE); 1322 } 1323 else { 1324 /* Do the generic action on the FIRSTSOCKE filter chain */ 1325 Curl_conn_keep_alive(data, conn, FIRSTSOCKET); 1326 } 1327 Curl_detach_connection(data); 1328 1329 conn->keepalive = *now; 1330 return 0; /* continue iteration */ 1331} 1332 1333static CURLcode upkeep(struct conncache *conn_cache, void *data) 1334{ 1335 struct curltime now = Curl_now(); 1336 /* Loop over every connection and make connection alive. */ 1337 Curl_conncache_foreach(data, 1338 conn_cache, 1339 &now, 1340 conn_upkeep); 1341 return CURLE_OK; 1342} 1343 1344/* 1345 * Performs connection upkeep for the given session handle. 1346 */ 1347CURLcode curl_easy_upkeep(struct Curl_easy *data) 1348{ 1349 /* Verify that we got an easy handle we can work with. */ 1350 if(!GOOD_EASY_HANDLE(data)) 1351 return CURLE_BAD_FUNCTION_ARGUMENT; 1352 1353 if(data->multi_easy) { 1354 /* Use the common function to keep connections alive. */ 1355 return upkeep(&data->multi_easy->conn_cache, data); 1356 } 1357 else { 1358 /* No connections, so just return success */ 1359 return CURLE_OK; 1360 } 1361} 1362