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