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