1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel (at) 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 /* 26 * See comment in curl_memory.h for the explanation of this sanity check. 27 */ 28 29 #ifdef CURLX_NO_MEMORY_CALLBACKS 30 #error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined" 31 #endif 32 33 #ifdef HAVE_NETINET_IN_H 34 #include <netinet/in.h> 35 #endif 36 #ifdef HAVE_NETDB_H 37 #include <netdb.h> 38 #endif 39 #ifdef HAVE_ARPA_INET_H 40 #include <arpa/inet.h> 41 #endif 42 #ifdef HAVE_NET_IF_H 43 #include <net/if.h> 44 #endif 45 #ifdef HAVE_SYS_IOCTL_H 46 #include <sys/ioctl.h> 47 #endif 48 49 #ifdef HAVE_SYS_PARAM_H 50 #include <sys/param.h> 51 #endif 52 53 #include "urldata.h" 54 #include <curl/curl.h> 55 #include "transfer.h" 56 #include "vtls/vtls.h" 57 #include "url.h" 58 #include "getinfo.h" 59 #include "hostip.h" 60 #include "share.h" 61 #include "strdup.h" 62 #include "progress.h" 63 #include "easyif.h" 64 #include "select.h" 65 #include "sendf.h" /* for failf function prototype */ 66 #include "connect.h" /* for Curl_getconnectinfo */ 67 #include "slist.h" 68 #include "mime.h" 69 #include "amigaos.h" 70 #include "non-ascii.h" 71 #include "warnless.h" 72 #include "multiif.h" 73 #include "sigpipe.h" 74 #include "ssh.h" 75 #include "setopt.h" 76 77 /* The last 3 #include files should be in this order */ 78 #include "curl_printf.h" 79 #include "curl_memory.h" 80 #include "memdebug.h" 81 82 void Curl_version_init(void); 83 84 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite 85 of win32_init() */ 86 static void win32_cleanup(void) 87 { 88 #ifdef USE_WINSOCK 89 WSACleanup(); 90 #endif 91 #ifdef USE_WINDOWS_SSPI 92 Curl_sspi_global_cleanup(); 93 #endif 94 } 95 96 /* win32_init() performs win32 socket initialization to properly setup the 97 stack to allow networking */ 98 static CURLcode win32_init(void) 99 { 100 #ifdef USE_WINSOCK 101 WORD wVersionRequested; 102 WSADATA wsaData; 103 int res; 104 105 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) 106 Error IPV6_requires_winsock2 107 #endif 108 109 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); 110 111 res = WSAStartup(wVersionRequested, &wsaData); 112 113 if(res != 0) 114 /* Tell the user that we couldn't find a useable */ 115 /* winsock.dll. */ 116 return CURLE_FAILED_INIT; 117 118 /* Confirm that the Windows Sockets DLL supports what we need.*/ 119 /* Note that if the DLL supports versions greater */ 120 /* than wVersionRequested, it will still return */ 121 /* wVersionRequested in wVersion. wHighVersion contains the */ 122 /* highest supported version. */ 123 124 if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || 125 HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { 126 /* Tell the user that we couldn't find a useable */ 127 128 /* winsock.dll. */ 129 WSACleanup(); 130 return CURLE_FAILED_INIT; 131 } 132 /* The Windows Sockets DLL is acceptable. Proceed. */ 133 #elif defined(USE_LWIPSOCK) 134 lwip_init(); 135 #endif 136 137 #ifdef USE_WINDOWS_SSPI 138 { 139 CURLcode result = Curl_sspi_global_init(); 140 if(result) 141 return result; 142 } 143 #endif 144 145 return CURLE_OK; 146 } 147 148 /* true globals -- for curl_global_init() and curl_global_cleanup() */ 149 static unsigned int initialized; 150 static long init_flags; 151 152 /* 153 * strdup (and other memory functions) is redefined in complicated 154 * ways, but at this point it must be defined as the system-supplied strdup 155 * so the callback pointer is initialized correctly. 156 */ 157 #if defined(_WIN32_WCE) 158 #define system_strdup _strdup 159 #elif !defined(HAVE_STRDUP) 160 #define system_strdup curlx_strdup 161 #else 162 #define system_strdup strdup 163 #endif 164 165 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) 166 # pragma warning(disable:4232) /* MSVC extension, dllimport identity */ 167 #endif 168 169 #ifndef __SYMBIAN32__ 170 /* 171 * If a memory-using function (like curl_getenv) is used before 172 * curl_global_init() is called, we need to have these pointers set already. 173 */ 174 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; 175 curl_free_callback Curl_cfree = (curl_free_callback)free; 176 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; 177 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; 178 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; 179 #if defined(WIN32) && defined(UNICODE) 180 curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; 181 #endif 182 #else 183 /* 184 * Symbian OS doesn't support initialization to code in writable static data. 185 * Initialization will occur in the curl_global_init() call. 186 */ 187 curl_malloc_callback Curl_cmalloc; 188 curl_free_callback Curl_cfree; 189 curl_realloc_callback Curl_crealloc; 190 curl_strdup_callback Curl_cstrdup; 191 curl_calloc_callback Curl_ccalloc; 192 #endif 193 194 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) 195 # pragma warning(default:4232) /* MSVC extension, dllimport identity */ 196 #endif 197 198 /** 199 * curl_global_init() globally initializes curl given a bitwise set of the 200 * different features of what to initialize. 201 */ 202 static CURLcode global_init(long flags, bool memoryfuncs) 203 { 204 if(initialized++) 205 return CURLE_OK; 206 207 if(memoryfuncs) { 208 /* Setup the default memory functions here (again) */ 209 Curl_cmalloc = (curl_malloc_callback)malloc; 210 Curl_cfree = (curl_free_callback)free; 211 Curl_crealloc = (curl_realloc_callback)realloc; 212 Curl_cstrdup = (curl_strdup_callback)system_strdup; 213 Curl_ccalloc = (curl_calloc_callback)calloc; 214 #if defined(WIN32) && defined(UNICODE) 215 Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; 216 #endif 217 } 218 219 if(!Curl_ssl_init()) { 220 DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); 221 return CURLE_FAILED_INIT; 222 } 223 224 if(flags & CURL_GLOBAL_WIN32) 225 if(win32_init()) { 226 DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); 227 return CURLE_FAILED_INIT; 228 } 229 230 #ifdef __AMIGA__ 231 if(!Curl_amiga_init()) { 232 DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); 233 return CURLE_FAILED_INIT; 234 } 235 #endif 236 237 #ifdef NETWARE 238 if(netware_init()) { 239 DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n")); 240 } 241 #endif 242 243 if(Curl_resolver_global_init()) { 244 DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); 245 return CURLE_FAILED_INIT; 246 } 247 248 (void)Curl_ipv6works(); 249 250 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT) 251 if(libssh2_init(0)) { 252 DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); 253 return CURLE_FAILED_INIT; 254 } 255 #endif 256 257 #if defined(USE_LIBSSH) 258 if(ssh_init()) { 259 DEBUGF(fprintf(stderr, "Error: libssh_init failed\n")); 260 return CURLE_FAILED_INIT; 261 } 262 #endif 263 264 if(flags & CURL_GLOBAL_ACK_EINTR) 265 Curl_ack_eintr = 1; 266 267 init_flags = flags; 268 269 Curl_version_init(); 270 271 return CURLE_OK; 272 } 273 274 275 /** 276 * curl_global_init() globally initializes curl given a bitwise set of the 277 * different features of what to initialize. 278 */ 279 CURLcode curl_global_init(long flags) 280 { 281 return global_init(flags, TRUE); 282 } 283 284 /* 285 * curl_global_init_mem() globally initializes curl and also registers the 286 * user provided callback routines. 287 */ 288 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m, 289 curl_free_callback f, curl_realloc_callback r, 290 curl_strdup_callback s, curl_calloc_callback c) 291 { 292 /* Invalid input, return immediately */ 293 if(!m || !f || !r || !s || !c) 294 return CURLE_FAILED_INIT; 295 296 if(initialized) { 297 /* Already initialized, don't do it again, but bump the variable anyway to 298 work like curl_global_init() and require the same amount of cleanup 299 calls. */ 300 initialized++; 301 return CURLE_OK; 302 } 303 304 /* set memory functions before global_init() in case it wants memory 305 functions */ 306 Curl_cmalloc = m; 307 Curl_cfree = f; 308 Curl_cstrdup = s; 309 Curl_crealloc = r; 310 Curl_ccalloc = c; 311 312 /* Call the actual init function, but without setting */ 313 return global_init(flags, FALSE); 314 } 315 316 /** 317 * curl_global_cleanup() globally cleanups curl, uses the value of 318 * "init_flags" to determine what needs to be cleaned up and what doesn't. 319 */ 320 void curl_global_cleanup(void) 321 { 322 if(!initialized) 323 return; 324 325 if(--initialized) 326 return; 327 328 Curl_global_host_cache_dtor(); 329 Curl_ssl_cleanup(); 330 Curl_resolver_global_cleanup(); 331 332 if(init_flags & CURL_GLOBAL_WIN32) 333 win32_cleanup(); 334 335 Curl_amiga_cleanup(); 336 337 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT) 338 (void)libssh2_exit(); 339 #endif 340 341 #if defined(USE_LIBSSH) 342 (void)ssh_finalize(); 343 #endif 344 345 init_flags = 0; 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 struct Curl_easy *curl_easy_init(void) 353 { 354 CURLcode result; 355 struct Curl_easy *data; 356 357 /* Make sure we inited the global SSL stuff */ 358 if(!initialized) { 359 result = curl_global_init(CURL_GLOBAL_DEFAULT); 360 if(result) { 361 /* something in the global init failed, return nothing */ 362 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n")); 363 return NULL; 364 } 365 } 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 379 struct 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 384 struct 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 398 static 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 */ 421 static 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 */ 438 static 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 */ 453 static 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 %d REMOVED\n", s); 484 } 485 else { 486 /* The socket 's' is already being monitored, update the activity 487 mask. Convert from libcurl bitmask to the poll one. */ 488 m->socket.events = socketcb2poll(what); 489 infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s, 490 what&CURL_POLL_IN?"IN":"", 491 what&CURL_POLL_OUT?"OUT":""); 492 } 493 break; 494 } 495 prev = m; 496 m = m->next; /* move to next node */ 497 } 498 if(!m) { 499 if(what == CURL_POLL_REMOVE) { 500 /* this happens a bit too often, libcurl fix perhaps? */ 501 /* fprintf(stderr, 502 "%s: socket %d asked to be REMOVED but not present!\n", 503 __func__, s); */ 504 } 505 else { 506 m = malloc(sizeof(struct socketmonitor)); 507 if(m) { 508 m->next = ev->list; 509 m->socket.fd = s; 510 m->socket.events = socketcb2poll(what); 511 m->socket.revents = 0; 512 ev->list = m; 513 infof(easy, "socket cb: socket %d ADDED as %s%s\n", s, 514 what&CURL_POLL_IN?"IN":"", 515 what&CURL_POLL_OUT?"OUT":""); 516 } 517 else 518 return CURLE_OUT_OF_MEMORY; 519 } 520 } 521 522 return 0; 523 } 524 525 526 /* 527 * events_setup() 528 * 529 * Do the multi handle setups that only event-based transfers need. 530 */ 531 static void events_setup(struct Curl_multi *multi, struct events *ev) 532 { 533 /* timer callback */ 534 curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer); 535 curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev); 536 537 /* socket callback */ 538 curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket); 539 curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev); 540 } 541 542 543 /* wait_or_timeout() 544 * 545 * waits for activity on any of the given sockets, or the timeout to trigger. 546 */ 547 548 static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) 549 { 550 bool done = FALSE; 551 CURLMcode mcode = CURLM_OK; 552 CURLcode result = CURLE_OK; 553 554 while(!done) { 555 CURLMsg *msg; 556 struct socketmonitor *m; 557 struct pollfd *f; 558 struct pollfd fds[4]; 559 int numfds = 0; 560 int pollrc; 561 int i; 562 struct curltime before; 563 struct curltime after; 564 565 /* populate the fds[] array */ 566 for(m = ev->list, f = &fds[0]; m; m = m->next) { 567 f->fd = m->socket.fd; 568 f->events = m->socket.events; 569 f->revents = 0; 570 /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */ 571 f++; 572 numfds++; 573 } 574 575 /* get the time stamp to use to figure out how long poll takes */ 576 before = Curl_now(); 577 578 /* wait for activity or timeout */ 579 pollrc = Curl_poll(fds, numfds, (int)ev->ms); 580 581 after = Curl_now(); 582 583 ev->msbump = FALSE; /* reset here */ 584 585 if(0 == pollrc) { 586 /* timeout! */ 587 ev->ms = 0; 588 /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */ 589 mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, 590 &ev->running_handles); 591 } 592 else if(pollrc > 0) { 593 /* loop over the monitored sockets to see which ones had activity */ 594 for(i = 0; i< numfds; i++) { 595 if(fds[i].revents) { 596 /* socket activity, tell libcurl */ 597 int act = poll2cselect(fds[i].revents); /* convert */ 598 infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n", 599 fds[i].fd); 600 mcode = curl_multi_socket_action(multi, fds[i].fd, act, 601 &ev->running_handles); 602 } 603 } 604 605 if(!ev->msbump) { 606 /* If nothing updated the timeout, we decrease it by the spent time. 607 * If it was updated, it has the new timeout time stored already. 608 */ 609 timediff_t timediff = Curl_timediff(after, before); 610 if(timediff > 0) { 611 if(timediff > ev->ms) 612 ev->ms = 0; 613 else 614 ev->ms -= (long)timediff; 615 } 616 } 617 } 618 else 619 return CURLE_RECV_ERROR; 620 621 if(mcode) 622 return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */ 623 624 /* we don't really care about the "msgs_in_queue" value returned in the 625 second argument */ 626 msg = curl_multi_info_read(multi, &pollrc); 627 if(msg) { 628 result = msg->data.result; 629 done = TRUE; 630 } 631 } 632 633 return result; 634 } 635 636 637 /* easy_events() 638 * 639 * Runs a transfer in a blocking manner using the events-based API 640 */ 641 static CURLcode easy_events(struct Curl_multi *multi) 642 { 643 /* this struct is made static to allow it to be used after this function 644 returns and curl_multi_remove_handle() is called */ 645 static struct events evs = {2, FALSE, 0, NULL, 0}; 646 647 /* if running event-based, do some further multi inits */ 648 events_setup(multi, &evs); 649 650 return wait_or_timeout(multi, &evs); 651 } 652 #else /* CURLDEBUG */ 653 /* when not built with debug, this function doesn't exist */ 654 #define easy_events(x) CURLE_NOT_BUILT_IN 655 #endif 656 657 static CURLcode easy_transfer(struct Curl_multi *multi) 658 { 659 bool done = FALSE; 660 CURLMcode mcode = CURLM_OK; 661 CURLcode result = CURLE_OK; 662 struct curltime before; 663 int without_fds = 0; /* count number of consecutive returns from 664 curl_multi_wait() without any filedescriptors */ 665 666 while(!done && !mcode) { 667 int still_running = 0; 668 int rc; 669 670 before = Curl_now(); 671 mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc); 672 673 if(!mcode) { 674 if(!rc) { 675 struct curltime after = Curl_now(); 676 677 /* If it returns without any filedescriptor instantly, we need to 678 avoid busy-looping during periods where it has nothing particular 679 to wait for */ 680 if(Curl_timediff(after, before) <= 10) { 681 without_fds++; 682 if(without_fds > 2) { 683 int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000; 684 Curl_wait_ms(sleep_ms); 685 } 686 } 687 else 688 /* it wasn't "instant", restart counter */ 689 without_fds = 0; 690 } 691 else 692 /* got file descriptor, restart counter */ 693 without_fds = 0; 694 695 mcode = curl_multi_perform(multi, &still_running); 696 } 697 698 /* only read 'still_running' if curl_multi_perform() return OK */ 699 if(!mcode && !still_running) { 700 CURLMsg *msg = curl_multi_info_read(multi, &rc); 701 if(msg) { 702 result = msg->data.result; 703 done = TRUE; 704 } 705 } 706 } 707 708 /* Make sure to return some kind of error if there was a multi problem */ 709 if(mcode) { 710 result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : 711 /* The other multi errors should never happen, so return 712 something suitably generic */ 713 CURLE_BAD_FUNCTION_ARGUMENT; 714 } 715 716 return result; 717 } 718 719 720 /* 721 * easy_perform() is the external interface that performs a blocking 722 * transfer as previously setup. 723 * 724 * CONCEPT: This function creates a multi handle, adds the easy handle to it, 725 * runs curl_multi_perform() until the transfer is done, then detaches the 726 * easy handle, destroys the multi handle and returns the easy handle's return 727 * code. 728 * 729 * REALITY: it can't just create and destroy the multi handle that easily. It 730 * needs to keep it around since if this easy handle is used again by this 731 * function, the same multi handle must be re-used so that the same pools and 732 * caches can be used. 733 * 734 * DEBUG: if 'events' is set TRUE, this function will use a replacement engine 735 * instead of curl_multi_perform() and use curl_multi_socket_action(). 736 */ 737 static CURLcode easy_perform(struct Curl_easy *data, bool events) 738 { 739 struct Curl_multi *multi; 740 CURLMcode mcode; 741 CURLcode result = CURLE_OK; 742 SIGPIPE_VARIABLE(pipe_st); 743 744 if(!data) 745 return CURLE_BAD_FUNCTION_ARGUMENT; 746 747 if(data->multi) { 748 failf(data, "easy handle already used in multi handle"); 749 return CURLE_FAILED_INIT; 750 } 751 752 if(data->multi_easy) 753 multi = data->multi_easy; 754 else { 755 /* this multi handle will only ever have a single easy handled attached 756 to it, so make it use minimal hashes */ 757 multi = Curl_multi_handle(1, 3); 758 if(!multi) 759 return CURLE_OUT_OF_MEMORY; 760 data->multi_easy = multi; 761 } 762 763 /* Copy the MAXCONNECTS option to the multi handle */ 764 curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects); 765 766 mcode = curl_multi_add_handle(multi, data); 767 if(mcode) { 768 curl_multi_cleanup(multi); 769 if(mcode == CURLM_OUT_OF_MEMORY) 770 return CURLE_OUT_OF_MEMORY; 771 return CURLE_FAILED_INIT; 772 } 773 774 sigpipe_ignore(data, &pipe_st); 775 776 /* assign this after curl_multi_add_handle() since that function checks for 777 it and rejects this handle otherwise */ 778 data->multi = multi; 779 780 /* run the transfer */ 781 result = events ? easy_events(multi) : easy_transfer(multi); 782 783 /* ignoring the return code isn't nice, but atm we can't really handle 784 a failure here, room for future improvement! */ 785 (void)curl_multi_remove_handle(multi, data); 786 787 sigpipe_restore(&pipe_st); 788 789 /* The multi handle is kept alive, owned by the easy handle */ 790 return result; 791 } 792 793 794 /* 795 * curl_easy_perform() is the external interface that performs a blocking 796 * transfer as previously setup. 797 */ 798 CURLcode curl_easy_perform(struct Curl_easy *data) 799 { 800 return easy_perform(data, FALSE); 801 } 802 803 #ifdef CURLDEBUG 804 /* 805 * curl_easy_perform_ev() is the external interface that performs a blocking 806 * transfer using the event-based API internally. 807 */ 808 CURLcode curl_easy_perform_ev(struct Curl_easy *data) 809 { 810 return easy_perform(data, TRUE); 811 } 812 813 #endif 814 815 /* 816 * curl_easy_cleanup() is the external interface to cleaning/freeing the given 817 * easy handle. 818 */ 819 void curl_easy_cleanup(struct Curl_easy *data) 820 { 821 SIGPIPE_VARIABLE(pipe_st); 822 823 if(!data) 824 return; 825 826 sigpipe_ignore(data, &pipe_st); 827 Curl_close(data); 828 sigpipe_restore(&pipe_st); 829 } 830 831 /* 832 * curl_easy_getinfo() is an external interface that allows an app to retrieve 833 * information from a performed transfer and similar. 834 */ 835 #undef curl_easy_getinfo 836 CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...) 837 { 838 va_list arg; 839 void *paramp; 840 CURLcode result; 841 842 va_start(arg, info); 843 paramp = va_arg(arg, void *); 844 845 result = Curl_getinfo(data, info, paramp); 846 847 va_end(arg); 848 return result; 849 } 850 851 static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) 852 { 853 CURLcode result = CURLE_OK; 854 enum dupstring i; 855 856 /* Copy src->set into dst->set first, then deal with the strings 857 afterwards */ 858 dst->set = src->set; 859 Curl_mime_initpart(&dst->set.mimepost, dst); 860 861 /* clear all string pointers first */ 862 memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); 863 864 /* duplicate all strings */ 865 for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { 866 result = Curl_setstropt(&dst->set.str[i], src->set.str[i]); 867 if(result) 868 return result; 869 } 870 871 /* duplicate memory areas pointed to */ 872 i = STRING_COPYPOSTFIELDS; 873 if(src->set.postfieldsize && src->set.str[i]) { 874 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ 875 dst->set.str[i] = Curl_memdup(src->set.str[i], 876 curlx_sotouz(src->set.postfieldsize)); 877 if(!dst->set.str[i]) 878 return CURLE_OUT_OF_MEMORY; 879 /* point to the new copy */ 880 dst->set.postfields = dst->set.str[i]; 881 } 882 883 /* Duplicate mime data. */ 884 result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost); 885 886 return result; 887 } 888 889 /* 890 * curl_easy_duphandle() is an external interface to allow duplication of a 891 * given input easy handle. The returned handle will be a new working handle 892 * with all options set exactly as the input source handle. 893 */ 894 struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) 895 { 896 struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy)); 897 if(NULL == outcurl) 898 goto fail; 899 900 /* 901 * We setup a few buffers we need. We should probably make them 902 * get setup on-demand in the code, as that would probably decrease 903 * the likeliness of us forgetting to init a buffer here in the future. 904 */ 905 outcurl->set.buffer_size = data->set.buffer_size; 906 outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1); 907 if(!outcurl->state.buffer) 908 goto fail; 909 910 outcurl->state.headerbuff = malloc(HEADERSIZE); 911 if(!outcurl->state.headerbuff) 912 goto fail; 913 outcurl->state.headersize = HEADERSIZE; 914 915 /* copy all userdefined values */ 916 if(dupset(outcurl, data)) 917 goto fail; 918 919 /* the connection cache is setup on demand */ 920 outcurl->state.conn_cache = NULL; 921 922 outcurl->state.lastconnect = NULL; 923 924 outcurl->progress.flags = data->progress.flags; 925 outcurl->progress.callback = data->progress.callback; 926 927 if(data->cookies) { 928 /* If cookies are enabled in the parent handle, we enable them 929 in the clone as well! */ 930 outcurl->cookies = Curl_cookie_init(data, 931 data->cookies->filename, 932 outcurl->cookies, 933 data->set.cookiesession); 934 if(!outcurl->cookies) 935 goto fail; 936 } 937 938 /* duplicate all values in 'change' */ 939 if(data->change.cookielist) { 940 outcurl->change.cookielist = 941 Curl_slist_duplicate(data->change.cookielist); 942 if(!outcurl->change.cookielist) 943 goto fail; 944 } 945 946 if(data->change.url) { 947 outcurl->change.url = strdup(data->change.url); 948 if(!outcurl->change.url) 949 goto fail; 950 outcurl->change.url_alloc = TRUE; 951 } 952 953 if(data->change.referer) { 954 outcurl->change.referer = strdup(data->change.referer); 955 if(!outcurl->change.referer) 956 goto fail; 957 outcurl->change.referer_alloc = TRUE; 958 } 959 960 /* Clone the resolver handle, if present, for the new handle */ 961 if(Curl_resolver_duphandle(&outcurl->state.resolver, 962 data->state.resolver)) 963 goto fail; 964 965 Curl_convert_setup(outcurl); 966 967 Curl_initinfo(outcurl); 968 969 outcurl->magic = CURLEASY_MAGIC_NUMBER; 970 971 /* we reach this point and thus we are OK */ 972 973 return outcurl; 974 975 fail: 976 977 if(outcurl) { 978 curl_slist_free_all(outcurl->change.cookielist); 979 outcurl->change.cookielist = NULL; 980 Curl_safefree(outcurl->state.buffer); 981 Curl_safefree(outcurl->state.headerbuff); 982 Curl_safefree(outcurl->change.url); 983 Curl_safefree(outcurl->change.referer); 984 Curl_freeset(outcurl); 985 free(outcurl); 986 } 987 988 return NULL; 989 } 990 991 /* 992 * curl_easy_reset() is an external interface that allows an app to re- 993 * initialize a session handle to the default values. 994 */ 995 void curl_easy_reset(struct Curl_easy *data) 996 { 997 Curl_safefree(data->state.pathbuffer); 998 999 data->state.path = NULL; 1000 1001 Curl_free_request_state(data); 1002 1003 /* zero out UserDefined data: */ 1004 Curl_freeset(data); 1005 memset(&data->set, 0, sizeof(struct UserDefined)); 1006 (void)Curl_init_userdefined(data); 1007 1008 /* zero out Progress data: */ 1009 memset(&data->progress, 0, sizeof(struct Progress)); 1010 1011 /* zero out PureInfo data: */ 1012 Curl_initinfo(data); 1013 1014 data->progress.flags |= PGRS_HIDE; 1015 data->state.current_speed = -1; /* init to negative == impossible */ 1016 1017 /* zero out authentication data: */ 1018 memset(&data->state.authhost, 0, sizeof(struct auth)); 1019 memset(&data->state.authproxy, 0, sizeof(struct auth)); 1020 } 1021 1022 /* 1023 * curl_easy_pause() allows an application to pause or unpause a specific 1024 * transfer and direction. This function sets the full new state for the 1025 * current connection this easy handle operates on. 1026 * 1027 * NOTE: if you have the receiving paused and you call this function to remove 1028 * the pausing, you may get your write callback called at this point. 1029 * 1030 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h 1031 */ 1032 CURLcode curl_easy_pause(struct Curl_easy *data, int action) 1033 { 1034 struct SingleRequest *k = &data->req; 1035 CURLcode result = CURLE_OK; 1036 1037 /* first switch off both pause bits */ 1038 int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); 1039 1040 /* set the new desired pause bits */ 1041 newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | 1042 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0); 1043 1044 /* put it back in the keepon */ 1045 k->keepon = newstate; 1046 1047 if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) { 1048 /* there are buffers for sending that can be delivered as the receive 1049 pausing is lifted! */ 1050 unsigned int i; 1051 unsigned int count = data->state.tempcount; 1052 struct tempbuf writebuf[3]; /* there can only be three */ 1053 struct connectdata *conn = data->easy_conn; 1054 struct Curl_easy *saved_data = NULL; 1055 1056 /* copy the structs to allow for immediate re-pausing */ 1057 for(i = 0; i < data->state.tempcount; i++) { 1058 writebuf[i] = data->state.tempwrite[i]; 1059 data->state.tempwrite[i].buf = NULL; 1060 } 1061 data->state.tempcount = 0; 1062 1063 /* set the connection's current owner */ 1064 if(conn->data != data) { 1065 saved_data = conn->data; 1066 conn->data = data; 1067 } 1068 1069 for(i = 0; i < count; i++) { 1070 /* even if one function returns error, this loops through and frees all 1071 buffers */ 1072 if(!result) 1073 result = Curl_client_chop_write(conn, 1074 writebuf[i].type, 1075 writebuf[i].buf, 1076 writebuf[i].len); 1077 free(writebuf[i].buf); 1078 } 1079 1080 /* recover previous owner of the connection */ 1081 if(saved_data) 1082 conn->data = saved_data; 1083 1084 if(result) 1085 return result; 1086 } 1087 1088 /* if there's no error and we're not pausing both directions, we want 1089 to have this handle checked soon */ 1090 if(!result && 1091 ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != 1092 (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) ) 1093 Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ 1094 1095 return result; 1096 } 1097 1098 1099 static CURLcode easy_connection(struct Curl_easy *data, 1100 curl_socket_t *sfd, 1101 struct connectdata **connp) 1102 { 1103 if(data == NULL) 1104 return CURLE_BAD_FUNCTION_ARGUMENT; 1105 1106 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */ 1107 if(!data->set.connect_only) { 1108 failf(data, "CONNECT_ONLY is required!"); 1109 return CURLE_UNSUPPORTED_PROTOCOL; 1110 } 1111 1112 *sfd = Curl_getconnectinfo(data, connp); 1113 1114 if(*sfd == CURL_SOCKET_BAD) { 1115 failf(data, "Failed to get recent socket"); 1116 return CURLE_UNSUPPORTED_PROTOCOL; 1117 } 1118 1119 return CURLE_OK; 1120 } 1121 1122 /* 1123 * Receives data from the connected socket. Use after successful 1124 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 1125 * Returns CURLE_OK on success, error code on error. 1126 */ 1127 CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen, 1128 size_t *n) 1129 { 1130 curl_socket_t sfd; 1131 CURLcode result; 1132 ssize_t n1; 1133 struct connectdata *c; 1134 1135 result = easy_connection(data, &sfd, &c); 1136 if(result) 1137 return result; 1138 1139 *n = 0; 1140 result = Curl_read(c, sfd, buffer, buflen, &n1); 1141 1142 if(result) 1143 return result; 1144 1145 *n = (size_t)n1; 1146 1147 return CURLE_OK; 1148 } 1149 1150 /* 1151 * Sends data over the connected socket. Use after successful 1152 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. 1153 */ 1154 CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, 1155 size_t buflen, size_t *n) 1156 { 1157 curl_socket_t sfd; 1158 CURLcode result; 1159 ssize_t n1; 1160 struct connectdata *c = NULL; 1161 1162 result = easy_connection(data, &sfd, &c); 1163 if(result) 1164 return result; 1165 1166 *n = 0; 1167 result = Curl_write(c, sfd, buffer, buflen, &n1); 1168 1169 if(n1 == -1) 1170 return CURLE_SEND_ERROR; 1171 1172 /* detect EAGAIN */ 1173 if(!result && !n1) 1174 return CURLE_AGAIN; 1175 1176 *n = (size_t)n1; 1177 1178 return result; 1179 } 1180