1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25#include "curl_setup.h" 26 27#include <curl/curl.h> 28 29#include "urldata.h" 30#include "transfer.h" 31#include "url.h" 32#include "cfilters.h" 33#include "connect.h" 34#include "progress.h" 35#include "easyif.h" 36#include "share.h" 37#include "psl.h" 38#include "multiif.h" 39#include "sendf.h" 40#include "timeval.h" 41#include "http.h" 42#include "select.h" 43#include "warnless.h" 44#include "speedcheck.h" 45#include "conncache.h" 46#include "multihandle.h" 47#include "sigpipe.h" 48#include "vtls/vtls.h" 49#include "http_proxy.h" 50#include "http2.h" 51#include "socketpair.h" 52#include "socks.h" 53/* The last 3 #include files should be in this order */ 54#include "curl_printf.h" 55#include "curl_memory.h" 56#include "memdebug.h" 57 58/* 59 CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 60 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every 61 CURL handle takes 45-50 K memory, therefore this 3K are not significant. 62*/ 63#ifndef CURL_SOCKET_HASH_TABLE_SIZE 64#define CURL_SOCKET_HASH_TABLE_SIZE 911 65#endif 66 67#ifndef CURL_CONNECTION_HASH_SIZE 68#define CURL_CONNECTION_HASH_SIZE 97 69#endif 70 71#ifndef CURL_DNS_HASH_SIZE 72#define CURL_DNS_HASH_SIZE 71 73#endif 74 75#define CURL_MULTI_HANDLE 0x000bab1e 76 77#ifdef DEBUGBUILD 78/* On a debug build, we want to fail hard on multi handles that 79 * are not NULL, but no longer have the MAGIC touch. This gives 80 * us early warning on things only discovered by valgrind otherwise. */ 81#define GOOD_MULTI_HANDLE(x) \ 82 (((x) && (x)->magic == CURL_MULTI_HANDLE)? TRUE: \ 83 (DEBUGASSERT(!(x)), FALSE)) 84#else 85#define GOOD_MULTI_HANDLE(x) \ 86 ((x) && (x)->magic == CURL_MULTI_HANDLE) 87#endif 88 89static CURLMcode singlesocket(struct Curl_multi *multi, 90 struct Curl_easy *data); 91static CURLMcode add_next_timeout(struct curltime now, 92 struct Curl_multi *multi, 93 struct Curl_easy *d); 94static CURLMcode multi_timeout(struct Curl_multi *multi, 95 long *timeout_ms); 96static void process_pending_handles(struct Curl_multi *multi); 97 98#ifdef DEBUGBUILD 99static const char * const multi_statename[]={ 100 "INIT", 101 "PENDING", 102 "CONNECT", 103 "RESOLVING", 104 "CONNECTING", 105 "TUNNELING", 106 "PROTOCONNECT", 107 "PROTOCONNECTING", 108 "DO", 109 "DOING", 110 "DOING_MORE", 111 "DID", 112 "PERFORMING", 113 "RATELIMITING", 114 "DONE", 115 "COMPLETED", 116 "MSGSENT", 117}; 118#endif 119 120/* function pointer called once when switching TO a state */ 121typedef void (*init_multistate_func)(struct Curl_easy *data); 122 123/* called in DID state, before PERFORMING state */ 124static void before_perform(struct Curl_easy *data) 125{ 126 data->req.chunk = FALSE; 127 Curl_pgrsTime(data, TIMER_PRETRANSFER); 128} 129 130static void init_completed(struct Curl_easy *data) 131{ 132 /* this is a completed transfer */ 133 134 /* Important: reset the conn pointer so that we don't point to memory 135 that could be freed anytime */ 136 Curl_detach_connection(data); 137 Curl_expire_clear(data); /* stop all timers */ 138} 139 140/* always use this function to change state, to make debugging easier */ 141static void mstate(struct Curl_easy *data, CURLMstate state 142#ifdef DEBUGBUILD 143 , int lineno 144#endif 145) 146{ 147 CURLMstate oldstate = data->mstate; 148 static const init_multistate_func finit[MSTATE_LAST] = { 149 NULL, /* INIT */ 150 NULL, /* PENDING */ 151 Curl_init_CONNECT, /* CONNECT */ 152 NULL, /* RESOLVING */ 153 NULL, /* CONNECTING */ 154 NULL, /* TUNNELING */ 155 NULL, /* PROTOCONNECT */ 156 NULL, /* PROTOCONNECTING */ 157 NULL, /* DO */ 158 NULL, /* DOING */ 159 NULL, /* DOING_MORE */ 160 before_perform, /* DID */ 161 NULL, /* PERFORMING */ 162 NULL, /* RATELIMITING */ 163 NULL, /* DONE */ 164 init_completed, /* COMPLETED */ 165 NULL /* MSGSENT */ 166 }; 167 168#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS) 169 (void) lineno; 170#endif 171 172 if(oldstate == state) 173 /* don't bother when the new state is the same as the old state */ 174 return; 175 176 data->mstate = state; 177 178#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) 179 if(data->mstate >= MSTATE_PENDING && 180 data->mstate < MSTATE_COMPLETED) { 181 infof(data, 182 "STATE: %s => %s handle %p; line %d", 183 multi_statename[oldstate], multi_statename[data->mstate], 184 (void *)data, lineno); 185 } 186#endif 187 188 if(state == MSTATE_COMPLETED) { 189 /* changing to COMPLETED means there's one less easy handle 'alive' */ 190 DEBUGASSERT(data->multi->num_alive > 0); 191 data->multi->num_alive--; 192 } 193 194 /* if this state has an init-function, run it */ 195 if(finit[state]) 196 finit[state](data); 197} 198 199#ifndef DEBUGBUILD 200#define multistate(x,y) mstate(x,y) 201#else 202#define multistate(x,y) mstate(x,y, __LINE__) 203#endif 204 205/* 206 * We add one of these structs to the sockhash for each socket 207 */ 208 209struct Curl_sh_entry { 210 struct Curl_hash transfers; /* hash of transfers using this socket */ 211 unsigned int action; /* what combined action READ/WRITE this socket waits 212 for */ 213 unsigned int users; /* number of transfers using this */ 214 void *socketp; /* settable by users with curl_multi_assign() */ 215 unsigned int readers; /* this many transfers want to read */ 216 unsigned int writers; /* this many transfers want to write */ 217}; 218 219/* look up a given socket in the socket hash, skip invalid sockets */ 220static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh, 221 curl_socket_t s) 222{ 223 if(s != CURL_SOCKET_BAD) { 224 /* only look for proper sockets */ 225 return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t)); 226 } 227 return NULL; 228} 229 230#define TRHASH_SIZE 13 231static size_t trhash(void *key, size_t key_length, size_t slots_num) 232{ 233 size_t keyval = (size_t)*(struct Curl_easy **)key; 234 (void) key_length; 235 236 return (keyval % slots_num); 237} 238 239static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) 240{ 241 (void)k1_len; 242 (void)k2_len; 243 244 return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2; 245} 246 247static void trhash_dtor(void *nada) 248{ 249 (void)nada; 250} 251 252/* 253 * The sockhash has its own separate subhash in each entry that need to be 254 * safely destroyed first. 255 */ 256static void sockhash_destroy(struct Curl_hash *h) 257{ 258 struct Curl_hash_iterator iter; 259 struct Curl_hash_element *he; 260 261 DEBUGASSERT(h); 262 Curl_hash_start_iterate(h, &iter); 263 he = Curl_hash_next_element(&iter); 264 while(he) { 265 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)he->ptr; 266 Curl_hash_destroy(&sh->transfers); 267 he = Curl_hash_next_element(&iter); 268 } 269 Curl_hash_destroy(h); 270} 271 272 273/* make sure this socket is present in the hash for this handle */ 274static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh, 275 curl_socket_t s) 276{ 277 struct Curl_sh_entry *there = sh_getentry(sh, s); 278 struct Curl_sh_entry *check; 279 280 if(there) { 281 /* it is present, return fine */ 282 return there; 283 } 284 285 /* not present, add it */ 286 check = calloc(1, sizeof(struct Curl_sh_entry)); 287 if(!check) 288 return NULL; /* major failure */ 289 290 Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, trhash_compare, 291 trhash_dtor); 292 293 /* make/add new hash entry */ 294 if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { 295 Curl_hash_destroy(&check->transfers); 296 free(check); 297 return NULL; /* major failure */ 298 } 299 300 return check; /* things are good in sockhash land */ 301} 302 303 304/* delete the given socket + handle from the hash */ 305static void sh_delentry(struct Curl_sh_entry *entry, 306 struct Curl_hash *sh, curl_socket_t s) 307{ 308 Curl_hash_destroy(&entry->transfers); 309 310 /* We remove the hash entry. This will end up in a call to 311 sh_freeentry(). */ 312 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t)); 313} 314 315/* 316 * free a sockhash entry 317 */ 318static void sh_freeentry(void *freethis) 319{ 320 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis; 321 322 free(p); 323} 324 325static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) 326{ 327 (void) k1_len; (void) k2_len; 328 329 return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2)); 330} 331 332static size_t hash_fd(void *key, size_t key_length, size_t slots_num) 333{ 334 curl_socket_t fd = *((curl_socket_t *) key); 335 (void) key_length; 336 337 return (fd % slots_num); 338} 339 340/* 341 * sh_init() creates a new socket hash and returns the handle for it. 342 * 343 * Quote from README.multi_socket: 344 * 345 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup 346 * is somewhat of a bottle neck. Its current implementation may be a bit too 347 * limiting. It simply has a fixed-size array, and on each entry in the array 348 * it has a linked list with entries. So the hash only checks which list to 349 * scan through. The code I had used so for used a list with merely 7 slots 350 * (as that is what the DNS hash uses) but with 7000 connections that would 351 * make an average of 1000 nodes in each list to run through. I upped that to 352 * 97 slots (I believe a prime is suitable) and noticed a significant speed 353 * increase. I need to reconsider the hash implementation or use a rather 354 * large default value like this. At 9000 connections I was still below 10us 355 * per call." 356 * 357 */ 358static void sh_init(struct Curl_hash *hash, int hashsize) 359{ 360 Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare, 361 sh_freeentry); 362} 363 364/* 365 * multi_addmsg() 366 * 367 * Called when a transfer is completed. Adds the given msg pointer to 368 * the list kept in the multi handle. 369 */ 370static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg) 371{ 372 Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg, 373 &msg->list); 374} 375 376struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ 377 int chashsize, /* connection hash */ 378 int dnssize) /* dns hash */ 379{ 380 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); 381 382 if(!multi) 383 return NULL; 384 385 multi->magic = CURL_MULTI_HANDLE; 386 387 Curl_init_dnscache(&multi->hostcache, dnssize); 388 389 sh_init(&multi->sockhash, hashsize); 390 391 if(Curl_conncache_init(&multi->conn_cache, chashsize)) 392 goto error; 393 394 Curl_llist_init(&multi->msglist, NULL); 395 Curl_llist_init(&multi->pending, NULL); 396 Curl_llist_init(&multi->msgsent, NULL); 397 398 multi->multiplexing = TRUE; 399 multi->max_concurrent_streams = 100; 400 401#ifdef USE_WINSOCK 402 multi->wsa_event = WSACreateEvent(); 403 if(multi->wsa_event == WSA_INVALID_EVENT) 404 goto error; 405#else 406#ifdef ENABLE_WAKEUP 407 if(wakeup_create(multi->wakeup_pair) < 0) { 408 multi->wakeup_pair[0] = CURL_SOCKET_BAD; 409 multi->wakeup_pair[1] = CURL_SOCKET_BAD; 410 } 411 else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 || 412 curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) { 413 wakeup_close(multi->wakeup_pair[0]); 414 wakeup_close(multi->wakeup_pair[1]); 415 multi->wakeup_pair[0] = CURL_SOCKET_BAD; 416 multi->wakeup_pair[1] = CURL_SOCKET_BAD; 417 } 418#endif 419#endif 420 421 return multi; 422 423error: 424 425 sockhash_destroy(&multi->sockhash); 426 Curl_hash_destroy(&multi->hostcache); 427 Curl_conncache_destroy(&multi->conn_cache); 428 free(multi); 429 return NULL; 430} 431 432struct Curl_multi *curl_multi_init(void) 433{ 434 return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE, 435 CURL_CONNECTION_HASH_SIZE, 436 CURL_DNS_HASH_SIZE); 437} 438 439#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) 440static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data) 441{ 442 if(!multi->warned) { 443 infof(data, "!!! WARNING !!!"); 444 infof(data, "This is a debug build of libcurl, " 445 "do not use in production."); 446 multi->warned = true; 447 } 448} 449#else 450#define multi_warn_debug(x,y) Curl_nop_stmt 451#endif 452 453/* returns TRUE if the easy handle is supposed to be present in the main link 454 list */ 455static bool in_main_list(struct Curl_easy *data) 456{ 457 return ((data->mstate != MSTATE_PENDING) && 458 (data->mstate != MSTATE_MSGSENT)); 459} 460 461static void link_easy(struct Curl_multi *multi, 462 struct Curl_easy *data) 463{ 464 /* We add the new easy entry last in the list. */ 465 data->next = NULL; /* end of the line */ 466 if(multi->easyp) { 467 struct Curl_easy *last = multi->easylp; 468 last->next = data; 469 data->prev = last; 470 multi->easylp = data; /* the new last node */ 471 } 472 else { 473 /* first node, make prev NULL! */ 474 data->prev = NULL; 475 multi->easylp = multi->easyp = data; /* both first and last */ 476 } 477} 478 479/* unlink the given easy handle from the linked list of easy handles */ 480static void unlink_easy(struct Curl_multi *multi, 481 struct Curl_easy *data) 482{ 483 /* make the previous node point to our next */ 484 if(data->prev) 485 data->prev->next = data->next; 486 else 487 multi->easyp = data->next; /* point to first node */ 488 489 /* make our next point to our previous node */ 490 if(data->next) 491 data->next->prev = data->prev; 492 else 493 multi->easylp = data->prev; /* point to last node */ 494 495 data->prev = data->next = NULL; 496} 497 498 499CURLMcode curl_multi_add_handle(struct Curl_multi *multi, 500 struct Curl_easy *data) 501{ 502 CURLMcode rc; 503 /* First, make some basic checks that the CURLM handle is a good handle */ 504 if(!GOOD_MULTI_HANDLE(multi)) 505 return CURLM_BAD_HANDLE; 506 507 /* Verify that we got a somewhat good easy handle too */ 508 if(!GOOD_EASY_HANDLE(data)) 509 return CURLM_BAD_EASY_HANDLE; 510 511 /* Prevent users from adding same easy handle more than once and prevent 512 adding to more than one multi stack */ 513 if(data->multi) 514 return CURLM_ADDED_ALREADY; 515 516 if(multi->in_callback) 517 return CURLM_RECURSIVE_API_CALL; 518 519 if(multi->dead) { 520 /* a "dead" handle cannot get added transfers while any existing easy 521 handles are still alive - but if there are none alive anymore, it is 522 fine to start over and unmark the "deadness" of this handle */ 523 if(multi->num_alive) 524 return CURLM_ABORTED_BY_CALLBACK; 525 multi->dead = FALSE; 526 } 527 528 /* Initialize timeout list for this handle */ 529 Curl_llist_init(&data->state.timeoutlist, NULL); 530 531 /* 532 * No failure allowed in this function beyond this point. And no 533 * modification of easy nor multi handle allowed before this except for 534 * potential multi's connection cache growing which won't be undone in this 535 * function no matter what. 536 */ 537 if(data->set.errorbuffer) 538 data->set.errorbuffer[0] = 0; 539 540 /* make the Curl_easy refer back to this multi handle - before Curl_expire() 541 is called. */ 542 data->multi = multi; 543 544 /* Set the timeout for this handle to expire really soon so that it will 545 be taken care of even when this handle is added in the midst of operation 546 when only the curl_multi_socket() API is used. During that flow, only 547 sockets that time-out or have actions will be dealt with. Since this 548 handle has no action yet, we make sure it times out to get things to 549 happen. */ 550 Curl_expire(data, 0, EXPIRE_RUN_NOW); 551 552 /* A somewhat crude work-around for a little glitch in Curl_update_timer() 553 that happens if the lastcall time is set to the same time when the handle 554 is removed as when the next handle is added, as then the check in 555 Curl_update_timer() that prevents calling the application multiple times 556 with the same timer info will not trigger and then the new handle's 557 timeout will not be notified to the app. 558 559 The work-around is thus simply to clear the 'lastcall' variable to force 560 Curl_update_timer() to always trigger a callback to the app when a new 561 easy handle is added */ 562 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); 563 564 rc = Curl_update_timer(multi); 565 if(rc) 566 return rc; 567 568 /* set the easy handle */ 569 multistate(data, MSTATE_INIT); 570 571 /* for multi interface connections, we share DNS cache automatically if the 572 easy handle's one is currently not set. */ 573 if(!data->dns.hostcache || 574 (data->dns.hostcachetype == HCACHE_NONE)) { 575 data->dns.hostcache = &multi->hostcache; 576 data->dns.hostcachetype = HCACHE_MULTI; 577 } 578 579 /* Point to the shared or multi handle connection cache */ 580 if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT))) 581 data->state.conn_cache = &data->share->conn_cache; 582 else 583 data->state.conn_cache = &multi->conn_cache; 584 data->state.lastconnect_id = -1; 585 586#ifdef USE_LIBPSL 587 /* Do the same for PSL. */ 588 if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL))) 589 data->psl = &data->share->psl; 590 else 591 data->psl = &multi->psl; 592#endif 593 594 link_easy(multi, data); 595 596 /* increase the node-counter */ 597 multi->num_easy++; 598 599 /* increase the alive-counter */ 600 multi->num_alive++; 601 602 CONNCACHE_LOCK(data); 603 /* The closure handle only ever has default timeouts set. To improve the 604 state somewhat we clone the timeouts from each added handle so that the 605 closure handle always has the same timeouts as the most recently added 606 easy handle. */ 607 data->state.conn_cache->closure_handle->set.timeout = data->set.timeout; 608 data->state.conn_cache->closure_handle->set.server_response_timeout = 609 data->set.server_response_timeout; 610 data->state.conn_cache->closure_handle->set.no_signal = 611 data->set.no_signal; 612 data->id = data->state.conn_cache->next_easy_id++; 613 if(data->state.conn_cache->next_easy_id <= 0) 614 data->state.conn_cache->next_easy_id = 0; 615 CONNCACHE_UNLOCK(data); 616 617 multi_warn_debug(multi, data); 618 619 return CURLM_OK; 620} 621 622#if 0 623/* Debug-function, used like this: 624 * 625 * Curl_hash_print(&multi->sockhash, debug_print_sock_hash); 626 * 627 * Enable the hash print function first by editing hash.c 628 */ 629static void debug_print_sock_hash(void *p) 630{ 631 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p; 632 633 fprintf(stderr, " [readers %u][writers %u]", 634 sh->readers, sh->writers); 635} 636#endif 637 638static CURLcode multi_done(struct Curl_easy *data, 639 CURLcode status, /* an error if this is called 640 after an error was detected */ 641 bool premature) 642{ 643 CURLcode result; 644 struct connectdata *conn = data->conn; 645 646#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) 647 DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d", 648 multi_statename[data->mstate], 649 (int)status, (int)premature, data->state.done)); 650#else 651 DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d", 652 (int)status, (int)premature, data->state.done)); 653#endif 654 655 if(data->state.done) 656 /* Stop if multi_done() has already been called */ 657 return CURLE_OK; 658 659 /* Stop the resolver and free its own resources (but not dns_entry yet). */ 660 Curl_resolver_kill(data); 661 662 /* Cleanup possible redirect junk */ 663 Curl_safefree(data->req.newurl); 664 Curl_safefree(data->req.location); 665 666 switch(status) { 667 case CURLE_ABORTED_BY_CALLBACK: 668 case CURLE_READ_ERROR: 669 case CURLE_WRITE_ERROR: 670 /* When we're aborted due to a callback return code it basically have to 671 be counted as premature as there is trouble ahead if we don't. We have 672 many callbacks and protocols work differently, we could potentially do 673 this more fine-grained in the future. */ 674 premature = TRUE; 675 FALLTHROUGH(); 676 default: 677 break; 678 } 679 680 /* this calls the protocol-specific function pointer previously set */ 681 if(conn->handler->done) 682 result = conn->handler->done(data, status, premature); 683 else 684 result = status; 685 686 if(CURLE_ABORTED_BY_CALLBACK != result) { 687 /* avoid this if we already aborted by callback to avoid this calling 688 another callback */ 689 int rc = Curl_pgrsDone(data); 690 if(!result && rc) 691 result = CURLE_ABORTED_BY_CALLBACK; 692 } 693 694 /* Inform connection filters that this transfer is done */ 695 Curl_conn_ev_data_done(data, premature); 696 697 process_pending_handles(data->multi); /* connection / multiplex */ 698 699 Curl_safefree(data->state.ulbuf); 700 701 Curl_client_cleanup(data); 702 703 CONNCACHE_LOCK(data); 704 Curl_detach_connection(data); 705 if(CONN_INUSE(conn)) { 706 /* Stop if still used. */ 707 CONNCACHE_UNLOCK(data); 708 DEBUGF(infof(data, "Connection still in use %zu, " 709 "no more multi_done now!", 710 conn->easyq.size)); 711 return CURLE_OK; 712 } 713 714 data->state.done = TRUE; /* called just now! */ 715 716 if(conn->dns_entry) { 717 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ 718 conn->dns_entry = NULL; 719 } 720 Curl_hostcache_prune(data); 721 722 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has 723 forced us to close this connection. This is ignored for requests taking 724 place in a NTLM/NEGOTIATE authentication handshake 725 726 if conn->bits.close is TRUE, it means that the connection should be 727 closed in spite of all our efforts to be nice, due to protocol 728 restrictions in our or the server's end 729 730 if premature is TRUE, it means this connection was said to be DONE before 731 the entire request operation is complete and thus we can't know in what 732 state it is for reusing, so we're forced to close it. In a perfect world 733 we can add code that keep track of if we really must close it here or not, 734 but currently we have no such detail knowledge. 735 */ 736 737 data->state.recent_conn_id = conn->connection_id; 738 if((data->set.reuse_forbid 739#if defined(USE_NTLM) 740 && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || 741 conn->proxy_ntlm_state == NTLMSTATE_TYPE2) 742#endif 743#if defined(USE_SPNEGO) 744 && !(conn->http_negotiate_state == GSS_AUTHRECV || 745 conn->proxy_negotiate_state == GSS_AUTHRECV) 746#endif 747 ) || conn->bits.close 748 || (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) { 749 DEBUGF(infof(data, "multi_done, not reusing connection=%" 750 CURL_FORMAT_CURL_OFF_T ", forbid=%d" 751 ", close=%d, premature=%d, conn_multiplex=%d", 752 conn->connection_id, 753 data->set.reuse_forbid, conn->bits.close, premature, 754 Curl_conn_is_multiplex(conn, FIRSTSOCKET))); 755 connclose(conn, "disconnecting"); 756 Curl_conncache_remove_conn(data, conn, FALSE); 757 CONNCACHE_UNLOCK(data); 758 Curl_disconnect(data, conn, premature); 759 } 760 else { 761 char buffer[256]; 762 const char *host = 763#ifndef CURL_DISABLE_PROXY 764 conn->bits.socksproxy ? 765 conn->socks_proxy.host.dispname : 766 conn->bits.httpproxy ? conn->http_proxy.host.dispname : 767#endif 768 conn->bits.conn_to_host ? conn->conn_to_host.dispname : 769 conn->host.dispname; 770 /* create string before returning the connection */ 771 curl_off_t connection_id = conn->connection_id; 772 msnprintf(buffer, sizeof(buffer), 773 "Connection #%" CURL_FORMAT_CURL_OFF_T " to host %s left intact", 774 connection_id, host); 775 /* the connection is no longer in use by this transfer */ 776 CONNCACHE_UNLOCK(data); 777 if(Curl_conncache_return_conn(data, conn)) { 778 /* remember the most recently used connection */ 779 data->state.lastconnect_id = connection_id; 780 data->state.recent_conn_id = connection_id; 781 infof(data, "%s", buffer); 782 } 783 else 784 data->state.lastconnect_id = -1; 785 } 786 787 Curl_safefree(data->state.buffer); 788 return result; 789} 790 791static int close_connect_only(struct Curl_easy *data, 792 struct connectdata *conn, void *param) 793{ 794 (void)param; 795 if(data->state.lastconnect_id != conn->connection_id) 796 return 0; 797 798 if(!conn->connect_only) 799 return 1; 800 801 connclose(conn, "Removing connect-only easy handle"); 802 803 return 1; 804} 805 806CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, 807 struct Curl_easy *data) 808{ 809 struct Curl_easy *easy = data; 810 bool premature; 811 struct Curl_llist_element *e; 812 CURLMcode rc; 813 814 /* First, make some basic checks that the CURLM handle is a good handle */ 815 if(!GOOD_MULTI_HANDLE(multi)) 816 return CURLM_BAD_HANDLE; 817 818 /* Verify that we got a somewhat good easy handle too */ 819 if(!GOOD_EASY_HANDLE(data)) 820 return CURLM_BAD_EASY_HANDLE; 821 822 /* Prevent users from trying to remove same easy handle more than once */ 823 if(!data->multi) 824 return CURLM_OK; /* it is already removed so let's say it is fine! */ 825 826 /* Prevent users from trying to remove an easy handle from the wrong multi */ 827 if(data->multi != multi) 828 return CURLM_BAD_EASY_HANDLE; 829 830 if(multi->in_callback) 831 return CURLM_RECURSIVE_API_CALL; 832 833 premature = (data->mstate < MSTATE_COMPLETED) ? TRUE : FALSE; 834 835 /* If the 'state' is not INIT or COMPLETED, we might need to do something 836 nice to put the easy_handle in a good known state when this returns. */ 837 if(premature) { 838 /* this handle is "alive" so we need to count down the total number of 839 alive connections when this is removed */ 840 multi->num_alive--; 841 } 842 843 if(data->conn && 844 data->mstate > MSTATE_DO && 845 data->mstate < MSTATE_COMPLETED) { 846 /* Set connection owner so that the DONE function closes it. We can 847 safely do this here since connection is killed. */ 848 streamclose(data->conn, "Removed with partial response"); 849 } 850 851 if(data->conn) { 852 /* multi_done() clears the association between the easy handle and the 853 connection. 854 855 Note that this ignores the return code simply because there's 856 nothing really useful to do with it anyway! */ 857 (void)multi_done(data, data->result, premature); 858 } 859 860 /* The timer must be shut down before data->multi is set to NULL, else the 861 timenode will remain in the splay tree after curl_easy_cleanup is 862 called. Do it after multi_done() in case that sets another time! */ 863 Curl_expire_clear(data); 864 865 if(data->connect_queue.ptr) { 866 /* the handle is in the pending or msgsent lists, so go ahead and remove 867 it */ 868 if(data->mstate == MSTATE_PENDING) 869 Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); 870 else 871 Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL); 872 } 873 if(in_main_list(data)) 874 unlink_easy(multi, data); 875 876 if(data->dns.hostcachetype == HCACHE_MULTI) { 877 /* stop using the multi handle's DNS cache, *after* the possible 878 multi_done() call above */ 879 data->dns.hostcache = NULL; 880 data->dns.hostcachetype = HCACHE_NONE; 881 } 882 883 Curl_wildcard_dtor(&data->wildcard); 884 885 /* change state without using multistate(), only to make singlesocket() do 886 what we want */ 887 data->mstate = MSTATE_COMPLETED; 888 889 /* This ignores the return code even in case of problems because there's 890 nothing more to do about that, here */ 891 (void)singlesocket(multi, easy); /* to let the application know what sockets 892 that vanish with this handle */ 893 894 /* Remove the association between the connection and the handle */ 895 Curl_detach_connection(data); 896 897 if(data->set.connect_only && !data->multi_easy) { 898 /* This removes a handle that was part the multi interface that used 899 CONNECT_ONLY, that connection is now left alive but since this handle 900 has bits.close set nothing can use that transfer anymore and it is 901 forbidden from reuse. And this easy handle cannot find the connection 902 anymore once removed from the multi handle 903 904 Better close the connection here, at once. 905 */ 906 struct connectdata *c; 907 curl_socket_t s; 908 s = Curl_getconnectinfo(data, &c); 909 if((s != CURL_SOCKET_BAD) && c) { 910 Curl_conncache_remove_conn(data, c, TRUE); 911 Curl_disconnect(data, c, TRUE); 912 } 913 } 914 915 if(data->state.lastconnect_id != -1) { 916 /* Mark any connect-only connection for closure */ 917 Curl_conncache_foreach(data, data->state.conn_cache, 918 NULL, close_connect_only); 919 } 920 921#ifdef USE_LIBPSL 922 /* Remove the PSL association. */ 923 if(data->psl == &multi->psl) 924 data->psl = NULL; 925#endif 926 927 /* as this was using a shared connection cache we clear the pointer to that 928 since we're not part of that multi handle anymore */ 929 data->state.conn_cache = NULL; 930 931 data->multi = NULL; /* clear the association to this multi handle */ 932 933 /* make sure there's no pending message in the queue sent from this easy 934 handle */ 935 for(e = multi->msglist.head; e; e = e->next) { 936 struct Curl_message *msg = e->ptr; 937 938 if(msg->extmsg.easy_handle == easy) { 939 Curl_llist_remove(&multi->msglist, e, NULL); 940 /* there can only be one from this specific handle */ 941 break; 942 } 943 } 944 945 /* NOTE NOTE NOTE 946 We do not touch the easy handle here! */ 947 multi->num_easy--; /* one less to care about now */ 948 949 process_pending_handles(multi); 950 951 rc = Curl_update_timer(multi); 952 if(rc) 953 return rc; 954 return CURLM_OK; 955} 956 957/* Return TRUE if the application asked for multiplexing */ 958bool Curl_multiplex_wanted(const struct Curl_multi *multi) 959{ 960 return (multi && (multi->multiplexing)); 961} 962 963/* 964 * Curl_detach_connection() removes the given transfer from the connection. 965 * 966 * This is the only function that should clear data->conn. This will 967 * occasionally be called with the data->conn pointer already cleared. 968 */ 969void Curl_detach_connection(struct Curl_easy *data) 970{ 971 struct connectdata *conn = data->conn; 972 if(conn) { 973 Curl_conn_ev_data_detach(conn, data); 974 Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); 975 } 976 data->conn = NULL; 977} 978 979/* 980 * Curl_attach_connection() attaches this transfer to this connection. 981 * 982 * This is the only function that should assign data->conn 983 */ 984void Curl_attach_connection(struct Curl_easy *data, 985 struct connectdata *conn) 986{ 987 DEBUGASSERT(!data->conn); 988 DEBUGASSERT(conn); 989 data->conn = conn; 990 Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, 991 &data->conn_queue); 992 if(conn->handler && conn->handler->attach) 993 conn->handler->attach(data, conn); 994 Curl_conn_ev_data_attach(conn, data); 995} 996 997static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks) 998{ 999 struct connectdata *conn = data->conn; 1000 (void)socks; 1001 /* Not using `conn->sockfd` as `Curl_setup_transfer()` initializes 1002 * that *after* the connect. */ 1003 if(conn && conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD) { 1004 /* Default is to wait to something from the server */ 1005 socks[0] = conn->sock[FIRSTSOCKET]; 1006 return GETSOCK_READSOCK(0); 1007 } 1008 return GETSOCK_BLANK; 1009} 1010 1011static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks) 1012{ 1013 struct connectdata *conn = data->conn; 1014 if(conn && conn->handler->proto_getsock) 1015 return conn->handler->proto_getsock(data, conn, socks); 1016 else if(conn && conn->sockfd != CURL_SOCKET_BAD) { 1017 /* Default is to wait to something from the server */ 1018 socks[0] = conn->sockfd; 1019 return GETSOCK_READSOCK(0); 1020 } 1021 return GETSOCK_BLANK; 1022} 1023 1024static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks) 1025{ 1026 struct connectdata *conn = data->conn; 1027 if(conn && conn->handler->domore_getsock) 1028 return conn->handler->domore_getsock(data, conn, socks); 1029 else if(conn && conn->sockfd != CURL_SOCKET_BAD) { 1030 /* Default is that we want to send something to the server */ 1031 socks[0] = conn->sockfd; 1032 return GETSOCK_WRITESOCK(0); 1033 } 1034 return GETSOCK_BLANK; 1035} 1036 1037static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks) 1038{ 1039 struct connectdata *conn = data->conn; 1040 if(conn && conn->handler->doing_getsock) 1041 return conn->handler->doing_getsock(data, conn, socks); 1042 else if(conn && conn->sockfd != CURL_SOCKET_BAD) { 1043 /* Default is that we want to send something to the server */ 1044 socks[0] = conn->sockfd; 1045 return GETSOCK_WRITESOCK(0); 1046 } 1047 return GETSOCK_BLANK; 1048} 1049 1050static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock) 1051{ 1052 struct connectdata *conn = data->conn; 1053 1054 if(!conn) 1055 return GETSOCK_BLANK; 1056 else if(conn->handler->perform_getsock) 1057 return conn->handler->perform_getsock(data, conn, sock); 1058 else { 1059 /* Default is to obey the data->req.keepon flags for send/recv */ 1060 int bitmap = GETSOCK_BLANK; 1061 unsigned sockindex = 0; 1062 if(CURL_WANT_RECV(data)) { 1063 DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD); 1064 bitmap |= GETSOCK_READSOCK(sockindex); 1065 sock[sockindex] = conn->sockfd; 1066 } 1067 1068 if(CURL_WANT_SEND(data)) { 1069 if((conn->sockfd != conn->writesockfd) || 1070 bitmap == GETSOCK_BLANK) { 1071 /* only if they are not the same socket and we have a readable 1072 one, we increase index */ 1073 if(bitmap != GETSOCK_BLANK) 1074 sockindex++; /* increase index if we need two entries */ 1075 1076 DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD); 1077 sock[sockindex] = conn->writesockfd; 1078 } 1079 bitmap |= GETSOCK_WRITESOCK(sockindex); 1080 } 1081 return bitmap; 1082 } 1083} 1084 1085/* Initializes `poll_set` with the current socket poll actions needed 1086 * for transfer `data`. */ 1087static void multi_getsock(struct Curl_easy *data, 1088 struct easy_pollset *ps) 1089{ 1090 /* The no connection case can happen when this is called from 1091 curl_multi_remove_handle() => singlesocket() => multi_getsock(). 1092 */ 1093 Curl_pollset_reset(data, ps); 1094 if(!data->conn) 1095 return; 1096 1097 switch(data->mstate) { 1098 case MSTATE_INIT: 1099 case MSTATE_PENDING: 1100 case MSTATE_CONNECT: 1101 /* nothing to poll for yet */ 1102 break; 1103 1104 case MSTATE_RESOLVING: 1105 Curl_pollset_add_socks(data, ps, Curl_resolv_getsock); 1106 /* connection filters are not involved in this phase */ 1107 break; 1108 1109 case MSTATE_CONNECTING: 1110 case MSTATE_TUNNELING: 1111 Curl_pollset_add_socks(data, ps, connecting_getsock); 1112 Curl_conn_adjust_pollset(data, ps); 1113 break; 1114 1115 case MSTATE_PROTOCONNECT: 1116 case MSTATE_PROTOCONNECTING: 1117 Curl_pollset_add_socks(data, ps, protocol_getsock); 1118 Curl_conn_adjust_pollset(data, ps); 1119 break; 1120 1121 case MSTATE_DO: 1122 case MSTATE_DOING: 1123 Curl_pollset_add_socks(data, ps, doing_getsock); 1124 Curl_conn_adjust_pollset(data, ps); 1125 break; 1126 1127 case MSTATE_DOING_MORE: 1128 Curl_pollset_add_socks(data, ps, domore_getsock); 1129 Curl_conn_adjust_pollset(data, ps); 1130 break; 1131 1132 case MSTATE_DID: /* same as PERFORMING in regard to polling */ 1133 case MSTATE_PERFORMING: 1134 Curl_pollset_add_socks(data, ps, perform_getsock); 1135 Curl_conn_adjust_pollset(data, ps); 1136 break; 1137 1138 case MSTATE_RATELIMITING: 1139 /* we need to let time pass, ignore socket(s) */ 1140 break; 1141 1142 case MSTATE_DONE: 1143 case MSTATE_COMPLETED: 1144 case MSTATE_MSGSENT: 1145 /* nothing more to poll for */ 1146 break; 1147 1148 default: 1149 failf(data, "multi_getsock: unexpected multi state %d", data->mstate); 1150 DEBUGASSERT(0); 1151 break; 1152 } 1153} 1154 1155CURLMcode curl_multi_fdset(struct Curl_multi *multi, 1156 fd_set *read_fd_set, fd_set *write_fd_set, 1157 fd_set *exc_fd_set, int *max_fd) 1158{ 1159 /* Scan through all the easy handles to get the file descriptors set. 1160 Some easy handles may not have connected to the remote host yet, 1161 and then we must make sure that is done. */ 1162 struct Curl_easy *data; 1163 int this_max_fd = -1; 1164 struct easy_pollset ps; 1165 unsigned int i; 1166 (void)exc_fd_set; /* not used */ 1167 1168 if(!GOOD_MULTI_HANDLE(multi)) 1169 return CURLM_BAD_HANDLE; 1170 1171 if(multi->in_callback) 1172 return CURLM_RECURSIVE_API_CALL; 1173 1174 memset(&ps, 0, sizeof(ps)); 1175 for(data = multi->easyp; data; data = data->next) { 1176 multi_getsock(data, &ps); 1177 1178 for(i = 0; i < ps.num; i++) { 1179 if(!FDSET_SOCK(ps.sockets[i])) 1180 /* pretend it doesn't exist */ 1181 continue; 1182 if(ps.actions[i] & CURL_POLL_IN) 1183 FD_SET(ps.sockets[i], read_fd_set); 1184 if(ps.actions[i] & CURL_POLL_OUT) 1185 FD_SET(ps.sockets[i], write_fd_set); 1186 if((int)ps.sockets[i] > this_max_fd) 1187 this_max_fd = (int)ps.sockets[i]; 1188 } 1189 } 1190 1191 *max_fd = this_max_fd; 1192 1193 return CURLM_OK; 1194} 1195 1196#ifdef USE_WINSOCK 1197/* Reset FD_WRITE for TCP sockets. Nothing is actually sent. UDP sockets can't 1198 * be reset this way because an empty datagram would be sent. #9203 1199 * 1200 * "On Windows the internal state of FD_WRITE as returned from 1201 * WSAEnumNetworkEvents is only reset after successful send()." 1202 */ 1203static void reset_socket_fdwrite(curl_socket_t s) 1204{ 1205 int t; 1206 int l = (int)sizeof(t); 1207 if(!getsockopt(s, SOL_SOCKET, SO_TYPE, (char *)&t, &l) && t == SOCK_STREAM) 1208 send(s, NULL, 0, 0); 1209} 1210#endif 1211 1212#define NUM_POLLS_ON_STACK 10 1213 1214static CURLMcode multi_wait(struct Curl_multi *multi, 1215 struct curl_waitfd extra_fds[], 1216 unsigned int extra_nfds, 1217 int timeout_ms, 1218 int *ret, 1219 bool extrawait, /* when no socket, wait */ 1220 bool use_wakeup) 1221{ 1222 struct Curl_easy *data; 1223 struct easy_pollset ps; 1224 size_t i; 1225 unsigned int nfds = 0; 1226 unsigned int curlfds; 1227 long timeout_internal; 1228 int retcode = 0; 1229 struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; 1230 struct pollfd *ufds = &a_few_on_stack[0]; 1231 bool ufds_malloc = FALSE; 1232#ifdef USE_WINSOCK 1233 WSANETWORKEVENTS wsa_events; 1234 DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT); 1235#endif 1236#ifndef ENABLE_WAKEUP 1237 (void)use_wakeup; 1238#endif 1239 1240 if(!GOOD_MULTI_HANDLE(multi)) 1241 return CURLM_BAD_HANDLE; 1242 1243 if(multi->in_callback) 1244 return CURLM_RECURSIVE_API_CALL; 1245 1246 if(timeout_ms < 0) 1247 return CURLM_BAD_FUNCTION_ARGUMENT; 1248 1249 /* Count up how many fds we have from the multi handle */ 1250 memset(&ps, 0, sizeof(ps)); 1251 for(data = multi->easyp; data; data = data->next) { 1252 multi_getsock(data, &ps); 1253 nfds += ps.num; 1254 } 1255 1256 /* If the internally desired timeout is actually shorter than requested from 1257 the outside, then use the shorter time! But only if the internal timer 1258 is actually larger than -1! */ 1259 (void)multi_timeout(multi, &timeout_internal); 1260 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) 1261 timeout_ms = (int)timeout_internal; 1262 1263 curlfds = nfds; /* number of internal file descriptors */ 1264 nfds += extra_nfds; /* add the externally provided ones */ 1265 1266#ifdef ENABLE_WAKEUP 1267#ifdef USE_WINSOCK 1268 if(use_wakeup) { 1269#else 1270 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { 1271#endif 1272 ++nfds; 1273 } 1274#endif 1275 1276 if(nfds > NUM_POLLS_ON_STACK) { 1277 /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes 1278 big, so at 2^29 sockets this value might wrap. When a process gets 1279 the capability to actually handle over 500 million sockets this 1280 calculation needs a integer overflow check. */ 1281 ufds = malloc(nfds * sizeof(struct pollfd)); 1282 if(!ufds) 1283 return CURLM_OUT_OF_MEMORY; 1284 ufds_malloc = TRUE; 1285 } 1286 nfds = 0; 1287 1288 /* only do the second loop if we found descriptors in the first stage run 1289 above */ 1290 1291 if(curlfds) { 1292 /* Add the curl handles to our pollfds first */ 1293 for(data = multi->easyp; data; data = data->next) { 1294 multi_getsock(data, &ps); 1295 1296 for(i = 0; i < ps.num; i++) { 1297 struct pollfd *ufd = &ufds[nfds++]; 1298#ifdef USE_WINSOCK 1299 long mask = 0; 1300#endif 1301 ufd->fd = ps.sockets[i]; 1302 ufd->events = 0; 1303 if(ps.actions[i] & CURL_POLL_IN) { 1304#ifdef USE_WINSOCK 1305 mask |= FD_READ|FD_ACCEPT|FD_CLOSE; 1306#endif 1307 ufd->events |= POLLIN; 1308 } 1309 if(ps.actions[i] & CURL_POLL_OUT) { 1310#ifdef USE_WINSOCK 1311 mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; 1312 reset_socket_fdwrite(ps.sockets[i]); 1313#endif 1314 ufd->events |= POLLOUT; 1315 } 1316#ifdef USE_WINSOCK 1317 if(WSAEventSelect(ps.sockets[i], multi->wsa_event, mask) != 0) { 1318 if(ufds_malloc) 1319 free(ufds); 1320 return CURLM_INTERNAL_ERROR; 1321 } 1322#endif 1323 } 1324 } 1325 } 1326 1327 /* Add external file descriptions from poll-like struct curl_waitfd */ 1328 for(i = 0; i < extra_nfds; i++) { 1329#ifdef USE_WINSOCK 1330 long mask = 0; 1331 if(extra_fds[i].events & CURL_WAIT_POLLIN) 1332 mask |= FD_READ|FD_ACCEPT|FD_CLOSE; 1333 if(extra_fds[i].events & CURL_WAIT_POLLPRI) 1334 mask |= FD_OOB; 1335 if(extra_fds[i].events & CURL_WAIT_POLLOUT) { 1336 mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; 1337 reset_socket_fdwrite(extra_fds[i].fd); 1338 } 1339 if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) { 1340 if(ufds_malloc) 1341 free(ufds); 1342 return CURLM_INTERNAL_ERROR; 1343 } 1344#endif 1345 ufds[nfds].fd = extra_fds[i].fd; 1346 ufds[nfds].events = 0; 1347 if(extra_fds[i].events & CURL_WAIT_POLLIN) 1348 ufds[nfds].events |= POLLIN; 1349 if(extra_fds[i].events & CURL_WAIT_POLLPRI) 1350 ufds[nfds].events |= POLLPRI; 1351 if(extra_fds[i].events & CURL_WAIT_POLLOUT) 1352 ufds[nfds].events |= POLLOUT; 1353 ++nfds; 1354 } 1355 1356#ifdef ENABLE_WAKEUP 1357#ifndef USE_WINSOCK 1358 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { 1359 ufds[nfds].fd = multi->wakeup_pair[0]; 1360 ufds[nfds].events = POLLIN; 1361 ++nfds; 1362 } 1363#endif 1364#endif 1365 1366#if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK) 1367 if(nfds || use_wakeup) { 1368#else 1369 if(nfds) { 1370#endif 1371 int pollrc; 1372#ifdef USE_WINSOCK 1373 if(nfds) 1374 pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */ 1375 else 1376 pollrc = 0; 1377#else 1378 pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */ 1379#endif 1380 if(pollrc < 0) 1381 return CURLM_UNRECOVERABLE_POLL; 1382 1383 if(pollrc > 0) { 1384 retcode = pollrc; 1385#ifdef USE_WINSOCK 1386 } 1387 else { /* now wait... if not ready during the pre-check (pollrc == 0) */ 1388 WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE); 1389 } 1390 /* With WinSock, we have to run the following section unconditionally 1391 to call WSAEventSelect(fd, event, 0) on all the sockets */ 1392 { 1393#endif 1394 /* copy revents results from the poll to the curl_multi_wait poll 1395 struct, the bit values of the actual underlying poll() implementation 1396 may not be the same as the ones in the public libcurl API! */ 1397 for(i = 0; i < extra_nfds; i++) { 1398 unsigned r = ufds[curlfds + i].revents; 1399 unsigned short mask = 0; 1400#ifdef USE_WINSOCK 1401 curl_socket_t s = extra_fds[i].fd; 1402 wsa_events.lNetworkEvents = 0; 1403 if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) { 1404 if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)) 1405 mask |= CURL_WAIT_POLLIN; 1406 if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE)) 1407 mask |= CURL_WAIT_POLLOUT; 1408 if(wsa_events.lNetworkEvents & FD_OOB) 1409 mask |= CURL_WAIT_POLLPRI; 1410 if(ret && !pollrc && wsa_events.lNetworkEvents) 1411 retcode++; 1412 } 1413 WSAEventSelect(s, multi->wsa_event, 0); 1414 if(!pollrc) { 1415 extra_fds[i].revents = mask; 1416 continue; 1417 } 1418#endif 1419 if(r & POLLIN) 1420 mask |= CURL_WAIT_POLLIN; 1421 if(r & POLLOUT) 1422 mask |= CURL_WAIT_POLLOUT; 1423 if(r & POLLPRI) 1424 mask |= CURL_WAIT_POLLPRI; 1425 extra_fds[i].revents = mask; 1426 } 1427 1428#ifdef USE_WINSOCK 1429 /* Count up all our own sockets that had activity, 1430 and remove them from the event. */ 1431 if(curlfds) { 1432 1433 for(data = multi->easyp; data; data = data->next) { 1434 multi_getsock(data, &ps); 1435 1436 for(i = 0; i < ps.num; i++) { 1437 wsa_events.lNetworkEvents = 0; 1438 if(WSAEnumNetworkEvents(ps.sockets[i], NULL, 1439 &wsa_events) == 0) { 1440 if(ret && !pollrc && wsa_events.lNetworkEvents) 1441 retcode++; 1442 } 1443 WSAEventSelect(ps.sockets[i], multi->wsa_event, 0); 1444 } 1445 } 1446 } 1447 1448 WSAResetEvent(multi->wsa_event); 1449#else 1450#ifdef ENABLE_WAKEUP 1451 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { 1452 if(ufds[curlfds + extra_nfds].revents & POLLIN) { 1453 char buf[64]; 1454 ssize_t nread; 1455 while(1) { 1456 /* the reading socket is non-blocking, try to read 1457 data from it until it receives an error (except EINTR). 1458 In normal cases it will get EAGAIN or EWOULDBLOCK 1459 when there is no more data, breaking the loop. */ 1460 nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf)); 1461 if(nread <= 0) { 1462 if(nread < 0 && EINTR == SOCKERRNO) 1463 continue; 1464 break; 1465 } 1466 } 1467 /* do not count the wakeup socket into the returned value */ 1468 retcode--; 1469 } 1470 } 1471#endif 1472#endif 1473 } 1474 } 1475 1476 if(ufds_malloc) 1477 free(ufds); 1478 if(ret) 1479 *ret = retcode; 1480#if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK) 1481 if(extrawait && !nfds && !use_wakeup) { 1482#else 1483 if(extrawait && !nfds) { 1484#endif 1485 long sleep_ms = 0; 1486 1487 /* Avoid busy-looping when there's nothing particular to wait for */ 1488 if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) { 1489 if(sleep_ms > timeout_ms) 1490 sleep_ms = timeout_ms; 1491 /* when there are no easy handles in the multi, this holds a -1 1492 timeout */ 1493 else if(sleep_ms < 0) 1494 sleep_ms = timeout_ms; 1495 Curl_wait_ms(sleep_ms); 1496 } 1497 } 1498 1499 return CURLM_OK; 1500} 1501 1502CURLMcode curl_multi_wait(struct Curl_multi *multi, 1503 struct curl_waitfd extra_fds[], 1504 unsigned int extra_nfds, 1505 int timeout_ms, 1506 int *ret) 1507{ 1508 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE, 1509 FALSE); 1510} 1511 1512CURLMcode curl_multi_poll(struct Curl_multi *multi, 1513 struct curl_waitfd extra_fds[], 1514 unsigned int extra_nfds, 1515 int timeout_ms, 1516 int *ret) 1517{ 1518 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE, 1519 TRUE); 1520} 1521 1522CURLMcode curl_multi_wakeup(struct Curl_multi *multi) 1523{ 1524 /* this function is usually called from another thread, 1525 it has to be careful only to access parts of the 1526 Curl_multi struct that are constant */ 1527 1528 /* GOOD_MULTI_HANDLE can be safely called */ 1529 if(!GOOD_MULTI_HANDLE(multi)) 1530 return CURLM_BAD_HANDLE; 1531 1532#ifdef ENABLE_WAKEUP 1533#ifdef USE_WINSOCK 1534 if(WSASetEvent(multi->wsa_event)) 1535 return CURLM_OK; 1536#else 1537 /* the wakeup_pair variable is only written during init and cleanup, 1538 making it safe to access from another thread after the init part 1539 and before cleanup */ 1540 if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) { 1541 char buf[1]; 1542 buf[0] = 1; 1543 while(1) { 1544 /* swrite() is not thread-safe in general, because concurrent calls 1545 can have their messages interleaved, but in this case the content 1546 of the messages does not matter, which makes it ok to call. 1547 1548 The write socket is set to non-blocking, this way this function 1549 cannot block, making it safe to call even from the same thread 1550 that will call curl_multi_wait(). If swrite() returns that it 1551 would block, it's considered successful because it means that 1552 previous calls to this function will wake up the poll(). */ 1553 if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) { 1554 int err = SOCKERRNO; 1555 int return_success; 1556#ifdef USE_WINSOCK 1557 return_success = WSAEWOULDBLOCK == err; 1558#else 1559 if(EINTR == err) 1560 continue; 1561 return_success = EWOULDBLOCK == err || EAGAIN == err; 1562#endif 1563 if(!return_success) 1564 return CURLM_WAKEUP_FAILURE; 1565 } 1566 return CURLM_OK; 1567 } 1568 } 1569#endif 1570#endif 1571 return CURLM_WAKEUP_FAILURE; 1572} 1573 1574/* 1575 * multi_ischanged() is called 1576 * 1577 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND 1578 * => CONNECT action. 1579 * 1580 * Set 'clear' to TRUE to have it also clear the state variable. 1581 */ 1582static bool multi_ischanged(struct Curl_multi *multi, bool clear) 1583{ 1584 bool retval = multi->recheckstate; 1585 if(clear) 1586 multi->recheckstate = FALSE; 1587 return retval; 1588} 1589 1590/* 1591 * Curl_multi_connchanged() is called to tell that there is a connection in 1592 * this multi handle that has changed state (multiplexing become possible, the 1593 * number of allowed streams changed or similar), and a subsequent use of this 1594 * multi handle should move CONNECT_PEND handles back to CONNECT to have them 1595 * retry. 1596 */ 1597void Curl_multi_connchanged(struct Curl_multi *multi) 1598{ 1599 multi->recheckstate = TRUE; 1600} 1601 1602CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, 1603 struct Curl_easy *data, 1604 struct connectdata *conn) 1605{ 1606 CURLMcode rc; 1607 1608 if(multi->in_callback) 1609 return CURLM_RECURSIVE_API_CALL; 1610 1611 rc = curl_multi_add_handle(multi, data); 1612 if(!rc) { 1613 struct SingleRequest *k = &data->req; 1614 1615 /* pass in NULL for 'conn' here since we don't want to init the 1616 connection, only this transfer */ 1617 Curl_init_do(data, NULL); 1618 1619 /* take this handle to the perform state right away */ 1620 multistate(data, MSTATE_PERFORMING); 1621 Curl_attach_connection(data, conn); 1622 k->keepon |= KEEP_RECV; /* setup to receive! */ 1623 } 1624 return rc; 1625} 1626 1627static CURLcode multi_do(struct Curl_easy *data, bool *done) 1628{ 1629 CURLcode result = CURLE_OK; 1630 struct connectdata *conn = data->conn; 1631 1632 DEBUGASSERT(conn); 1633 DEBUGASSERT(conn->handler); 1634 1635 if(conn->handler->do_it) 1636 result = conn->handler->do_it(data, done); 1637 1638 return result; 1639} 1640 1641/* 1642 * multi_do_more() is called during the DO_MORE multi state. It is basically a 1643 * second stage DO state which (wrongly) was introduced to support FTP's 1644 * second connection. 1645 * 1646 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to 1647 * DOING state there's more work to do! 1648 */ 1649 1650static CURLcode multi_do_more(struct Curl_easy *data, int *complete) 1651{ 1652 CURLcode result = CURLE_OK; 1653 struct connectdata *conn = data->conn; 1654 1655 *complete = 0; 1656 1657 if(conn->handler->do_more) 1658 result = conn->handler->do_more(data, complete); 1659 1660 return result; 1661} 1662 1663/* 1664 * Check whether a timeout occurred, and handle it if it did 1665 */ 1666static bool multi_handle_timeout(struct Curl_easy *data, 1667 struct curltime *now, 1668 bool *stream_error, 1669 CURLcode *result, 1670 bool connect_timeout) 1671{ 1672 timediff_t timeout_ms; 1673 timeout_ms = Curl_timeleft(data, now, connect_timeout); 1674 1675 if(timeout_ms < 0) { 1676 /* Handle timed out */ 1677 if(data->mstate == MSTATE_RESOLVING) 1678 failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T 1679 " milliseconds", 1680 Curl_timediff(*now, data->progress.t_startsingle)); 1681 else if(data->mstate == MSTATE_CONNECTING) 1682 failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T 1683 " milliseconds", 1684 Curl_timediff(*now, data->progress.t_startsingle)); 1685 else { 1686 struct SingleRequest *k = &data->req; 1687 if(k->size != -1) { 1688 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T 1689 " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" 1690 CURL_FORMAT_CURL_OFF_T " bytes received", 1691 Curl_timediff(*now, data->progress.t_startsingle), 1692 k->bytecount, k->size); 1693 } 1694 else { 1695 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T 1696 " milliseconds with %" CURL_FORMAT_CURL_OFF_T 1697 " bytes received", 1698 Curl_timediff(*now, data->progress.t_startsingle), 1699 k->bytecount); 1700 } 1701 } 1702 1703 /* Force connection closed if the connection has indeed been used */ 1704 if(data->mstate > MSTATE_DO) { 1705 streamclose(data->conn, "Disconnected with pending data"); 1706 *stream_error = TRUE; 1707 } 1708 *result = CURLE_OPERATION_TIMEDOUT; 1709 (void)multi_done(data, *result, TRUE); 1710 } 1711 1712 return (timeout_ms < 0); 1713} 1714 1715/* 1716 * We are doing protocol-specific connecting and this is being called over and 1717 * over from the multi interface until the connection phase is done on 1718 * protocol layer. 1719 */ 1720 1721static CURLcode protocol_connecting(struct Curl_easy *data, bool *done) 1722{ 1723 CURLcode result = CURLE_OK; 1724 struct connectdata *conn = data->conn; 1725 1726 if(conn && conn->handler->connecting) { 1727 *done = FALSE; 1728 result = conn->handler->connecting(data, done); 1729 } 1730 else 1731 *done = TRUE; 1732 1733 return result; 1734} 1735 1736/* 1737 * We are DOING this is being called over and over from the multi interface 1738 * until the DOING phase is done on protocol layer. 1739 */ 1740 1741static CURLcode protocol_doing(struct Curl_easy *data, bool *done) 1742{ 1743 CURLcode result = CURLE_OK; 1744 struct connectdata *conn = data->conn; 1745 1746 if(conn && conn->handler->doing) { 1747 *done = FALSE; 1748 result = conn->handler->doing(data, done); 1749 } 1750 else 1751 *done = TRUE; 1752 1753 return result; 1754} 1755 1756/* 1757 * We have discovered that the TCP connection has been successful, we can now 1758 * proceed with some action. 1759 * 1760 */ 1761static CURLcode protocol_connect(struct Curl_easy *data, 1762 bool *protocol_done) 1763{ 1764 CURLcode result = CURLE_OK; 1765 struct connectdata *conn = data->conn; 1766 DEBUGASSERT(conn); 1767 DEBUGASSERT(protocol_done); 1768 1769 *protocol_done = FALSE; 1770 1771 if(Curl_conn_is_connected(conn, FIRSTSOCKET) 1772 && conn->bits.protoconnstart) { 1773 /* We already are connected, get back. This may happen when the connect 1774 worked fine in the first call, like when we connect to a local server 1775 or proxy. Note that we don't know if the protocol is actually done. 1776 1777 Unless this protocol doesn't have any protocol-connect callback, as 1778 then we know we're done. */ 1779 if(!conn->handler->connecting) 1780 *protocol_done = TRUE; 1781 1782 return CURLE_OK; 1783 } 1784 1785 if(!conn->bits.protoconnstart) { 1786 if(conn->handler->connect_it) { 1787 /* is there a protocol-specific connect() procedure? */ 1788 1789 /* Call the protocol-specific connect function */ 1790 result = conn->handler->connect_it(data, protocol_done); 1791 } 1792 else 1793 *protocol_done = TRUE; 1794 1795 /* it has started, possibly even completed but that knowledge isn't stored 1796 in this bit! */ 1797 if(!result) 1798 conn->bits.protoconnstart = TRUE; 1799 } 1800 1801 return result; /* pass back status */ 1802} 1803 1804/* 1805 * readrewind() rewinds the read stream. This is typically used for HTTP 1806 * POST/PUT with multi-pass authentication when a sending was denied and a 1807 * resend is necessary. 1808 */ 1809static CURLcode readrewind(struct Curl_easy *data) 1810{ 1811 curl_mimepart *mimepart = &data->set.mimepost; 1812 DEBUGASSERT(data->conn); 1813 1814 data->state.rewindbeforesend = FALSE; /* we rewind now */ 1815 1816 /* explicitly switch off sending data on this connection now since we are 1817 about to restart a new transfer and thus we want to avoid inadvertently 1818 sending more data on the existing connection until the next transfer 1819 starts */ 1820 data->req.keepon &= ~KEEP_SEND; 1821 1822 /* We have sent away data. If not using CURLOPT_POSTFIELDS or 1823 CURLOPT_HTTPPOST, call app to rewind 1824 */ 1825#ifndef CURL_DISABLE_HTTP 1826 if(data->conn->handler->protocol & PROTO_FAMILY_HTTP) { 1827 if(data->state.mimepost) 1828 mimepart = data->state.mimepost; 1829 } 1830#endif 1831 if(data->set.postfields || 1832 (data->state.httpreq == HTTPREQ_GET) || 1833 (data->state.httpreq == HTTPREQ_HEAD)) 1834 ; /* no need to rewind */ 1835 else if(data->state.httpreq == HTTPREQ_POST_MIME || 1836 data->state.httpreq == HTTPREQ_POST_FORM) { 1837 CURLcode result = Curl_mime_rewind(mimepart); 1838 if(result) { 1839 failf(data, "Cannot rewind mime/post data"); 1840 return result; 1841 } 1842 } 1843 else { 1844 if(data->set.seek_func) { 1845 int err; 1846 1847 Curl_set_in_callback(data, true); 1848 err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET); 1849 Curl_set_in_callback(data, false); 1850 if(err) { 1851 failf(data, "seek callback returned error %d", (int)err); 1852 return CURLE_SEND_FAIL_REWIND; 1853 } 1854 } 1855 else if(data->set.ioctl_func) { 1856 curlioerr err; 1857 1858 Curl_set_in_callback(data, true); 1859 err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, 1860 data->set.ioctl_client); 1861 Curl_set_in_callback(data, false); 1862 infof(data, "the ioctl callback returned %d", (int)err); 1863 1864 if(err) { 1865 failf(data, "ioctl callback returned error %d", (int)err); 1866 return CURLE_SEND_FAIL_REWIND; 1867 } 1868 } 1869 else { 1870 /* If no CURLOPT_READFUNCTION is used, we know that we operate on a 1871 given FILE * stream and we can actually attempt to rewind that 1872 ourselves with fseek() */ 1873 if(data->state.fread_func == (curl_read_callback)fread) { 1874 if(-1 != fseek(data->state.in, 0, SEEK_SET)) 1875 /* successful rewind */ 1876 return CURLE_OK; 1877 } 1878 1879 /* no callback set or failure above, makes us fail at once */ 1880 failf(data, "necessary data rewind wasn't possible"); 1881 return CURLE_SEND_FAIL_REWIND; 1882 } 1883 } 1884 return CURLE_OK; 1885} 1886 1887/* 1888 * Curl_preconnect() is called immediately before a connect starts. When a 1889 * redirect is followed, this is then called multiple times during a single 1890 * transfer. 1891 */ 1892CURLcode Curl_preconnect(struct Curl_easy *data) 1893{ 1894 if(!data->state.buffer) { 1895 data->state.buffer = malloc(data->set.buffer_size + 1); 1896 if(!data->state.buffer) 1897 return CURLE_OUT_OF_MEMORY; 1898 } 1899 1900 return CURLE_OK; 1901} 1902 1903static void set_in_callback(struct Curl_multi *multi, bool value) 1904{ 1905 multi->in_callback = value; 1906} 1907 1908static CURLMcode multi_runsingle(struct Curl_multi *multi, 1909 struct curltime *nowp, 1910 struct Curl_easy *data) 1911{ 1912 struct Curl_message *msg = NULL; 1913 bool connected; 1914 bool async; 1915 bool protocol_connected = FALSE; 1916 bool dophase_done = FALSE; 1917 bool done = FALSE; 1918 CURLMcode rc; 1919 CURLcode result = CURLE_OK; 1920 timediff_t recv_timeout_ms; 1921 timediff_t send_timeout_ms; 1922 int control; 1923 1924 if(!GOOD_EASY_HANDLE(data)) 1925 return CURLM_BAD_EASY_HANDLE; 1926 1927 if(multi->dead) { 1928 /* a multi-level callback returned error before, meaning every individual 1929 transfer now has failed */ 1930 result = CURLE_ABORTED_BY_CALLBACK; 1931 Curl_posttransfer(data); 1932 multi_done(data, result, FALSE); 1933 multistate(data, MSTATE_COMPLETED); 1934 } 1935 1936 multi_warn_debug(multi, data); 1937 1938 do { 1939 /* A "stream" here is a logical stream if the protocol can handle that 1940 (HTTP/2), or the full connection for older protocols */ 1941 bool stream_error = FALSE; 1942 rc = CURLM_OK; 1943 1944 if(multi_ischanged(multi, TRUE)) { 1945 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue")); 1946 process_pending_handles(multi); /* multiplexed */ 1947 } 1948 1949 if(data->mstate > MSTATE_CONNECT && 1950 data->mstate < MSTATE_COMPLETED) { 1951 /* Make sure we set the connection's current owner */ 1952 DEBUGASSERT(data->conn); 1953 if(!data->conn) 1954 return CURLM_INTERNAL_ERROR; 1955 } 1956 1957 if(data->conn && 1958 (data->mstate >= MSTATE_CONNECT) && 1959 (data->mstate < MSTATE_COMPLETED)) { 1960 /* Check for overall operation timeout here but defer handling the 1961 * connection timeout to later, to allow for a connection to be set up 1962 * in the window since we last checked timeout. This prevents us 1963 * tearing down a completed connection in the case where we were slow 1964 * to check the timeout (e.g. process descheduled during this loop). 1965 * We set connect_timeout=FALSE to do this. */ 1966 1967 /* we need to wait for the connect state as only then is the start time 1968 stored, but we must not check already completed handles */ 1969 if(multi_handle_timeout(data, nowp, &stream_error, &result, FALSE)) { 1970 /* Skip the statemachine and go directly to error handling section. */ 1971 goto statemachine_end; 1972 } 1973 } 1974 1975 switch(data->mstate) { 1976 case MSTATE_INIT: 1977 /* init this transfer. */ 1978 result = Curl_pretransfer(data); 1979 1980 if(!result) { 1981 /* after init, go CONNECT */ 1982 multistate(data, MSTATE_CONNECT); 1983 *nowp = Curl_pgrsTime(data, TIMER_STARTOP); 1984 rc = CURLM_CALL_MULTI_PERFORM; 1985 } 1986 break; 1987 1988 case MSTATE_CONNECT: 1989 /* Connect. We want to get a connection identifier filled in. */ 1990 /* init this transfer. */ 1991 result = Curl_preconnect(data); 1992 if(result) 1993 break; 1994 1995 *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE); 1996 if(data->set.timeout) 1997 Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT); 1998 1999 if(data->set.connecttimeout) 2000 Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT); 2001 2002 result = Curl_connect(data, &async, &connected); 2003 if(CURLE_NO_CONNECTION_AVAILABLE == result) { 2004 /* There was no connection available. We will go to the pending 2005 state and wait for an available connection. */ 2006 multistate(data, MSTATE_PENDING); 2007 2008 /* add this handle to the list of connect-pending handles */ 2009 Curl_llist_insert_next(&multi->pending, multi->pending.tail, data, 2010 &data->connect_queue); 2011 /* unlink from the main list */ 2012 unlink_easy(multi, data); 2013 result = CURLE_OK; 2014 break; 2015 } 2016 else if(data->state.previouslypending) { 2017 /* this transfer comes from the pending queue so try move another */ 2018 infof(data, "Transfer was pending, now try another"); 2019 process_pending_handles(data->multi); 2020 } 2021 2022 if(!result) { 2023 *nowp = Curl_pgrsTime(data, TIMER_POSTQUEUE); 2024 if(async) 2025 /* We're now waiting for an asynchronous name lookup */ 2026 multistate(data, MSTATE_RESOLVING); 2027 else { 2028 /* after the connect has been sent off, go WAITCONNECT unless the 2029 protocol connect is already done and we can go directly to 2030 WAITDO or DO! */ 2031 rc = CURLM_CALL_MULTI_PERFORM; 2032 2033 if(connected) 2034 multistate(data, MSTATE_PROTOCONNECT); 2035 else { 2036 multistate(data, MSTATE_CONNECTING); 2037 } 2038 } 2039 } 2040 break; 2041 2042 case MSTATE_RESOLVING: 2043 /* awaiting an asynch name resolve to complete */ 2044 { 2045 struct Curl_dns_entry *dns = NULL; 2046 struct connectdata *conn = data->conn; 2047 const char *hostname; 2048 2049 DEBUGASSERT(conn); 2050#ifndef CURL_DISABLE_PROXY 2051 if(conn->bits.httpproxy) 2052 hostname = conn->http_proxy.host.name; 2053 else 2054#endif 2055 if(conn->bits.conn_to_host) 2056 hostname = conn->conn_to_host.name; 2057 else 2058 hostname = conn->host.name; 2059 2060 /* check if we have the name resolved by now */ 2061 dns = Curl_fetch_addr(data, hostname, (int)conn->port); 2062 2063 if(dns) { 2064#ifdef CURLRES_ASYNCH 2065 data->state.async.dns = dns; 2066 data->state.async.done = TRUE; 2067#endif 2068 result = CURLE_OK; 2069 infof(data, "Hostname '%s' was found in DNS cache", hostname); 2070 } 2071 2072 if(!dns) 2073 result = Curl_resolv_check(data, &dns); 2074 2075 /* Update sockets here, because the socket(s) may have been 2076 closed and the application thus needs to be told, even if it 2077 is likely that the same socket(s) will again be used further 2078 down. If the name has not yet been resolved, it is likely 2079 that new sockets have been opened in an attempt to contact 2080 another resolver. */ 2081 rc = singlesocket(multi, data); 2082 if(rc) 2083 return rc; 2084 2085 if(dns) { 2086 /* Perform the next step in the connection phase, and then move on 2087 to the WAITCONNECT state */ 2088 result = Curl_once_resolved(data, &connected); 2089 2090 if(result) 2091 /* if Curl_once_resolved() returns failure, the connection struct 2092 is already freed and gone */ 2093 data->conn = NULL; /* no more connection */ 2094 else { 2095 /* call again please so that we get the next socket setup */ 2096 rc = CURLM_CALL_MULTI_PERFORM; 2097 if(connected) 2098 multistate(data, MSTATE_PROTOCONNECT); 2099 else { 2100 multistate(data, MSTATE_CONNECTING); 2101 } 2102 } 2103 } 2104 2105 if(result) { 2106 /* failure detected */ 2107 stream_error = TRUE; 2108 break; 2109 } 2110 } 2111 break; 2112 2113#ifndef CURL_DISABLE_HTTP 2114 case MSTATE_TUNNELING: 2115 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ 2116 DEBUGASSERT(data->conn); 2117 result = Curl_http_connect(data, &protocol_connected); 2118#ifndef CURL_DISABLE_PROXY 2119 if(data->conn->bits.proxy_connect_closed) { 2120 rc = CURLM_CALL_MULTI_PERFORM; 2121 /* connect back to proxy again */ 2122 result = CURLE_OK; 2123 multi_done(data, CURLE_OK, FALSE); 2124 multistate(data, MSTATE_CONNECT); 2125 } 2126 else 2127#endif 2128 if(!result) { 2129 rc = CURLM_CALL_MULTI_PERFORM; 2130 /* initiate protocol connect phase */ 2131 multistate(data, MSTATE_PROTOCONNECT); 2132 } 2133 else 2134 stream_error = TRUE; 2135 break; 2136#endif 2137 2138 case MSTATE_CONNECTING: 2139 /* awaiting a completion of an asynch TCP connect */ 2140 DEBUGASSERT(data->conn); 2141 result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected); 2142 if(connected && !result) { 2143 rc = CURLM_CALL_MULTI_PERFORM; 2144 multistate(data, MSTATE_PROTOCONNECT); 2145 } 2146 else if(result) { 2147 /* failure detected */ 2148 Curl_posttransfer(data); 2149 multi_done(data, result, TRUE); 2150 stream_error = TRUE; 2151 break; 2152 } 2153 break; 2154 2155 case MSTATE_PROTOCONNECT: 2156 if(data->state.rewindbeforesend) 2157 result = readrewind(data); 2158 2159 if(!result && data->conn->bits.reuse) { 2160 /* ftp seems to hang when protoconnect on reused connection 2161 * since we handle PROTOCONNECT in general inside the filers, it 2162 * seems wrong to restart this on a reused connection. */ 2163 multistate(data, MSTATE_DO); 2164 rc = CURLM_CALL_MULTI_PERFORM; 2165 break; 2166 } 2167 if(!result) 2168 result = protocol_connect(data, &protocol_connected); 2169 if(!result && !protocol_connected) { 2170 /* switch to waiting state */ 2171 multistate(data, MSTATE_PROTOCONNECTING); 2172 rc = CURLM_CALL_MULTI_PERFORM; 2173 } 2174 else if(!result) { 2175 /* protocol connect has completed, go WAITDO or DO */ 2176 multistate(data, MSTATE_DO); 2177 rc = CURLM_CALL_MULTI_PERFORM; 2178 } 2179 else { 2180 /* failure detected */ 2181 Curl_posttransfer(data); 2182 multi_done(data, result, TRUE); 2183 stream_error = TRUE; 2184 } 2185 break; 2186 2187 case MSTATE_PROTOCONNECTING: 2188 /* protocol-specific connect phase */ 2189 result = protocol_connecting(data, &protocol_connected); 2190 if(!result && protocol_connected) { 2191 /* after the connect has completed, go WAITDO or DO */ 2192 multistate(data, MSTATE_DO); 2193 rc = CURLM_CALL_MULTI_PERFORM; 2194 } 2195 else if(result) { 2196 /* failure detected */ 2197 Curl_posttransfer(data); 2198 multi_done(data, result, TRUE); 2199 stream_error = TRUE; 2200 } 2201 break; 2202 2203 case MSTATE_DO: 2204 if(data->set.fprereq) { 2205 int prereq_rc; 2206 2207 /* call the prerequest callback function */ 2208 Curl_set_in_callback(data, true); 2209 prereq_rc = data->set.fprereq(data->set.prereq_userp, 2210 data->info.conn_primary_ip, 2211 data->info.conn_local_ip, 2212 data->info.conn_primary_port, 2213 data->info.conn_local_port); 2214 Curl_set_in_callback(data, false); 2215 if(prereq_rc != CURL_PREREQFUNC_OK) { 2216 failf(data, "operation aborted by pre-request callback"); 2217 /* failure in pre-request callback - don't do any other processing */ 2218 result = CURLE_ABORTED_BY_CALLBACK; 2219 Curl_posttransfer(data); 2220 multi_done(data, result, FALSE); 2221 stream_error = TRUE; 2222 break; 2223 } 2224 } 2225 2226 if(data->set.connect_only == 1) { 2227 /* keep connection open for application to use the socket */ 2228 connkeep(data->conn, "CONNECT_ONLY"); 2229 multistate(data, MSTATE_DONE); 2230 result = CURLE_OK; 2231 rc = CURLM_CALL_MULTI_PERFORM; 2232 } 2233 else { 2234 /* Perform the protocol's DO action */ 2235 result = multi_do(data, &dophase_done); 2236 2237 /* When multi_do() returns failure, data->conn might be NULL! */ 2238 2239 if(!result) { 2240 if(!dophase_done) { 2241#ifndef CURL_DISABLE_FTP 2242 /* some steps needed for wildcard matching */ 2243 if(data->state.wildcardmatch) { 2244 struct WildcardData *wc = data->wildcard; 2245 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { 2246 /* skip some states if it is important */ 2247 multi_done(data, CURLE_OK, FALSE); 2248 2249 /* if there's no connection left, skip the DONE state */ 2250 multistate(data, data->conn ? 2251 MSTATE_DONE : MSTATE_COMPLETED); 2252 rc = CURLM_CALL_MULTI_PERFORM; 2253 break; 2254 } 2255 } 2256#endif 2257 /* DO was not completed in one function call, we must continue 2258 DOING... */ 2259 multistate(data, MSTATE_DOING); 2260 rc = CURLM_CALL_MULTI_PERFORM; 2261 } 2262 2263 /* after DO, go DO_DONE... or DO_MORE */ 2264 else if(data->conn->bits.do_more) { 2265 /* we're supposed to do more, but we need to sit down, relax 2266 and wait a little while first */ 2267 multistate(data, MSTATE_DOING_MORE); 2268 rc = CURLM_CALL_MULTI_PERFORM; 2269 } 2270 else { 2271 /* we're done with the DO, now DID */ 2272 multistate(data, MSTATE_DID); 2273 rc = CURLM_CALL_MULTI_PERFORM; 2274 } 2275 } 2276 else if((CURLE_SEND_ERROR == result) && 2277 data->conn->bits.reuse) { 2278 /* 2279 * In this situation, a connection that we were trying to use 2280 * may have unexpectedly died. If possible, send the connection 2281 * back to the CONNECT phase so we can try again. 2282 */ 2283 char *newurl = NULL; 2284 followtype follow = FOLLOW_NONE; 2285 CURLcode drc; 2286 2287 drc = Curl_retry_request(data, &newurl); 2288 if(drc) { 2289 /* a failure here pretty much implies an out of memory */ 2290 result = drc; 2291 stream_error = TRUE; 2292 } 2293 2294 Curl_posttransfer(data); 2295 drc = multi_done(data, result, FALSE); 2296 2297 /* When set to retry the connection, we must go back to the CONNECT 2298 * state */ 2299 if(newurl) { 2300 if(!drc || (drc == CURLE_SEND_ERROR)) { 2301 follow = FOLLOW_RETRY; 2302 drc = Curl_follow(data, newurl, follow); 2303 if(!drc) { 2304 multistate(data, MSTATE_CONNECT); 2305 rc = CURLM_CALL_MULTI_PERFORM; 2306 result = CURLE_OK; 2307 } 2308 else { 2309 /* Follow failed */ 2310 result = drc; 2311 } 2312 } 2313 else { 2314 /* done didn't return OK or SEND_ERROR */ 2315 result = drc; 2316 } 2317 } 2318 else { 2319 /* Have error handler disconnect conn if we can't retry */ 2320 stream_error = TRUE; 2321 } 2322 free(newurl); 2323 } 2324 else { 2325 /* failure detected */ 2326 Curl_posttransfer(data); 2327 if(data->conn) 2328 multi_done(data, result, FALSE); 2329 stream_error = TRUE; 2330 } 2331 } 2332 break; 2333 2334 case MSTATE_DOING: 2335 /* we continue DOING until the DO phase is complete */ 2336 DEBUGASSERT(data->conn); 2337 result = protocol_doing(data, &dophase_done); 2338 if(!result) { 2339 if(dophase_done) { 2340 /* after DO, go DO_DONE or DO_MORE */ 2341 multistate(data, data->conn->bits.do_more? 2342 MSTATE_DOING_MORE : MSTATE_DID); 2343 rc = CURLM_CALL_MULTI_PERFORM; 2344 } /* dophase_done */ 2345 } 2346 else { 2347 /* failure detected */ 2348 Curl_posttransfer(data); 2349 multi_done(data, result, FALSE); 2350 stream_error = TRUE; 2351 } 2352 break; 2353 2354 case MSTATE_DOING_MORE: 2355 /* 2356 * When we are connected, DOING MORE and then go DID 2357 */ 2358 DEBUGASSERT(data->conn); 2359 result = multi_do_more(data, &control); 2360 2361 if(!result) { 2362 if(control) { 2363 /* if positive, advance to DO_DONE 2364 if negative, go back to DOING */ 2365 multistate(data, control == 1? 2366 MSTATE_DID : MSTATE_DOING); 2367 rc = CURLM_CALL_MULTI_PERFORM; 2368 } 2369 /* else 2370 stay in DO_MORE */ 2371 } 2372 else { 2373 /* failure detected */ 2374 Curl_posttransfer(data); 2375 multi_done(data, result, FALSE); 2376 stream_error = TRUE; 2377 } 2378 break; 2379 2380 case MSTATE_DID: 2381 DEBUGASSERT(data->conn); 2382 if(data->conn->bits.multiplex) 2383 /* Check if we can move pending requests to send pipe */ 2384 process_pending_handles(multi); /* multiplexed */ 2385 2386 /* Only perform the transfer if there's a good socket to work with. 2387 Having both BAD is a signal to skip immediately to DONE */ 2388 if((data->conn->sockfd != CURL_SOCKET_BAD) || 2389 (data->conn->writesockfd != CURL_SOCKET_BAD)) 2390 multistate(data, MSTATE_PERFORMING); 2391 else { 2392#ifndef CURL_DISABLE_FTP 2393 if(data->state.wildcardmatch && 2394 ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) { 2395 data->wildcard->state = CURLWC_DONE; 2396 } 2397#endif 2398 multistate(data, MSTATE_DONE); 2399 } 2400 rc = CURLM_CALL_MULTI_PERFORM; 2401 break; 2402 2403 case MSTATE_RATELIMITING: /* limit-rate exceeded in either direction */ 2404 DEBUGASSERT(data->conn); 2405 /* if both rates are within spec, resume transfer */ 2406 if(Curl_pgrsUpdate(data)) 2407 result = CURLE_ABORTED_BY_CALLBACK; 2408 else 2409 result = Curl_speedcheck(data, *nowp); 2410 2411 if(result) { 2412 if(!(data->conn->handler->flags & PROTOPT_DUAL) && 2413 result != CURLE_HTTP2_STREAM) 2414 streamclose(data->conn, "Transfer returned error"); 2415 2416 Curl_posttransfer(data); 2417 multi_done(data, result, TRUE); 2418 } 2419 else { 2420 send_timeout_ms = 0; 2421 if(data->set.max_send_speed) 2422 send_timeout_ms = 2423 Curl_pgrsLimitWaitTime(data->progress.uploaded, 2424 data->progress.ul_limit_size, 2425 data->set.max_send_speed, 2426 data->progress.ul_limit_start, 2427 *nowp); 2428 2429 recv_timeout_ms = 0; 2430 if(data->set.max_recv_speed) 2431 recv_timeout_ms = 2432 Curl_pgrsLimitWaitTime(data->progress.downloaded, 2433 data->progress.dl_limit_size, 2434 data->set.max_recv_speed, 2435 data->progress.dl_limit_start, 2436 *nowp); 2437 2438 if(!send_timeout_ms && !recv_timeout_ms) { 2439 multistate(data, MSTATE_PERFORMING); 2440 Curl_ratelimit(data, *nowp); 2441 } 2442 else if(send_timeout_ms >= recv_timeout_ms) 2443 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); 2444 else 2445 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST); 2446 } 2447 break; 2448 2449 case MSTATE_PERFORMING: 2450 { 2451 char *newurl = NULL; 2452 bool retry = FALSE; 2453 DEBUGASSERT(data->state.buffer); 2454 /* check if over send speed */ 2455 send_timeout_ms = 0; 2456 if(data->set.max_send_speed) 2457 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, 2458 data->progress.ul_limit_size, 2459 data->set.max_send_speed, 2460 data->progress.ul_limit_start, 2461 *nowp); 2462 2463 /* check if over recv speed */ 2464 recv_timeout_ms = 0; 2465 if(data->set.max_recv_speed) 2466 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, 2467 data->progress.dl_limit_size, 2468 data->set.max_recv_speed, 2469 data->progress.dl_limit_start, 2470 *nowp); 2471 2472 if(send_timeout_ms || recv_timeout_ms) { 2473 Curl_ratelimit(data, *nowp); 2474 multistate(data, MSTATE_RATELIMITING); 2475 if(send_timeout_ms >= recv_timeout_ms) 2476 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); 2477 else 2478 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST); 2479 break; 2480 } 2481 2482 /* read/write data if it is ready to do so */ 2483 result = Curl_readwrite(data, &done); 2484 2485 if(done || (result == CURLE_RECV_ERROR)) { 2486 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race 2487 * condition and the server closed the reused connection exactly when 2488 * we wanted to use it, so figure out if that is indeed the case. 2489 */ 2490 CURLcode ret = Curl_retry_request(data, &newurl); 2491 if(!ret) 2492 retry = (newurl)?TRUE:FALSE; 2493 else if(!result) 2494 result = ret; 2495 2496 if(retry) { 2497 /* if we are to retry, set the result to OK and consider the 2498 request as done */ 2499 result = CURLE_OK; 2500 done = TRUE; 2501 } 2502 } 2503 else if((CURLE_HTTP2_STREAM == result) && 2504 Curl_h2_http_1_1_error(data)) { 2505 CURLcode ret = Curl_retry_request(data, &newurl); 2506 2507 if(!ret) { 2508 infof(data, "Downgrades to HTTP/1.1"); 2509 streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1"); 2510 data->state.httpwant = CURL_HTTP_VERSION_1_1; 2511 /* clear the error message bit too as we ignore the one we got */ 2512 data->state.errorbuf = FALSE; 2513 if(!newurl) 2514 /* typically for HTTP_1_1_REQUIRED error on first flight */ 2515 newurl = strdup(data->state.url); 2516 /* if we are to retry, set the result to OK and consider the request 2517 as done */ 2518 retry = TRUE; 2519 result = CURLE_OK; 2520 done = TRUE; 2521 } 2522 else 2523 result = ret; 2524 } 2525 2526 if(result) { 2527 /* 2528 * The transfer phase returned error, we mark the connection to get 2529 * closed to prevent being reused. This is because we can't possibly 2530 * know if the connection is in a good shape or not now. Unless it is 2531 * a protocol which uses two "channels" like FTP, as then the error 2532 * happened in the data connection. 2533 */ 2534 2535 if(!(data->conn->handler->flags & PROTOPT_DUAL) && 2536 result != CURLE_HTTP2_STREAM) 2537 streamclose(data->conn, "Transfer returned error"); 2538 2539 Curl_posttransfer(data); 2540 multi_done(data, result, TRUE); 2541 } 2542 else if(done) { 2543 2544 /* call this even if the readwrite function returned error */ 2545 Curl_posttransfer(data); 2546 2547 /* When we follow redirects or is set to retry the connection, we must 2548 to go back to the CONNECT state */ 2549 if(data->req.newurl || retry) { 2550 followtype follow = FOLLOW_NONE; 2551 if(!retry) { 2552 /* if the URL is a follow-location and not just a retried request 2553 then figure out the URL here */ 2554 free(newurl); 2555 newurl = data->req.newurl; 2556 data->req.newurl = NULL; 2557 follow = FOLLOW_REDIR; 2558 } 2559 else 2560 follow = FOLLOW_RETRY; 2561 (void)multi_done(data, CURLE_OK, FALSE); 2562 /* multi_done() might return CURLE_GOT_NOTHING */ 2563 result = Curl_follow(data, newurl, follow); 2564 if(!result) { 2565 multistate(data, MSTATE_CONNECT); 2566 rc = CURLM_CALL_MULTI_PERFORM; 2567 } 2568 free(newurl); 2569 } 2570 else { 2571 /* after the transfer is done, go DONE */ 2572 2573 /* but first check to see if we got a location info even though we're 2574 not following redirects */ 2575 if(data->req.location) { 2576 free(newurl); 2577 newurl = data->req.location; 2578 data->req.location = NULL; 2579 result = Curl_follow(data, newurl, FOLLOW_FAKE); 2580 free(newurl); 2581 if(result) { 2582 stream_error = TRUE; 2583 result = multi_done(data, result, TRUE); 2584 } 2585 } 2586 2587 if(!result) { 2588 multistate(data, MSTATE_DONE); 2589 rc = CURLM_CALL_MULTI_PERFORM; 2590 } 2591 } 2592 } 2593 else if(data->state.select_bits) { 2594 /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer 2595 won't get stuck on this transfer at the expense of other concurrent 2596 transfers */ 2597 Curl_expire(data, 0, EXPIRE_RUN_NOW); 2598 } 2599 break; 2600 } 2601 2602 case MSTATE_DONE: 2603 /* this state is highly transient, so run another loop after this */ 2604 rc = CURLM_CALL_MULTI_PERFORM; 2605 2606 if(data->conn) { 2607 CURLcode res; 2608 2609 if(data->conn->bits.multiplex) 2610 /* Check if we can move pending requests to connection */ 2611 process_pending_handles(multi); /* multiplexing */ 2612 2613 /* post-transfer command */ 2614 res = multi_done(data, result, FALSE); 2615 2616 /* allow a previously set error code take precedence */ 2617 if(!result) 2618 result = res; 2619 } 2620 2621#ifndef CURL_DISABLE_FTP 2622 if(data->state.wildcardmatch) { 2623 if(data->wildcard->state != CURLWC_DONE) { 2624 /* if a wildcard is set and we are not ending -> lets start again 2625 with MSTATE_INIT */ 2626 multistate(data, MSTATE_INIT); 2627 break; 2628 } 2629 } 2630#endif 2631 /* after we have DONE what we're supposed to do, go COMPLETED, and 2632 it doesn't matter what the multi_done() returned! */ 2633 multistate(data, MSTATE_COMPLETED); 2634 break; 2635 2636 case MSTATE_COMPLETED: 2637 break; 2638 2639 case MSTATE_PENDING: 2640 case MSTATE_MSGSENT: 2641 /* handles in these states should NOT be in this list */ 2642 DEBUGASSERT(0); 2643 break; 2644 2645 default: 2646 return CURLM_INTERNAL_ERROR; 2647 } 2648 2649 if(data->conn && 2650 data->mstate >= MSTATE_CONNECT && 2651 data->mstate < MSTATE_DO && 2652 rc != CURLM_CALL_MULTI_PERFORM && 2653 !multi_ischanged(multi, false)) { 2654 /* We now handle stream timeouts if and only if this will be the last 2655 * loop iteration. We only check this on the last iteration to ensure 2656 * that if we know we have additional work to do immediately 2657 * (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before 2658 * declaring the connection timed out as we may almost have a completed 2659 * connection. */ 2660 multi_handle_timeout(data, nowp, &stream_error, &result, TRUE); 2661 } 2662 2663statemachine_end: 2664 2665 if(data->mstate < MSTATE_COMPLETED) { 2666 if(result) { 2667 /* 2668 * If an error was returned, and we aren't in completed state now, 2669 * then we go to completed and consider this transfer aborted. 2670 */ 2671 2672 /* NOTE: no attempt to disconnect connections must be made 2673 in the case blocks above - cleanup happens only here */ 2674 2675 /* Check if we can move pending requests to send pipe */ 2676 process_pending_handles(multi); /* connection */ 2677 2678 if(data->conn) { 2679 if(stream_error) { 2680 /* Don't attempt to send data over a connection that timed out */ 2681 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT; 2682 struct connectdata *conn = data->conn; 2683 2684 /* This is where we make sure that the conn pointer is reset. 2685 We don't have to do this in every case block above where a 2686 failure is detected */ 2687 Curl_detach_connection(data); 2688 2689 /* remove connection from cache */ 2690 Curl_conncache_remove_conn(data, conn, TRUE); 2691 2692 /* disconnect properly */ 2693 Curl_disconnect(data, conn, dead_connection); 2694 } 2695 } 2696 else if(data->mstate == MSTATE_CONNECT) { 2697 /* Curl_connect() failed */ 2698 (void)Curl_posttransfer(data); 2699 } 2700 2701 multistate(data, MSTATE_COMPLETED); 2702 rc = CURLM_CALL_MULTI_PERFORM; 2703 } 2704 /* if there's still a connection to use, call the progress function */ 2705 else if(data->conn && Curl_pgrsUpdate(data)) { 2706 /* aborted due to progress callback return code must close the 2707 connection */ 2708 result = CURLE_ABORTED_BY_CALLBACK; 2709 streamclose(data->conn, "Aborted by callback"); 2710 2711 /* if not yet in DONE state, go there, otherwise COMPLETED */ 2712 multistate(data, (data->mstate < MSTATE_DONE)? 2713 MSTATE_DONE: MSTATE_COMPLETED); 2714 rc = CURLM_CALL_MULTI_PERFORM; 2715 } 2716 } 2717 2718 if(MSTATE_COMPLETED == data->mstate) { 2719 if(data->set.fmultidone) { 2720 /* signal via callback instead */ 2721 data->set.fmultidone(data, result); 2722 } 2723 else { 2724 /* now fill in the Curl_message with this info */ 2725 msg = &data->msg; 2726 2727 msg->extmsg.msg = CURLMSG_DONE; 2728 msg->extmsg.easy_handle = data; 2729 msg->extmsg.data.result = result; 2730 2731 multi_addmsg(multi, msg); 2732 DEBUGASSERT(!data->conn); 2733 } 2734 multistate(data, MSTATE_MSGSENT); 2735 2736 /* add this handle to the list of msgsent handles */ 2737 Curl_llist_insert_next(&multi->msgsent, multi->msgsent.tail, data, 2738 &data->connect_queue); 2739 /* unlink from the main list */ 2740 unlink_easy(multi, data); 2741 return CURLM_OK; 2742 } 2743 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); 2744 2745 data->result = result; 2746 return rc; 2747} 2748 2749 2750CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) 2751{ 2752 struct Curl_easy *data; 2753 CURLMcode returncode = CURLM_OK; 2754 struct Curl_tree *t; 2755 struct curltime now = Curl_now(); 2756 2757 if(!GOOD_MULTI_HANDLE(multi)) 2758 return CURLM_BAD_HANDLE; 2759 2760 if(multi->in_callback) 2761 return CURLM_RECURSIVE_API_CALL; 2762 2763 data = multi->easyp; 2764 if(data) { 2765 CURLMcode result; 2766 bool nosig = data->set.no_signal; 2767 SIGPIPE_VARIABLE(pipe_st); 2768 sigpipe_ignore(data, &pipe_st); 2769 /* Do the loop and only alter the signal ignore state if the next handle 2770 has a different NO_SIGNAL state than the previous */ 2771 do { 2772 /* the current node might be unlinked in multi_runsingle(), get the next 2773 pointer now */ 2774 struct Curl_easy *datanext = data->next; 2775 if(data->set.no_signal != nosig) { 2776 sigpipe_restore(&pipe_st); 2777 sigpipe_ignore(data, &pipe_st); 2778 nosig = data->set.no_signal; 2779 } 2780 result = multi_runsingle(multi, &now, data); 2781 if(result) 2782 returncode = result; 2783 data = datanext; /* operate on next handle */ 2784 } while(data); 2785 sigpipe_restore(&pipe_st); 2786 } 2787 2788 /* 2789 * Simply remove all expired timers from the splay since handles are dealt 2790 * with unconditionally by this function and curl_multi_timeout() requires 2791 * that already passed/handled expire times are removed from the splay. 2792 * 2793 * It is important that the 'now' value is set at the entry of this function 2794 * and not for the current time as it may have ticked a little while since 2795 * then and then we risk this loop to remove timers that actually have not 2796 * been handled! 2797 */ 2798 do { 2799 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); 2800 if(t) 2801 /* the removed may have another timeout in queue */ 2802 (void)add_next_timeout(now, multi, t->payload); 2803 2804 } while(t); 2805 2806 *running_handles = multi->num_alive; 2807 2808 if(CURLM_OK >= returncode) 2809 returncode = Curl_update_timer(multi); 2810 2811 return returncode; 2812} 2813 2814/* unlink_all_msgsent_handles() detaches all those easy handles from this 2815 multi handle */ 2816static void unlink_all_msgsent_handles(struct Curl_multi *multi) 2817{ 2818 struct Curl_llist_element *e = multi->msgsent.head; 2819 if(e) { 2820 struct Curl_easy *data = e->ptr; 2821 DEBUGASSERT(data->mstate == MSTATE_MSGSENT); 2822 data->multi = NULL; 2823 } 2824} 2825 2826CURLMcode curl_multi_cleanup(struct Curl_multi *multi) 2827{ 2828 struct Curl_easy *data; 2829 struct Curl_easy *nextdata; 2830 2831 if(GOOD_MULTI_HANDLE(multi)) { 2832 if(multi->in_callback) 2833 return CURLM_RECURSIVE_API_CALL; 2834 2835 multi->magic = 0; /* not good anymore */ 2836 2837 unlink_all_msgsent_handles(multi); 2838 process_pending_handles(multi); 2839 /* First remove all remaining easy handles */ 2840 data = multi->easyp; 2841 while(data) { 2842 nextdata = data->next; 2843 if(!data->state.done && data->conn) 2844 /* if DONE was never called for this handle */ 2845 (void)multi_done(data, CURLE_OK, TRUE); 2846 if(data->dns.hostcachetype == HCACHE_MULTI) { 2847 /* clear out the usage of the shared DNS cache */ 2848 Curl_hostcache_clean(data, data->dns.hostcache); 2849 data->dns.hostcache = NULL; 2850 data->dns.hostcachetype = HCACHE_NONE; 2851 } 2852 2853 /* Clear the pointer to the connection cache */ 2854 data->state.conn_cache = NULL; 2855 data->multi = NULL; /* clear the association */ 2856 2857#ifdef USE_LIBPSL 2858 if(data->psl == &multi->psl) 2859 data->psl = NULL; 2860#endif 2861 2862 data = nextdata; 2863 } 2864 2865 /* Close all the connections in the connection cache */ 2866 Curl_conncache_close_all_connections(&multi->conn_cache); 2867 2868 sockhash_destroy(&multi->sockhash); 2869 Curl_conncache_destroy(&multi->conn_cache); 2870 Curl_hash_destroy(&multi->hostcache); 2871 Curl_psl_destroy(&multi->psl); 2872 2873#ifdef USE_WINSOCK 2874 WSACloseEvent(multi->wsa_event); 2875#else 2876#ifdef ENABLE_WAKEUP 2877 wakeup_close(multi->wakeup_pair[0]); 2878 wakeup_close(multi->wakeup_pair[1]); 2879#endif 2880#endif 2881 2882#ifdef USE_SSL 2883 Curl_free_multi_ssl_backend_data(multi->ssl_backend_data); 2884#endif 2885 2886 free(multi); 2887 2888 return CURLM_OK; 2889 } 2890 return CURLM_BAD_HANDLE; 2891} 2892 2893/* 2894 * curl_multi_info_read() 2895 * 2896 * This function is the primary way for a multi/multi_socket application to 2897 * figure out if a transfer has ended. We MUST make this function as fast as 2898 * possible as it will be polled frequently and we MUST NOT scan any lists in 2899 * here to figure out things. We must scale fine to thousands of handles and 2900 * beyond. The current design is fully O(1). 2901 */ 2902 2903CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) 2904{ 2905 struct Curl_message *msg; 2906 2907 *msgs_in_queue = 0; /* default to none */ 2908 2909 if(GOOD_MULTI_HANDLE(multi) && 2910 !multi->in_callback && 2911 Curl_llist_count(&multi->msglist)) { 2912 /* there is one or more messages in the list */ 2913 struct Curl_llist_element *e; 2914 2915 /* extract the head of the list to return */ 2916 e = multi->msglist.head; 2917 2918 msg = e->ptr; 2919 2920 /* remove the extracted entry */ 2921 Curl_llist_remove(&multi->msglist, e, NULL); 2922 2923 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist)); 2924 2925 return &msg->extmsg; 2926 } 2927 return NULL; 2928} 2929 2930/* 2931 * singlesocket() checks what sockets we deal with and their "action state" 2932 * and if we have a different state in any of those sockets from last time we 2933 * call the callback accordingly. 2934 */ 2935static CURLMcode singlesocket(struct Curl_multi *multi, 2936 struct Curl_easy *data) 2937{ 2938 struct easy_pollset cur_poll; 2939 unsigned int i; 2940 struct Curl_sh_entry *entry; 2941 curl_socket_t s; 2942 int rc; 2943 2944 /* Fill in the 'current' struct with the state as it is now: what sockets to 2945 supervise and for what actions */ 2946 multi_getsock(data, &cur_poll); 2947 2948 /* We have 0 .. N sockets already and we get to know about the 0 .. M 2949 sockets we should have from now on. Detect the differences, remove no 2950 longer supervised ones and add new ones */ 2951 2952 /* walk over the sockets we got right now */ 2953 for(i = 0; i < cur_poll.num; i++) { 2954 unsigned char cur_action = cur_poll.actions[i]; 2955 unsigned char last_action = 0; 2956 int comboaction; 2957 2958 s = cur_poll.sockets[i]; 2959 2960 /* get it from the hash */ 2961 entry = sh_getentry(&multi->sockhash, s); 2962 if(entry) { 2963 /* check if new for this transfer */ 2964 unsigned int j; 2965 for(j = 0; j< data->last_poll.num; j++) { 2966 if(s == data->last_poll.sockets[j]) { 2967 last_action = data->last_poll.actions[j]; 2968 break; 2969 } 2970 } 2971 } 2972 else { 2973 /* this is a socket we didn't have before, add it to the hash! */ 2974 entry = sh_addentry(&multi->sockhash, s); 2975 if(!entry) 2976 /* fatal */ 2977 return CURLM_OUT_OF_MEMORY; 2978 } 2979 if(last_action && (last_action != cur_action)) { 2980 /* Socket was used already, but different action now */ 2981 if(last_action & CURL_POLL_IN) 2982 entry->readers--; 2983 if(last_action & CURL_POLL_OUT) 2984 entry->writers--; 2985 if(cur_action & CURL_POLL_IN) 2986 entry->readers++; 2987 if(cur_action & CURL_POLL_OUT) 2988 entry->writers++; 2989 } 2990 else if(!last_action) { 2991 /* a new transfer using this socket */ 2992 entry->users++; 2993 if(cur_action & CURL_POLL_IN) 2994 entry->readers++; 2995 if(cur_action & CURL_POLL_OUT) 2996 entry->writers++; 2997 2998 /* add 'data' to the transfer hash on this socket! */ 2999 if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */ 3000 sizeof(struct Curl_easy *), data)) { 3001 Curl_hash_destroy(&entry->transfers); 3002 return CURLM_OUT_OF_MEMORY; 3003 } 3004 } 3005 3006 comboaction = (entry->writers ? CURL_POLL_OUT : 0) | 3007 (entry->readers ? CURL_POLL_IN : 0); 3008 3009 /* socket existed before and has the same action set as before */ 3010 if(last_action && ((int)entry->action == comboaction)) 3011 /* same, continue */ 3012 continue; 3013 3014 if(multi->socket_cb) { 3015 set_in_callback(multi, TRUE); 3016 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp, 3017 entry->socketp); 3018 3019 set_in_callback(multi, FALSE); 3020 if(rc == -1) { 3021 multi->dead = TRUE; 3022 return CURLM_ABORTED_BY_CALLBACK; 3023 } 3024 } 3025 3026 entry->action = comboaction; /* store the current action state */ 3027 } 3028 3029 /* Check for last_poll.sockets that no longer appear in cur_poll.sockets. 3030 * Need to remove the easy handle from the multi->sockhash->transfers and 3031 * remove multi->sockhash entry when this was the last transfer */ 3032 for(i = 0; i< data->last_poll.num; i++) { 3033 unsigned int j; 3034 bool stillused = FALSE; 3035 s = data->last_poll.sockets[i]; 3036 for(j = 0; j < cur_poll.num; j++) { 3037 if(s == cur_poll.sockets[j]) { 3038 /* this is still supervised */ 3039 stillused = TRUE; 3040 break; 3041 } 3042 } 3043 if(stillused) 3044 continue; 3045 3046 entry = sh_getentry(&multi->sockhash, s); 3047 /* if this is NULL here, the socket has been closed and notified so 3048 already by Curl_multi_closed() */ 3049 if(entry) { 3050 unsigned char oldactions = data->last_poll.actions[i]; 3051 /* this socket has been removed. Decrease user count */ 3052 entry->users--; 3053 if(oldactions & CURL_POLL_OUT) 3054 entry->writers--; 3055 if(oldactions & CURL_POLL_IN) 3056 entry->readers--; 3057 if(!entry->users) { 3058 if(multi->socket_cb) { 3059 set_in_callback(multi, TRUE); 3060 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, 3061 multi->socket_userp, entry->socketp); 3062 set_in_callback(multi, FALSE); 3063 if(rc == -1) { 3064 multi->dead = TRUE; 3065 return CURLM_ABORTED_BY_CALLBACK; 3066 } 3067 } 3068 sh_delentry(entry, &multi->sockhash, s); 3069 } 3070 else { 3071 /* still users, but remove this handle as a user of this socket */ 3072 if(Curl_hash_delete(&entry->transfers, (char *)&data, 3073 sizeof(struct Curl_easy *))) { 3074 DEBUGASSERT(NULL); 3075 } 3076 } 3077 } 3078 } /* for loop over num */ 3079 3080 /* Remember for next time */ 3081 memcpy(&data->last_poll, &cur_poll, sizeof(data->last_poll)); 3082 return CURLM_OK; 3083} 3084 3085CURLcode Curl_updatesocket(struct Curl_easy *data) 3086{ 3087 if(singlesocket(data->multi, data)) 3088 return CURLE_ABORTED_BY_CALLBACK; 3089 return CURLE_OK; 3090} 3091 3092 3093/* 3094 * Curl_multi_closed() 3095 * 3096 * Used by the connect code to tell the multi_socket code that one of the 3097 * sockets we were using is about to be closed. This function will then 3098 * remove it from the sockethash for this handle to make the multi_socket API 3099 * behave properly, especially for the case when libcurl will create another 3100 * socket again and it gets the same file descriptor number. 3101 */ 3102 3103void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) 3104{ 3105 if(data) { 3106 /* if there's still an easy handle associated with this connection */ 3107 struct Curl_multi *multi = data->multi; 3108 if(multi) { 3109 /* this is set if this connection is part of a handle that is added to 3110 a multi handle, and only then this is necessary */ 3111 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); 3112 3113 if(entry) { 3114 int rc = 0; 3115 if(multi->socket_cb) { 3116 set_in_callback(multi, TRUE); 3117 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, 3118 multi->socket_userp, entry->socketp); 3119 set_in_callback(multi, FALSE); 3120 } 3121 3122 /* now remove it from the socket hash */ 3123 sh_delentry(entry, &multi->sockhash, s); 3124 if(rc == -1) 3125 /* This just marks the multi handle as "dead" without returning an 3126 error code primarily because this function is used from many 3127 places where propagating an error back is tricky. */ 3128 multi->dead = TRUE; 3129 } 3130 } 3131 } 3132} 3133 3134/* 3135 * add_next_timeout() 3136 * 3137 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called 3138 * when it has just been removed from the splay tree because the timeout has 3139 * expired. This function is then to advance in the list to pick the next 3140 * timeout to use (skip the already expired ones) and add this node back to 3141 * the splay tree again. 3142 * 3143 * The splay tree only has each sessionhandle as a single node and the nearest 3144 * timeout is used to sort it on. 3145 */ 3146static CURLMcode add_next_timeout(struct curltime now, 3147 struct Curl_multi *multi, 3148 struct Curl_easy *d) 3149{ 3150 struct curltime *tv = &d->state.expiretime; 3151 struct Curl_llist *list = &d->state.timeoutlist; 3152 struct Curl_llist_element *e; 3153 struct time_node *node = NULL; 3154 3155 /* move over the timeout list for this specific handle and remove all 3156 timeouts that are now passed tense and store the next pending 3157 timeout in *tv */ 3158 for(e = list->head; e;) { 3159 struct Curl_llist_element *n = e->next; 3160 timediff_t diff; 3161 node = (struct time_node *)e->ptr; 3162 diff = Curl_timediff_us(node->time, now); 3163 if(diff <= 0) 3164 /* remove outdated entry */ 3165 Curl_llist_remove(list, e, NULL); 3166 else 3167 /* the list is sorted so get out on the first mismatch */ 3168 break; 3169 e = n; 3170 } 3171 e = list->head; 3172 if(!e) { 3173 /* clear the expire times within the handles that we remove from the 3174 splay tree */ 3175 tv->tv_sec = 0; 3176 tv->tv_usec = 0; 3177 } 3178 else { 3179 /* copy the first entry to 'tv' */ 3180 memcpy(tv, &node->time, sizeof(*tv)); 3181 3182 /* Insert this node again into the splay. Keep the timer in the list in 3183 case we need to recompute future timers. */ 3184 multi->timetree = Curl_splayinsert(*tv, multi->timetree, 3185 &d->state.timenode); 3186 } 3187 return CURLM_OK; 3188} 3189 3190static CURLMcode multi_socket(struct Curl_multi *multi, 3191 bool checkall, 3192 curl_socket_t s, 3193 int ev_bitmask, 3194 int *running_handles) 3195{ 3196 CURLMcode result = CURLM_OK; 3197 struct Curl_easy *data = NULL; 3198 struct Curl_tree *t; 3199 struct curltime now = Curl_now(); 3200 bool first = FALSE; 3201 bool nosig = FALSE; 3202 SIGPIPE_VARIABLE(pipe_st); 3203 3204 if(checkall) { 3205 /* *perform() deals with running_handles on its own */ 3206 result = curl_multi_perform(multi, running_handles); 3207 3208 /* walk through each easy handle and do the socket state change magic 3209 and callbacks */ 3210 if(result != CURLM_BAD_HANDLE) { 3211 data = multi->easyp; 3212 while(data && !result) { 3213 result = singlesocket(multi, data); 3214 data = data->next; 3215 } 3216 } 3217 3218 /* or should we fall-through and do the timer-based stuff? */ 3219 return result; 3220 } 3221 if(s != CURL_SOCKET_TIMEOUT) { 3222 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); 3223 3224 if(!entry) 3225 /* Unmatched socket, we can't act on it but we ignore this fact. In 3226 real-world tests it has been proved that libevent can in fact give 3227 the application actions even though the socket was just previously 3228 asked to get removed, so thus we better survive stray socket actions 3229 and just move on. */ 3230 ; 3231 else { 3232 struct Curl_hash_iterator iter; 3233 struct Curl_hash_element *he; 3234 3235 /* the socket can be shared by many transfers, iterate */ 3236 Curl_hash_start_iterate(&entry->transfers, &iter); 3237 for(he = Curl_hash_next_element(&iter); he; 3238 he = Curl_hash_next_element(&iter)) { 3239 data = (struct Curl_easy *)he->ptr; 3240 DEBUGASSERT(data); 3241 DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER); 3242 3243 if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK)) 3244 /* set socket event bitmask if they're not locked */ 3245 data->state.select_bits = (unsigned char)ev_bitmask; 3246 3247 Curl_expire(data, 0, EXPIRE_RUN_NOW); 3248 } 3249 3250 /* Now we fall-through and do the timer-based stuff, since we don't want 3251 to force the user to have to deal with timeouts as long as at least 3252 one connection in fact has traffic. */ 3253 3254 data = NULL; /* set data to NULL again to avoid calling 3255 multi_runsingle() in case there's no need to */ 3256 now = Curl_now(); /* get a newer time since the multi_runsingle() loop 3257 may have taken some time */ 3258 } 3259 } 3260 else { 3261 /* Asked to run due to time-out. Clear the 'lastcall' variable to force 3262 Curl_update_timer() to trigger a callback to the app again even if the 3263 same timeout is still the one to run after this call. That handles the 3264 case when the application asks libcurl to run the timeout 3265 prematurely. */ 3266 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); 3267 } 3268 3269 /* 3270 * The loop following here will go on as long as there are expire-times left 3271 * to process in the splay and 'data' will be re-assigned for every expired 3272 * handle we deal with. 3273 */ 3274 do { 3275 /* the first loop lap 'data' can be NULL */ 3276 if(data) { 3277 if(!first) { 3278 first = TRUE; 3279 nosig = data->set.no_signal; /* initial state */ 3280 sigpipe_ignore(data, &pipe_st); 3281 } 3282 else if(data->set.no_signal != nosig) { 3283 sigpipe_restore(&pipe_st); 3284 sigpipe_ignore(data, &pipe_st); 3285 nosig = data->set.no_signal; /* remember new state */ 3286 } 3287 result = multi_runsingle(multi, &now, data); 3288 3289 if(CURLM_OK >= result) { 3290 /* get the socket(s) and check if the state has been changed since 3291 last */ 3292 result = singlesocket(multi, data); 3293 if(result) 3294 break; 3295 } 3296 } 3297 3298 /* Check if there's one (more) expired timer to deal with! This function 3299 extracts a matching node if there is one */ 3300 3301 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); 3302 if(t) { 3303 data = t->payload; /* assign this for next loop */ 3304 (void)add_next_timeout(now, multi, t->payload); 3305 } 3306 3307 } while(t); 3308 if(first) 3309 sigpipe_restore(&pipe_st); 3310 3311 *running_handles = multi->num_alive; 3312 return result; 3313} 3314 3315#undef curl_multi_setopt 3316CURLMcode curl_multi_setopt(struct Curl_multi *multi, 3317 CURLMoption option, ...) 3318{ 3319 CURLMcode res = CURLM_OK; 3320 va_list param; 3321 unsigned long uarg; 3322 3323 if(!GOOD_MULTI_HANDLE(multi)) 3324 return CURLM_BAD_HANDLE; 3325 3326 if(multi->in_callback) 3327 return CURLM_RECURSIVE_API_CALL; 3328 3329 va_start(param, option); 3330 3331 switch(option) { 3332 case CURLMOPT_SOCKETFUNCTION: 3333 multi->socket_cb = va_arg(param, curl_socket_callback); 3334 break; 3335 case CURLMOPT_SOCKETDATA: 3336 multi->socket_userp = va_arg(param, void *); 3337 break; 3338 case CURLMOPT_PUSHFUNCTION: 3339 multi->push_cb = va_arg(param, curl_push_callback); 3340 break; 3341 case CURLMOPT_PUSHDATA: 3342 multi->push_userp = va_arg(param, void *); 3343 break; 3344 case CURLMOPT_PIPELINING: 3345 multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0; 3346 break; 3347 case CURLMOPT_TIMERFUNCTION: 3348 multi->timer_cb = va_arg(param, curl_multi_timer_callback); 3349 break; 3350 case CURLMOPT_TIMERDATA: 3351 multi->timer_userp = va_arg(param, void *); 3352 break; 3353 case CURLMOPT_MAXCONNECTS: 3354 uarg = va_arg(param, unsigned long); 3355 if(uarg <= UINT_MAX) 3356 multi->maxconnects = (unsigned int)uarg; 3357 break; 3358 case CURLMOPT_MAX_HOST_CONNECTIONS: 3359 multi->max_host_connections = va_arg(param, long); 3360 break; 3361 case CURLMOPT_MAX_TOTAL_CONNECTIONS: 3362 multi->max_total_connections = va_arg(param, long); 3363 break; 3364 /* options formerly used for pipelining */ 3365 case CURLMOPT_MAX_PIPELINE_LENGTH: 3366 break; 3367 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: 3368 break; 3369 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE: 3370 break; 3371 case CURLMOPT_PIPELINING_SITE_BL: 3372 break; 3373 case CURLMOPT_PIPELINING_SERVER_BL: 3374 break; 3375 case CURLMOPT_MAX_CONCURRENT_STREAMS: 3376 { 3377 long streams = va_arg(param, long); 3378 if((streams < 1) || (streams > INT_MAX)) 3379 streams = 100; 3380 multi->max_concurrent_streams = (unsigned int)streams; 3381 } 3382 break; 3383 default: 3384 res = CURLM_UNKNOWN_OPTION; 3385 break; 3386 } 3387 va_end(param); 3388 return res; 3389} 3390 3391/* we define curl_multi_socket() in the public multi.h header */ 3392#undef curl_multi_socket 3393 3394CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, 3395 int *running_handles) 3396{ 3397 CURLMcode result; 3398 if(multi->in_callback) 3399 return CURLM_RECURSIVE_API_CALL; 3400 result = multi_socket(multi, FALSE, s, 0, running_handles); 3401 if(CURLM_OK >= result) 3402 result = Curl_update_timer(multi); 3403 return result; 3404} 3405 3406CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, 3407 int ev_bitmask, int *running_handles) 3408{ 3409 CURLMcode result; 3410 if(multi->in_callback) 3411 return CURLM_RECURSIVE_API_CALL; 3412 result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles); 3413 if(CURLM_OK >= result) 3414 result = Curl_update_timer(multi); 3415 return result; 3416} 3417 3418CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) 3419{ 3420 CURLMcode result; 3421 if(multi->in_callback) 3422 return CURLM_RECURSIVE_API_CALL; 3423 result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); 3424 if(CURLM_OK >= result) 3425 result = Curl_update_timer(multi); 3426 return result; 3427} 3428 3429static CURLMcode multi_timeout(struct Curl_multi *multi, 3430 long *timeout_ms) 3431{ 3432 static const struct curltime tv_zero = {0, 0}; 3433 3434 if(multi->dead) { 3435 *timeout_ms = 0; 3436 return CURLM_OK; 3437 } 3438 3439 if(multi->timetree) { 3440 /* we have a tree of expire times */ 3441 struct curltime now = Curl_now(); 3442 3443 /* splay the lowest to the bottom */ 3444 multi->timetree = Curl_splay(tv_zero, multi->timetree); 3445 3446 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) { 3447 /* some time left before expiration */ 3448 timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now); 3449 /* this should be safe even on 32 bit archs, as we don't use that 3450 overly long timeouts */ 3451 *timeout_ms = (long)diff; 3452 } 3453 else 3454 /* 0 means immediately */ 3455 *timeout_ms = 0; 3456 } 3457 else 3458 *timeout_ms = -1; 3459 3460 return CURLM_OK; 3461} 3462 3463CURLMcode curl_multi_timeout(struct Curl_multi *multi, 3464 long *timeout_ms) 3465{ 3466 /* First, make some basic checks that the CURLM handle is a good handle */ 3467 if(!GOOD_MULTI_HANDLE(multi)) 3468 return CURLM_BAD_HANDLE; 3469 3470 if(multi->in_callback) 3471 return CURLM_RECURSIVE_API_CALL; 3472 3473 return multi_timeout(multi, timeout_ms); 3474} 3475 3476/* 3477 * Tell the application it should update its timers, if it subscribes to the 3478 * update timer callback. 3479 */ 3480CURLMcode Curl_update_timer(struct Curl_multi *multi) 3481{ 3482 long timeout_ms; 3483 int rc; 3484 3485 if(!multi->timer_cb || multi->dead) 3486 return CURLM_OK; 3487 if(multi_timeout(multi, &timeout_ms)) { 3488 return CURLM_OK; 3489 } 3490 if(timeout_ms < 0) { 3491 static const struct curltime none = {0, 0}; 3492 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) { 3493 multi->timer_lastcall = none; 3494 /* there's no timeout now but there was one previously, tell the app to 3495 disable it */ 3496 set_in_callback(multi, TRUE); 3497 rc = multi->timer_cb(multi, -1, multi->timer_userp); 3498 set_in_callback(multi, FALSE); 3499 if(rc == -1) { 3500 multi->dead = TRUE; 3501 return CURLM_ABORTED_BY_CALLBACK; 3502 } 3503 return CURLM_OK; 3504 } 3505 return CURLM_OK; 3506 } 3507 3508 /* When multi_timeout() is done, multi->timetree points to the node with the 3509 * timeout we got the (relative) time-out time for. We can thus easily check 3510 * if this is the same (fixed) time as we got in a previous call and then 3511 * avoid calling the callback again. */ 3512 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0) 3513 return CURLM_OK; 3514 3515 multi->timer_lastcall = multi->timetree->key; 3516 3517 set_in_callback(multi, TRUE); 3518 rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp); 3519 set_in_callback(multi, FALSE); 3520 if(rc == -1) { 3521 multi->dead = TRUE; 3522 return CURLM_ABORTED_BY_CALLBACK; 3523 } 3524 return CURLM_OK; 3525} 3526 3527/* 3528 * multi_deltimeout() 3529 * 3530 * Remove a given timestamp from the list of timeouts. 3531 */ 3532static void 3533multi_deltimeout(struct Curl_easy *data, expire_id eid) 3534{ 3535 struct Curl_llist_element *e; 3536 struct Curl_llist *timeoutlist = &data->state.timeoutlist; 3537 /* find and remove the specific node from the list */ 3538 for(e = timeoutlist->head; e; e = e->next) { 3539 struct time_node *n = (struct time_node *)e->ptr; 3540 if(n->eid == eid) { 3541 Curl_llist_remove(timeoutlist, e, NULL); 3542 return; 3543 } 3544 } 3545} 3546 3547/* 3548 * multi_addtimeout() 3549 * 3550 * Add a timestamp to the list of timeouts. Keep the list sorted so that head 3551 * of list is always the timeout nearest in time. 3552 * 3553 */ 3554static CURLMcode 3555multi_addtimeout(struct Curl_easy *data, 3556 struct curltime *stamp, 3557 expire_id eid) 3558{ 3559 struct Curl_llist_element *e; 3560 struct time_node *node; 3561 struct Curl_llist_element *prev = NULL; 3562 size_t n; 3563 struct Curl_llist *timeoutlist = &data->state.timeoutlist; 3564 3565 node = &data->state.expires[eid]; 3566 3567 /* copy the timestamp and id */ 3568 memcpy(&node->time, stamp, sizeof(*stamp)); 3569 node->eid = eid; /* also marks it as in use */ 3570 3571 n = Curl_llist_count(timeoutlist); 3572 if(n) { 3573 /* find the correct spot in the list */ 3574 for(e = timeoutlist->head; e; e = e->next) { 3575 struct time_node *check = (struct time_node *)e->ptr; 3576 timediff_t diff = Curl_timediff(check->time, node->time); 3577 if(diff > 0) 3578 break; 3579 prev = e; 3580 } 3581 3582 } 3583 /* else 3584 this is the first timeout on the list */ 3585 3586 Curl_llist_insert_next(timeoutlist, prev, node, &node->list); 3587 return CURLM_OK; 3588} 3589 3590/* 3591 * Curl_expire() 3592 * 3593 * given a number of milliseconds from now to use to set the 'act before 3594 * this'-time for the transfer, to be extracted by curl_multi_timeout() 3595 * 3596 * The timeout will be added to a queue of timeouts if it defines a moment in 3597 * time that is later than the current head of queue. 3598 * 3599 * Expire replaces a former timeout using the same id if already set. 3600 */ 3601void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) 3602{ 3603 struct Curl_multi *multi = data->multi; 3604 struct curltime *nowp = &data->state.expiretime; 3605 struct curltime set; 3606 3607 /* this is only interesting while there is still an associated multi struct 3608 remaining! */ 3609 if(!multi) 3610 return; 3611 3612 DEBUGASSERT(id < EXPIRE_LAST); 3613 3614 set = Curl_now(); 3615 set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */ 3616 set.tv_usec += (unsigned int)(milli%1000)*1000; 3617 3618 if(set.tv_usec >= 1000000) { 3619 set.tv_sec++; 3620 set.tv_usec -= 1000000; 3621 } 3622 3623 /* Remove any timer with the same id just in case. */ 3624 multi_deltimeout(data, id); 3625 3626 /* Add it to the timer list. It must stay in the list until it has expired 3627 in case we need to recompute the minimum timer later. */ 3628 multi_addtimeout(data, &set, id); 3629 3630 if(nowp->tv_sec || nowp->tv_usec) { 3631 /* This means that the struct is added as a node in the splay tree. 3632 Compare if the new time is earlier, and only remove-old/add-new if it 3633 is. */ 3634 timediff_t diff = Curl_timediff(set, *nowp); 3635 int rc; 3636 3637 if(diff > 0) { 3638 /* The current splay tree entry is sooner than this new expiry time. 3639 We don't need to update our splay tree entry. */ 3640 return; 3641 } 3642 3643 /* Since this is an updated time, we must remove the previous entry from 3644 the splay tree first and then re-add the new value */ 3645 rc = Curl_splayremove(multi->timetree, &data->state.timenode, 3646 &multi->timetree); 3647 if(rc) 3648 infof(data, "Internal error removing splay node = %d", rc); 3649 } 3650 3651 /* Indicate that we are in the splay tree and insert the new timer expiry 3652 value since it is our local minimum. */ 3653 *nowp = set; 3654 data->state.timenode.payload = data; 3655 multi->timetree = Curl_splayinsert(*nowp, multi->timetree, 3656 &data->state.timenode); 3657} 3658 3659/* 3660 * Curl_expire_done() 3661 * 3662 * Removes the expire timer. Marks it as done. 3663 * 3664 */ 3665void Curl_expire_done(struct Curl_easy *data, expire_id id) 3666{ 3667 /* remove the timer, if there */ 3668 multi_deltimeout(data, id); 3669} 3670 3671/* 3672 * Curl_expire_clear() 3673 * 3674 * Clear ALL timeout values for this handle. 3675 */ 3676void Curl_expire_clear(struct Curl_easy *data) 3677{ 3678 struct Curl_multi *multi = data->multi; 3679 struct curltime *nowp = &data->state.expiretime; 3680 3681 /* this is only interesting while there is still an associated multi struct 3682 remaining! */ 3683 if(!multi) 3684 return; 3685 3686 if(nowp->tv_sec || nowp->tv_usec) { 3687 /* Since this is an cleared time, we must remove the previous entry from 3688 the splay tree */ 3689 struct Curl_llist *list = &data->state.timeoutlist; 3690 int rc; 3691 3692 rc = Curl_splayremove(multi->timetree, &data->state.timenode, 3693 &multi->timetree); 3694 if(rc) 3695 infof(data, "Internal error clearing splay node = %d", rc); 3696 3697 /* flush the timeout list too */ 3698 while(list->size > 0) { 3699 Curl_llist_remove(list, list->tail, NULL); 3700 } 3701 3702#ifdef DEBUGBUILD 3703 infof(data, "Expire cleared"); 3704#endif 3705 nowp->tv_sec = 0; 3706 nowp->tv_usec = 0; 3707 } 3708} 3709 3710 3711 3712 3713CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, 3714 void *hashp) 3715{ 3716 struct Curl_sh_entry *there = NULL; 3717 3718 there = sh_getentry(&multi->sockhash, s); 3719 3720 if(!there) 3721 return CURLM_BAD_SOCKET; 3722 3723 there->socketp = hashp; 3724 3725 return CURLM_OK; 3726} 3727 3728size_t Curl_multi_max_host_connections(struct Curl_multi *multi) 3729{ 3730 return multi ? multi->max_host_connections : 0; 3731} 3732 3733size_t Curl_multi_max_total_connections(struct Curl_multi *multi) 3734{ 3735 return multi ? multi->max_total_connections : 0; 3736} 3737 3738/* 3739 * When information about a connection has appeared, call this! 3740 */ 3741 3742void Curl_multiuse_state(struct Curl_easy *data, 3743 int bundlestate) /* use BUNDLE_* defines */ 3744{ 3745 struct connectdata *conn; 3746 DEBUGASSERT(data); 3747 DEBUGASSERT(data->multi); 3748 conn = data->conn; 3749 DEBUGASSERT(conn); 3750 DEBUGASSERT(conn->bundle); 3751 3752 conn->bundle->multiuse = bundlestate; 3753 process_pending_handles(data->multi); 3754} 3755 3756/* process_pending_handles() moves all handles from PENDING 3757 back into the main list and change state to CONNECT */ 3758static void process_pending_handles(struct Curl_multi *multi) 3759{ 3760 struct Curl_llist_element *e = multi->pending.head; 3761 if(e) { 3762 struct Curl_easy *data = e->ptr; 3763 3764 DEBUGASSERT(data->mstate == MSTATE_PENDING); 3765 3766 /* put it back into the main list */ 3767 link_easy(multi, data); 3768 3769 multistate(data, MSTATE_CONNECT); 3770 3771 /* Remove this node from the list */ 3772 Curl_llist_remove(&multi->pending, e, NULL); 3773 3774 /* Make sure that the handle will be processed soonish. */ 3775 Curl_expire(data, 0, EXPIRE_RUN_NOW); 3776 3777 /* mark this as having been in the pending queue */ 3778 data->state.previouslypending = TRUE; 3779 } 3780} 3781 3782void Curl_set_in_callback(struct Curl_easy *data, bool value) 3783{ 3784 /* might get called when there is no data pointer! */ 3785 if(data) { 3786 if(data->multi_easy) 3787 data->multi_easy->in_callback = value; 3788 else if(data->multi) 3789 data->multi->in_callback = value; 3790 } 3791} 3792 3793bool Curl_is_in_callback(struct Curl_easy *easy) 3794{ 3795 return ((easy->multi && easy->multi->in_callback) || 3796 (easy->multi_easy && easy->multi_easy->in_callback)); 3797} 3798 3799unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi) 3800{ 3801 DEBUGASSERT(multi); 3802 return multi->max_concurrent_streams; 3803} 3804 3805struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi) 3806{ 3807 struct Curl_easy **a = malloc(sizeof(struct Curl_easy *) * 3808 (multi->num_easy + 1)); 3809 if(a) { 3810 unsigned int i = 0; 3811 struct Curl_easy *e = multi->easyp; 3812 while(e) { 3813 DEBUGASSERT(i < multi->num_easy); 3814 if(!e->state.internal) 3815 a[i++] = e; 3816 e = e->next; 3817 } 3818 a[i] = NULL; /* last entry is a NULL */ 3819 } 3820 return a; 3821} 3822