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