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