1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23#include "curl_setup.h" 24 25#include <curl/curl.h> 26 27#include "urldata.h" 28#include "transfer.h" 29#include "url.h" 30#include "connect.h" 31#include "progress.h" 32#include "easyif.h" 33#include "share.h" 34#include "multiif.h" 35#include "sendf.h" 36#include "timeval.h" 37#include "http.h" 38#include "select.h" 39#include "warnless.h" 40#include "speedcheck.h" 41#include "conncache.h" 42#include "multihandle.h" 43#include "pipeline.h" 44#include "sigpipe.h" 45/* The last 3 #include files should be in this order */ 46#include "curl_printf.h" 47#include "curl_memory.h" 48#include "memdebug.h" 49 50/* 51 CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 52 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every 53 CURL handle takes 45-50 K memory, therefore this 3K are not significant. 54*/ 55#ifndef CURL_SOCKET_HASH_TABLE_SIZE 56#define CURL_SOCKET_HASH_TABLE_SIZE 911 57#endif 58 59#define CURL_CONNECTION_HASH_SIZE 97 60 61#define CURL_MULTI_HANDLE 0x000bab1e 62 63#define GOOD_MULTI_HANDLE(x) \ 64 ((x) && (x)->type == CURL_MULTI_HANDLE) 65 66static void singlesocket(struct Curl_multi *multi, 67 struct Curl_easy *data); 68static int update_timer(struct Curl_multi *multi); 69 70static CURLMcode add_next_timeout(struct timeval now, 71 struct Curl_multi *multi, 72 struct Curl_easy *d); 73static CURLMcode multi_timeout(struct Curl_multi *multi, 74 long *timeout_ms); 75 76#ifdef DEBUGBUILD 77static const char * const statename[]={ 78 "INIT", 79 "CONNECT_PEND", 80 "CONNECT", 81 "WAITRESOLVE", 82 "WAITCONNECT", 83 "WAITPROXYCONNECT", 84 "SENDPROTOCONNECT", 85 "PROTOCONNECT", 86 "WAITDO", 87 "DO", 88 "DOING", 89 "DO_MORE", 90 "DO_DONE", 91 "WAITPERFORM", 92 "PERFORM", 93 "TOOFAST", 94 "DONE", 95 "COMPLETED", 96 "MSGSENT", 97}; 98#endif 99 100static void multi_freetimeout(void *a, void *b); 101 102/* function pointer called once when switching TO a state */ 103typedef void (*init_multistate_func)(struct Curl_easy *data); 104 105/* always use this function to change state, to make debugging easier */ 106static void mstate(struct Curl_easy *data, CURLMstate state 107#ifdef DEBUGBUILD 108 , int lineno 109#endif 110) 111{ 112 CURLMstate oldstate = data->mstate; 113 static const init_multistate_func finit[CURLM_STATE_LAST] = { 114 NULL, 115 NULL, 116 Curl_init_CONNECT, /* CONNECT */ 117 /* the rest is NULL too */ 118 }; 119 120#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS) 121 (void) lineno; 122#endif 123 124 if(oldstate == state) 125 /* don't bother when the new state is the same as the old state */ 126 return; 127 128 data->mstate = state; 129 130#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) 131 if(data->mstate >= CURLM_STATE_CONNECT_PEND && 132 data->mstate < CURLM_STATE_COMPLETED) { 133 long connection_id = -5000; 134 135 if(data->easy_conn) 136 connection_id = data->easy_conn->connection_id; 137 138 infof(data, 139 "STATE: %s => %s handle %p; line %d (connection #%ld)\n", 140 statename[oldstate], statename[data->mstate], 141 (void *)data, lineno, connection_id); 142 } 143#endif 144 145 if(state == CURLM_STATE_COMPLETED) 146 /* changing to COMPLETED means there's one less easy handle 'alive' */ 147 data->multi->num_alive--; 148 149 /* if this state has an init-function, run it */ 150 if(finit[state]) 151 finit[state](data); 152} 153 154#ifndef DEBUGBUILD 155#define multistate(x,y) mstate(x,y) 156#else 157#define multistate(x,y) mstate(x,y, __LINE__) 158#endif 159 160/* 161 * We add one of these structs to the sockhash for a particular socket 162 */ 163 164struct Curl_sh_entry { 165 struct Curl_easy *easy; 166 int action; /* what action READ/WRITE this socket waits for */ 167 curl_socket_t socket; /* mainly to ease debugging */ 168 void *socketp; /* settable by users with curl_multi_assign() */ 169}; 170/* bits for 'action' having no bits means this socket is not expecting any 171 action */ 172#define SH_READ 1 173#define SH_WRITE 2 174 175/* look up a given socket in the socket hash, skip invalid sockets */ 176static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh, 177 curl_socket_t s) 178{ 179 if(s != CURL_SOCKET_BAD) 180 /* only look for proper sockets */ 181 return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t)); 182 return NULL; 183} 184 185/* make sure this socket is present in the hash for this handle */ 186static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, 187 curl_socket_t s, 188 struct Curl_easy *data) 189{ 190 struct Curl_sh_entry *there = sh_getentry(sh, s); 191 struct Curl_sh_entry *check; 192 193 if(there) 194 /* it is present, return fine */ 195 return there; 196 197 /* not present, add it */ 198 check = calloc(1, sizeof(struct Curl_sh_entry)); 199 if(!check) 200 return NULL; /* major failure */ 201 202 check->easy = data; 203 check->socket = s; 204 205 /* make/add new hash entry */ 206 if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { 207 free(check); 208 return NULL; /* major failure */ 209 } 210 211 return check; /* things are good in sockhash land */ 212} 213 214 215/* delete the given socket + handle from the hash */ 216static void sh_delentry(struct curl_hash *sh, curl_socket_t s) 217{ 218 /* We remove the hash entry. This will end up in a call to 219 sh_freeentry(). */ 220 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t)); 221} 222 223/* 224 * free a sockhash entry 225 */ 226static void sh_freeentry(void *freethis) 227{ 228 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis; 229 230 free(p); 231} 232 233static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) 234{ 235 (void) k1_len; (void) k2_len; 236 237 return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2)); 238} 239 240static size_t hash_fd(void *key, size_t key_length, size_t slots_num) 241{ 242 curl_socket_t fd = *((curl_socket_t *) key); 243 (void) key_length; 244 245 return (fd % slots_num); 246} 247 248/* 249 * sh_init() creates a new socket hash and returns the handle for it. 250 * 251 * Quote from README.multi_socket: 252 * 253 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup 254 * is somewhat of a bottle neck. Its current implementation may be a bit too 255 * limiting. It simply has a fixed-size array, and on each entry in the array 256 * it has a linked list with entries. So the hash only checks which list to 257 * scan through. The code I had used so for used a list with merely 7 slots 258 * (as that is what the DNS hash uses) but with 7000 connections that would 259 * make an average of 1000 nodes in each list to run through. I upped that to 260 * 97 slots (I believe a prime is suitable) and noticed a significant speed 261 * increase. I need to reconsider the hash implementation or use a rather 262 * large default value like this. At 9000 connections I was still below 10us 263 * per call." 264 * 265 */ 266static int sh_init(struct curl_hash *hash, int hashsize) 267{ 268 return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare, 269 sh_freeentry); 270} 271 272/* 273 * multi_addmsg() 274 * 275 * Called when a transfer is completed. Adds the given msg pointer to 276 * the list kept in the multi handle. 277 */ 278static CURLMcode multi_addmsg(struct Curl_multi *multi, 279 struct Curl_message *msg) 280{ 281 if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg)) 282 return CURLM_OUT_OF_MEMORY; 283 284 return CURLM_OK; 285} 286 287/* 288 * multi_freeamsg() 289 * 290 * Callback used by the llist system when a single list entry is destroyed. 291 */ 292static void multi_freeamsg(void *a, void *b) 293{ 294 (void)a; 295 (void)b; 296} 297 298struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ 299 int chashsize) /* connection hash */ 300{ 301 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); 302 303 if(!multi) 304 return NULL; 305 306 multi->type = CURL_MULTI_HANDLE; 307 308 if(Curl_mk_dnscache(&multi->hostcache)) 309 goto error; 310 311 if(sh_init(&multi->sockhash, hashsize)) 312 goto error; 313 314 if(Curl_conncache_init(&multi->conn_cache, chashsize)) 315 goto error; 316 317 multi->msglist = Curl_llist_alloc(multi_freeamsg); 318 if(!multi->msglist) 319 goto error; 320 321 multi->pending = Curl_llist_alloc(multi_freeamsg); 322 if(!multi->pending) 323 goto error; 324 325 /* allocate a new easy handle to use when closing cached connections */ 326 multi->closure_handle = curl_easy_init(); 327 if(!multi->closure_handle) 328 goto error; 329 330 multi->closure_handle->multi = multi; 331 multi->closure_handle->state.conn_cache = &multi->conn_cache; 332 333 multi->max_pipeline_length = 5; 334 335 /* -1 means it not set by user, use the default value */ 336 multi->maxconnects = -1; 337 return multi; 338 339 error: 340 341 Curl_hash_destroy(&multi->sockhash); 342 Curl_hash_destroy(&multi->hostcache); 343 Curl_conncache_destroy(&multi->conn_cache); 344 Curl_close(multi->closure_handle); 345 multi->closure_handle = NULL; 346 Curl_llist_destroy(multi->msglist, NULL); 347 Curl_llist_destroy(multi->pending, NULL); 348 349 free(multi); 350 return NULL; 351} 352 353struct Curl_multi *curl_multi_init(void) 354{ 355 return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE, 356 CURL_CONNECTION_HASH_SIZE); 357} 358 359CURLMcode curl_multi_add_handle(struct Curl_multi *multi, 360 struct Curl_easy *data) 361{ 362 struct curl_llist *timeoutlist; 363 364 /* First, make some basic checks that the CURLM handle is a good handle */ 365 if(!GOOD_MULTI_HANDLE(multi)) 366 return CURLM_BAD_HANDLE; 367 368 /* Verify that we got a somewhat good easy handle too */ 369 if(!GOOD_EASY_HANDLE(data)) 370 return CURLM_BAD_EASY_HANDLE; 371 372 /* Prevent users from adding same easy handle more than once and prevent 373 adding to more than one multi stack */ 374 if(data->multi) 375 return CURLM_ADDED_ALREADY; 376 377 /* Allocate and initialize timeout list for easy handle */ 378 timeoutlist = Curl_llist_alloc(multi_freetimeout); 379 if(!timeoutlist) 380 return CURLM_OUT_OF_MEMORY; 381 382 /* 383 * No failure allowed in this function beyond this point. And no 384 * modification of easy nor multi handle allowed before this except for 385 * potential multi's connection cache growing which won't be undone in this 386 * function no matter what. 387 */ 388 389 /* Make easy handle use timeout list initialized above */ 390 data->state.timeoutlist = timeoutlist; 391 timeoutlist = NULL; 392 393 /* set the easy handle */ 394 multistate(data, CURLM_STATE_INIT); 395 396 if((data->set.global_dns_cache) && 397 (data->dns.hostcachetype != HCACHE_GLOBAL)) { 398 /* global dns cache was requested but still isn't */ 399 struct curl_hash *global = Curl_global_host_cache_init(); 400 if(global) { 401 /* only do this if the global cache init works */ 402 data->dns.hostcache = global; 403 data->dns.hostcachetype = HCACHE_GLOBAL; 404 } 405 } 406 /* for multi interface connections, we share DNS cache automatically if the 407 easy handle's one is currently not set. */ 408 else if(!data->dns.hostcache || 409 (data->dns.hostcachetype == HCACHE_NONE)) { 410 data->dns.hostcache = &multi->hostcache; 411 data->dns.hostcachetype = HCACHE_MULTI; 412 } 413 414 /* Point to the multi's connection cache */ 415 data->state.conn_cache = &multi->conn_cache; 416 417 /* This adds the new entry at the 'end' of the doubly-linked circular 418 list of Curl_easy structs to try and maintain a FIFO queue so 419 the pipelined requests are in order. */ 420 421 /* We add this new entry last in the list. */ 422 423 data->next = NULL; /* end of the line */ 424 if(multi->easyp) { 425 struct Curl_easy *last = multi->easylp; 426 last->next = data; 427 data->prev = last; 428 multi->easylp = data; /* the new last node */ 429 } 430 else { 431 /* first node, make prev NULL! */ 432 data->prev = NULL; 433 multi->easylp = multi->easyp = data; /* both first and last */ 434 } 435 436 /* make the Curl_easy refer back to this multi handle */ 437 data->multi = multi; 438 439 /* Set the timeout for this handle to expire really soon so that it will 440 be taken care of even when this handle is added in the midst of operation 441 when only the curl_multi_socket() API is used. During that flow, only 442 sockets that time-out or have actions will be dealt with. Since this 443 handle has no action yet, we make sure it times out to get things to 444 happen. */ 445 Curl_expire(data, 1); 446 447 /* increase the node-counter */ 448 multi->num_easy++; 449 450 /* increase the alive-counter */ 451 multi->num_alive++; 452 453 /* A somewhat crude work-around for a little glitch in update_timer() that 454 happens if the lastcall time is set to the same time when the handle is 455 removed as when the next handle is added, as then the check in 456 update_timer() that prevents calling the application multiple times with 457 the same timer infor will not trigger and then the new handle's timeout 458 will not be notified to the app. 459 460 The work-around is thus simply to clear the 'lastcall' variable to force 461 update_timer() to always trigger a callback to the app when a new easy 462 handle is added */ 463 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); 464 465 update_timer(multi); 466 return CURLM_OK; 467} 468 469#if 0 470/* Debug-function, used like this: 471 * 472 * Curl_hash_print(multi->sockhash, debug_print_sock_hash); 473 * 474 * Enable the hash print function first by editing hash.c 475 */ 476static void debug_print_sock_hash(void *p) 477{ 478 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p; 479 480 fprintf(stderr, " [easy %p/magic %x/socket %d]", 481 (void *)sh->data, sh->data->magic, (int)sh->socket); 482} 483#endif 484 485/* Mark the connection as 'idle', or close it if the cache is full. 486 Returns TRUE if the connection is kept, or FALSE if it was closed. */ 487static bool 488ConnectionDone(struct Curl_easy *data, struct connectdata *conn) 489{ 490 /* data->multi->maxconnects can be negative, deal with it. */ 491 size_t maxconnects = 492 (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: 493 data->multi->maxconnects; 494 struct connectdata *conn_candidate = NULL; 495 496 /* Mark the current connection as 'unused' */ 497 conn->inuse = FALSE; 498 499 if(maxconnects > 0 && 500 data->state.conn_cache->num_connections > maxconnects) { 501 infof(data, "Connection cache is full, closing the oldest one.\n"); 502 503 conn_candidate = Curl_oldest_idle_connection(data); 504 505 if(conn_candidate) { 506 /* Set the connection's owner correctly */ 507 conn_candidate->data = data; 508 509 /* the winner gets the honour of being disconnected */ 510 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); 511 } 512 } 513 514 return (conn_candidate == conn) ? FALSE : TRUE; 515} 516 517static CURLcode multi_done(struct connectdata **connp, 518 CURLcode status, /* an error if this is called 519 after an error was detected */ 520 bool premature) 521{ 522 CURLcode result; 523 struct connectdata *conn; 524 struct Curl_easy *data; 525 526 DEBUGASSERT(*connp); 527 528 conn = *connp; 529 data = conn->data; 530 531 DEBUGF(infof(data, "multi_done\n")); 532 533 if(data->state.done) 534 /* Stop if multi_done() has already been called */ 535 return CURLE_OK; 536 537 Curl_getoff_all_pipelines(data, conn); 538 539 /* Cleanup possible redirect junk */ 540 free(data->req.newurl); 541 data->req.newurl = NULL; 542 free(data->req.location); 543 data->req.location = NULL; 544 545 switch(status) { 546 case CURLE_ABORTED_BY_CALLBACK: 547 case CURLE_READ_ERROR: 548 case CURLE_WRITE_ERROR: 549 /* When we're aborted due to a callback return code it basically have to 550 be counted as premature as there is trouble ahead if we don't. We have 551 many callbacks and protocols work differently, we could potentially do 552 this more fine-grained in the future. */ 553 premature = TRUE; 554 default: 555 break; 556 } 557 558 /* this calls the protocol-specific function pointer previously set */ 559 if(conn->handler->done) 560 result = conn->handler->done(conn, status, premature); 561 else 562 result = status; 563 564 if(CURLE_ABORTED_BY_CALLBACK != result) { 565 /* avoid this if we already aborted by callback to avoid this calling 566 another callback */ 567 CURLcode rc = Curl_pgrsDone(conn); 568 if(!result && rc) 569 result = CURLE_ABORTED_BY_CALLBACK; 570 } 571 572 if((!premature && 573 conn->send_pipe->size + conn->recv_pipe->size != 0 && 574 !data->set.reuse_forbid && 575 !conn->bits.close)) { 576 /* Stop if pipeline is not empty and we do not have to close 577 connection. */ 578 DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n")); 579 return CURLE_OK; 580 } 581 582 data->state.done = TRUE; /* called just now! */ 583 Curl_resolver_cancel(conn); 584 585 if(conn->dns_entry) { 586 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ 587 conn->dns_entry = NULL; 588 } 589 590 /* if the transfer was completed in a paused state there can be buffered 591 data left to write and then kill */ 592 free(data->state.tempwrite); 593 data->state.tempwrite = NULL; 594 595 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has 596 forced us to close this connection. This is ignored for requests taking 597 place in a NTLM authentication handshake 598 599 if conn->bits.close is TRUE, it means that the connection should be 600 closed in spite of all our efforts to be nice, due to protocol 601 restrictions in our or the server's end 602 603 if premature is TRUE, it means this connection was said to be DONE before 604 the entire request operation is complete and thus we can't know in what 605 state it is for re-using, so we're forced to close it. In a perfect world 606 we can add code that keep track of if we really must close it here or not, 607 but currently we have no such detail knowledge. 608 */ 609 610 if((data->set.reuse_forbid 611#if defined(USE_NTLM) 612 && !(conn->ntlm.state == NTLMSTATE_TYPE2 || 613 conn->proxyntlm.state == NTLMSTATE_TYPE2) 614#endif 615 ) || conn->bits.close || premature) { 616 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ 617 618 /* If we had an error already, make sure we return that one. But 619 if we got a new error, return that. */ 620 if(!result && res2) 621 result = res2; 622 } 623 else { 624 /* the connection is no longer in use */ 625 if(ConnectionDone(data, conn)) { 626 /* remember the most recently used connection */ 627 data->state.lastconnect = conn; 628 629 infof(data, "Connection #%ld to host %s left intact\n", 630 conn->connection_id, 631 conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); 632 } 633 else 634 data->state.lastconnect = NULL; 635 } 636 637 *connp = NULL; /* to make the caller of this function better detect that 638 this was either closed or handed over to the connection 639 cache here, and therefore cannot be used from this point on 640 */ 641 Curl_free_request_state(data); 642 643 return result; 644} 645 646CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, 647 struct Curl_easy *data) 648{ 649 struct Curl_easy *easy = data; 650 bool premature; 651 bool easy_owns_conn; 652 struct curl_llist_element *e; 653 654 /* First, make some basic checks that the CURLM handle is a good handle */ 655 if(!GOOD_MULTI_HANDLE(multi)) 656 return CURLM_BAD_HANDLE; 657 658 /* Verify that we got a somewhat good easy handle too */ 659 if(!GOOD_EASY_HANDLE(data)) 660 return CURLM_BAD_EASY_HANDLE; 661 662 /* Prevent users from trying to remove same easy handle more than once */ 663 if(!data->multi) 664 return CURLM_OK; /* it is already removed so let's say it is fine! */ 665 666 premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE; 667 easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ? 668 TRUE : FALSE; 669 670 /* If the 'state' is not INIT or COMPLETED, we might need to do something 671 nice to put the easy_handle in a good known state when this returns. */ 672 if(premature) { 673 /* this handle is "alive" so we need to count down the total number of 674 alive connections when this is removed */ 675 multi->num_alive--; 676 677 /* When this handle gets removed, other handles may be able to get the 678 connection */ 679 Curl_multi_process_pending_handles(multi); 680 } 681 682 if(data->easy_conn && 683 data->mstate > CURLM_STATE_DO && 684 data->mstate < CURLM_STATE_COMPLETED) { 685 /* If the handle is in a pipeline and has started sending off its 686 request but not received its response yet, we need to close 687 connection. */ 688 connclose(data->easy_conn, "Removed with partial response"); 689 /* Set connection owner so that the DONE function closes it. We can 690 safely do this here since connection is killed. */ 691 data->easy_conn->data = easy; 692 easy_owns_conn = TRUE; 693 } 694 695 /* The timer must be shut down before data->multi is set to NULL, 696 else the timenode will remain in the splay tree after 697 curl_easy_cleanup is called. */ 698 Curl_expire(data, 0); 699 700 if(data->dns.hostcachetype == HCACHE_MULTI) { 701 /* stop using the multi handle's DNS cache */ 702 data->dns.hostcache = NULL; 703 data->dns.hostcachetype = HCACHE_NONE; 704 } 705 706 if(data->easy_conn) { 707 708 /* we must call multi_done() here (if we still own the connection) so that 709 we don't leave a half-baked one around */ 710 if(easy_owns_conn) { 711 712 /* multi_done() clears the conn->data field to lose the association 713 between the easy handle and the connection 714 715 Note that this ignores the return code simply because there's 716 nothing really useful to do with it anyway! */ 717 (void)multi_done(&data->easy_conn, data->result, premature); 718 } 719 else 720 /* Clear connection pipelines, if multi_done above was not called */ 721 Curl_getoff_all_pipelines(data, data->easy_conn); 722 } 723 724 Curl_wildcard_dtor(&data->wildcard); 725 726 /* destroy the timeout list that is held in the easy handle, do this *after* 727 multi_done() as that may actually call Curl_expire that uses this */ 728 if(data->state.timeoutlist) { 729 Curl_llist_destroy(data->state.timeoutlist, NULL); 730 data->state.timeoutlist = NULL; 731 } 732 733 /* as this was using a shared connection cache we clear the pointer to that 734 since we're not part of that multi handle anymore */ 735 data->state.conn_cache = NULL; 736 737 /* change state without using multistate(), only to make singlesocket() do 738 what we want */ 739 data->mstate = CURLM_STATE_COMPLETED; 740 singlesocket(multi, easy); /* to let the application know what sockets that 741 vanish with this handle */ 742 743 /* Remove the association between the connection and the handle */ 744 if(data->easy_conn) { 745 data->easy_conn->data = NULL; 746 data->easy_conn = NULL; 747 } 748 749 data->multi = NULL; /* clear the association to this multi handle */ 750 751 /* make sure there's no pending message in the queue sent from this easy 752 handle */ 753 754 for(e = multi->msglist->head; e; e = e->next) { 755 struct Curl_message *msg = e->ptr; 756 757 if(msg->extmsg.easy_handle == easy) { 758 Curl_llist_remove(multi->msglist, e, NULL); 759 /* there can only be one from this specific handle */ 760 break; 761 } 762 } 763 764 /* make the previous node point to our next */ 765 if(data->prev) 766 data->prev->next = data->next; 767 else 768 multi->easyp = data->next; /* point to first node */ 769 770 /* make our next point to our previous node */ 771 if(data->next) 772 data->next->prev = data->prev; 773 else 774 multi->easylp = data->prev; /* point to last node */ 775 776 /* NOTE NOTE NOTE 777 We do not touch the easy handle here! */ 778 multi->num_easy--; /* one less to care about now */ 779 780 update_timer(multi); 781 return CURLM_OK; 782} 783 784/* Return TRUE if the application asked for a certain set of pipelining */ 785bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits) 786{ 787 return (multi && (multi->pipelining & bits)) ? TRUE : FALSE; 788} 789 790void Curl_multi_handlePipeBreak(struct Curl_easy *data) 791{ 792 data->easy_conn = NULL; 793} 794 795static int waitconnect_getsock(struct connectdata *conn, 796 curl_socket_t *sock, 797 int numsocks) 798{ 799 int i; 800 int s=0; 801 int rc=0; 802 803 if(!numsocks) 804 return GETSOCK_BLANK; 805 806 for(i=0; i<2; i++) { 807 if(conn->tempsock[i] != CURL_SOCKET_BAD) { 808 sock[s] = conn->tempsock[i]; 809 rc |= GETSOCK_WRITESOCK(s++); 810 } 811 } 812 813 return rc; 814} 815 816static int waitproxyconnect_getsock(struct connectdata *conn, 817 curl_socket_t *sock, 818 int numsocks) 819{ 820 if(!numsocks) 821 return GETSOCK_BLANK; 822 823 sock[0] = conn->sock[FIRSTSOCKET]; 824 825 /* when we've sent a CONNECT to a proxy, we should rather wait for the 826 socket to become readable to be able to get the response headers */ 827 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) 828 return GETSOCK_READSOCK(0); 829 830 return GETSOCK_WRITESOCK(0); 831} 832 833static int domore_getsock(struct connectdata *conn, 834 curl_socket_t *socks, 835 int numsocks) 836{ 837 if(conn && conn->handler->domore_getsock) 838 return conn->handler->domore_getsock(conn, socks, numsocks); 839 return GETSOCK_BLANK; 840} 841 842/* returns bitmapped flags for this handle and its sockets */ 843static int multi_getsock(struct Curl_easy *data, 844 curl_socket_t *socks, /* points to numsocks number 845 of sockets */ 846 int numsocks) 847{ 848 /* If the pipe broke, or if there's no connection left for this easy handle, 849 then we MUST bail out now with no bitmask set. The no connection case can 850 happen when this is called from curl_multi_remove_handle() => 851 singlesocket() => multi_getsock(). 852 */ 853 if(data->state.pipe_broke || !data->easy_conn) 854 return 0; 855 856 if(data->mstate > CURLM_STATE_CONNECT && 857 data->mstate < CURLM_STATE_COMPLETED) { 858 /* Set up ownership correctly */ 859 data->easy_conn->data = data; 860 } 861 862 switch(data->mstate) { 863 default: 864#if 0 /* switch back on these cases to get the compiler to check for all enums 865 to be present */ 866 case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */ 867 case CURLM_STATE_COMPLETED: 868 case CURLM_STATE_MSGSENT: 869 case CURLM_STATE_INIT: 870 case CURLM_STATE_CONNECT: 871 case CURLM_STATE_WAITDO: 872 case CURLM_STATE_DONE: 873 case CURLM_STATE_LAST: 874 /* this will get called with CURLM_STATE_COMPLETED when a handle is 875 removed */ 876#endif 877 return 0; 878 879 case CURLM_STATE_WAITRESOLVE: 880 return Curl_resolver_getsock(data->easy_conn, socks, numsocks); 881 882 case CURLM_STATE_PROTOCONNECT: 883 case CURLM_STATE_SENDPROTOCONNECT: 884 return Curl_protocol_getsock(data->easy_conn, socks, numsocks); 885 886 case CURLM_STATE_DO: 887 case CURLM_STATE_DOING: 888 return Curl_doing_getsock(data->easy_conn, socks, numsocks); 889 890 case CURLM_STATE_WAITPROXYCONNECT: 891 return waitproxyconnect_getsock(data->easy_conn, socks, numsocks); 892 893 case CURLM_STATE_WAITCONNECT: 894 return waitconnect_getsock(data->easy_conn, socks, numsocks); 895 896 case CURLM_STATE_DO_MORE: 897 return domore_getsock(data->easy_conn, socks, numsocks); 898 899 case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch 900 to waiting for the same as the *PERFORM 901 states */ 902 case CURLM_STATE_PERFORM: 903 case CURLM_STATE_WAITPERFORM: 904 return Curl_single_getsock(data->easy_conn, socks, numsocks); 905 } 906 907} 908 909CURLMcode curl_multi_fdset(struct Curl_multi *multi, 910 fd_set *read_fd_set, fd_set *write_fd_set, 911 fd_set *exc_fd_set, int *max_fd) 912{ 913 /* Scan through all the easy handles to get the file descriptors set. 914 Some easy handles may not have connected to the remote host yet, 915 and then we must make sure that is done. */ 916 struct Curl_easy *data; 917 int this_max_fd=-1; 918 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; 919 int bitmap; 920 int i; 921 (void)exc_fd_set; /* not used */ 922 923 if(!GOOD_MULTI_HANDLE(multi)) 924 return CURLM_BAD_HANDLE; 925 926 data=multi->easyp; 927 while(data) { 928 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); 929 930 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { 931 curl_socket_t s = CURL_SOCKET_BAD; 932 933 if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) { 934 FD_SET(sockbunch[i], read_fd_set); 935 s = sockbunch[i]; 936 } 937 if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) { 938 FD_SET(sockbunch[i], write_fd_set); 939 s = sockbunch[i]; 940 } 941 if(s == CURL_SOCKET_BAD) 942 /* this socket is unused, break out of loop */ 943 break; 944 else { 945 if((int)s > this_max_fd) 946 this_max_fd = (int)s; 947 } 948 } 949 950 data = data->next; /* check next handle */ 951 } 952 953 *max_fd = this_max_fd; 954 955 return CURLM_OK; 956} 957 958CURLMcode curl_multi_wait(struct Curl_multi *multi, 959 struct curl_waitfd extra_fds[], 960 unsigned int extra_nfds, 961 int timeout_ms, 962 int *ret) 963{ 964 struct Curl_easy *data; 965 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; 966 int bitmap; 967 unsigned int i; 968 unsigned int nfds = 0; 969 unsigned int curlfds; 970 struct pollfd *ufds = NULL; 971 long timeout_internal; 972 int retcode = 0; 973 974 if(!GOOD_MULTI_HANDLE(multi)) 975 return CURLM_BAD_HANDLE; 976 977 /* If the internally desired timeout is actually shorter than requested from 978 the outside, then use the shorter time! But only if the internal timer 979 is actually larger than -1! */ 980 (void)multi_timeout(multi, &timeout_internal); 981 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) 982 timeout_ms = (int)timeout_internal; 983 984 /* Count up how many fds we have from the multi handle */ 985 data=multi->easyp; 986 while(data) { 987 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); 988 989 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { 990 curl_socket_t s = CURL_SOCKET_BAD; 991 992 if(bitmap & GETSOCK_READSOCK(i)) { 993 ++nfds; 994 s = sockbunch[i]; 995 } 996 if(bitmap & GETSOCK_WRITESOCK(i)) { 997 ++nfds; 998 s = sockbunch[i]; 999 } 1000 if(s == CURL_SOCKET_BAD) { 1001 break; 1002 } 1003 } 1004 1005 data = data->next; /* check next handle */ 1006 } 1007 1008 curlfds = nfds; /* number of internal file descriptors */ 1009 nfds += extra_nfds; /* add the externally provided ones */ 1010 1011 if(nfds || extra_nfds) { 1012 ufds = malloc(nfds * sizeof(struct pollfd)); 1013 if(!ufds) 1014 return CURLM_OUT_OF_MEMORY; 1015 } 1016 nfds = 0; 1017 1018 /* only do the second loop if we found descriptors in the first stage run 1019 above */ 1020 1021 if(curlfds) { 1022 /* Add the curl handles to our pollfds first */ 1023 data=multi->easyp; 1024 while(data) { 1025 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); 1026 1027 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { 1028 curl_socket_t s = CURL_SOCKET_BAD; 1029 1030 if(bitmap & GETSOCK_READSOCK(i)) { 1031 ufds[nfds].fd = sockbunch[i]; 1032 ufds[nfds].events = POLLIN; 1033 ++nfds; 1034 s = sockbunch[i]; 1035 } 1036 if(bitmap & GETSOCK_WRITESOCK(i)) { 1037 ufds[nfds].fd = sockbunch[i]; 1038 ufds[nfds].events = POLLOUT; 1039 ++nfds; 1040 s = sockbunch[i]; 1041 } 1042 if(s == CURL_SOCKET_BAD) { 1043 break; 1044 } 1045 } 1046 1047 data = data->next; /* check next handle */ 1048 } 1049 } 1050 1051 /* Add external file descriptions from poll-like struct curl_waitfd */ 1052 for(i = 0; i < extra_nfds; i++) { 1053 ufds[nfds].fd = extra_fds[i].fd; 1054 ufds[nfds].events = 0; 1055 if(extra_fds[i].events & CURL_WAIT_POLLIN) 1056 ufds[nfds].events |= POLLIN; 1057 if(extra_fds[i].events & CURL_WAIT_POLLPRI) 1058 ufds[nfds].events |= POLLPRI; 1059 if(extra_fds[i].events & CURL_WAIT_POLLOUT) 1060 ufds[nfds].events |= POLLOUT; 1061 ++nfds; 1062 } 1063 1064 if(nfds) { 1065 int pollrc; 1066 /* wait... */ 1067 pollrc = Curl_poll(ufds, nfds, timeout_ms); 1068 DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n", 1069 nfds, timeout_ms, pollrc)); 1070 1071 if(pollrc > 0) { 1072 retcode = pollrc; 1073 /* copy revents results from the poll to the curl_multi_wait poll 1074 struct, the bit values of the actual underlying poll() implementation 1075 may not be the same as the ones in the public libcurl API! */ 1076 for(i = 0; i < extra_nfds; i++) { 1077 unsigned short mask = 0; 1078 unsigned r = ufds[curlfds + i].revents; 1079 1080 if(r & POLLIN) 1081 mask |= CURL_WAIT_POLLIN; 1082 if(r & POLLOUT) 1083 mask |= CURL_WAIT_POLLOUT; 1084 if(r & POLLPRI) 1085 mask |= CURL_WAIT_POLLPRI; 1086 1087 extra_fds[i].revents = mask; 1088 } 1089 } 1090 } 1091 1092 free(ufds); 1093 if(ret) 1094 *ret = retcode; 1095 return CURLM_OK; 1096} 1097 1098/* 1099 * Curl_multi_connchanged() is called to tell that there is a connection in 1100 * this multi handle that has changed state (pipelining become possible, the 1101 * number of allowed streams changed or similar), and a subsequent use of this 1102 * multi handle should move CONNECT_PEND handles back to CONNECT to have them 1103 * retry. 1104 */ 1105void Curl_multi_connchanged(struct Curl_multi *multi) 1106{ 1107 multi->recheckstate = TRUE; 1108} 1109 1110/* 1111 * multi_ischanged() is called 1112 * 1113 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND 1114 * => CONNECT action. 1115 * 1116 * Set 'clear' to TRUE to have it also clear the state variable. 1117 */ 1118static bool multi_ischanged(struct Curl_multi *multi, bool clear) 1119{ 1120 bool retval = multi->recheckstate; 1121 if(clear) 1122 multi->recheckstate = FALSE; 1123 return retval; 1124} 1125 1126CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, 1127 struct Curl_easy *data, 1128 struct connectdata *conn) 1129{ 1130 CURLMcode rc; 1131 1132 rc = curl_multi_add_handle(multi, data); 1133 if(!rc) { 1134 struct SingleRequest *k = &data->req; 1135 1136 /* pass in NULL for 'conn' here since we don't want to init the 1137 connection, only this transfer */ 1138 Curl_init_do(data, NULL); 1139 1140 /* take this handle to the perform state right away */ 1141 multistate(data, CURLM_STATE_PERFORM); 1142 data->easy_conn = conn; 1143 k->keepon |= KEEP_RECV; /* setup to receive! */ 1144 } 1145 return rc; 1146} 1147 1148static CURLcode multi_reconnect_request(struct connectdata **connp) 1149{ 1150 CURLcode result = CURLE_OK; 1151 struct connectdata *conn = *connp; 1152 struct Curl_easy *data = conn->data; 1153 1154 /* This was a re-use of a connection and we got a write error in the 1155 * DO-phase. Then we DISCONNECT this connection and have another attempt to 1156 * CONNECT and then DO again! The retry cannot possibly find another 1157 * connection to re-use, since we only keep one possible connection for 1158 * each. */ 1159 1160 infof(data, "Re-used connection seems dead, get a new one\n"); 1161 1162 connclose(conn, "Reconnect dead connection"); /* enforce close */ 1163 result = multi_done(&conn, result, FALSE); /* we are so done with this */ 1164 1165 /* conn may no longer be a good pointer, clear it to avoid mistakes by 1166 parent functions */ 1167 *connp = NULL; 1168 1169 /* 1170 * We need to check for CURLE_SEND_ERROR here as well. This could happen 1171 * when the request failed on a FTP connection and thus multi_done() itself 1172 * tried to use the connection (again). 1173 */ 1174 if(!result || (CURLE_SEND_ERROR == result)) { 1175 bool async; 1176 bool protocol_done = TRUE; 1177 1178 /* Now, redo the connect and get a new connection */ 1179 result = Curl_connect(data, connp, &async, &protocol_done); 1180 if(!result) { 1181 /* We have connected or sent away a name resolve query fine */ 1182 1183 conn = *connp; /* setup conn to again point to something nice */ 1184 if(async) { 1185 /* Now, if async is TRUE here, we need to wait for the name 1186 to resolve */ 1187 result = Curl_resolver_wait_resolv(conn, NULL); 1188 if(result) 1189 return result; 1190 1191 /* Resolved, continue with the connection */ 1192 result = Curl_async_resolved(conn, &protocol_done); 1193 if(result) 1194 return result; 1195 } 1196 } 1197 } 1198 1199 return result; 1200} 1201 1202/* 1203 * do_complete is called when the DO actions are complete. 1204 * 1205 * We init chunking and trailer bits to their default values here immediately 1206 * before receiving any header data for the current request in the pipeline. 1207 */ 1208static void do_complete(struct connectdata *conn) 1209{ 1210 conn->data->req.chunk=FALSE; 1211 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? 1212 conn->sockfd:conn->writesockfd)+1; 1213 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER); 1214} 1215 1216static CURLcode multi_do(struct connectdata **connp, bool *done) 1217{ 1218 CURLcode result=CURLE_OK; 1219 struct connectdata *conn = *connp; 1220 struct Curl_easy *data = conn->data; 1221 1222 if(conn->handler->do_it) { 1223 /* generic protocol-specific function pointer set in curl_connect() */ 1224 result = conn->handler->do_it(conn, done); 1225 1226 /* This was formerly done in transfer.c, but we better do it here */ 1227 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { 1228 /* 1229 * If the connection is using an easy handle, call reconnect 1230 * to re-establish the connection. Otherwise, let the multi logic 1231 * figure out how to re-establish the connection. 1232 */ 1233 if(!data->multi) { 1234 result = multi_reconnect_request(connp); 1235 1236 if(!result) { 1237 /* ... finally back to actually retry the DO phase */ 1238 conn = *connp; /* re-assign conn since multi_reconnect_request 1239 creates a new connection */ 1240 result = conn->handler->do_it(conn, done); 1241 } 1242 } 1243 else 1244 return result; 1245 } 1246 1247 if(!result && *done) 1248 /* do_complete must be called after the protocol-specific DO function */ 1249 do_complete(conn); 1250 } 1251 return result; 1252} 1253 1254/* 1255 * multi_do_more() is called during the DO_MORE multi state. It is basically a 1256 * second stage DO state which (wrongly) was introduced to support FTP's 1257 * second connection. 1258 * 1259 * TODO: A future libcurl should be able to work away this state. 1260 * 1261 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to 1262 * DOING state there's more work to do! 1263 */ 1264 1265static CURLcode multi_do_more(struct connectdata *conn, int *complete) 1266{ 1267 CURLcode result=CURLE_OK; 1268 1269 *complete = 0; 1270 1271 if(conn->handler->do_more) 1272 result = conn->handler->do_more(conn, complete); 1273 1274 if(!result && (*complete == 1)) 1275 /* do_complete must be called after the protocol-specific DO function */ 1276 do_complete(conn); 1277 1278 return result; 1279} 1280 1281static CURLMcode multi_runsingle(struct Curl_multi *multi, 1282 struct timeval now, 1283 struct Curl_easy *data) 1284{ 1285 struct Curl_message *msg = NULL; 1286 bool connected; 1287 bool async; 1288 bool protocol_connect = FALSE; 1289 bool dophase_done = FALSE; 1290 bool done = FALSE; 1291 CURLMcode rc; 1292 CURLcode result = CURLE_OK; 1293 struct SingleRequest *k; 1294 long timeout_ms; 1295 int control; 1296 1297 if(!GOOD_EASY_HANDLE(data)) 1298 return CURLM_BAD_EASY_HANDLE; 1299 1300 do { 1301 bool disconnect_conn = FALSE; 1302 rc = CURLM_OK; 1303 1304 /* Handle the case when the pipe breaks, i.e., the connection 1305 we're using gets cleaned up and we're left with nothing. */ 1306 if(data->state.pipe_broke) { 1307 infof(data, "Pipe broke: handle %p, url = %s\n", 1308 (void *)data, data->state.path); 1309 1310 if(data->mstate < CURLM_STATE_COMPLETED) { 1311 /* Head back to the CONNECT state */ 1312 multistate(data, CURLM_STATE_CONNECT); 1313 rc = CURLM_CALL_MULTI_PERFORM; 1314 result = CURLE_OK; 1315 } 1316 1317 data->state.pipe_broke = FALSE; 1318 data->easy_conn = NULL; 1319 continue; 1320 } 1321 1322 if(!data->easy_conn && 1323 data->mstate > CURLM_STATE_CONNECT && 1324 data->mstate < CURLM_STATE_DONE) { 1325 /* In all these states, the code will blindly access 'data->easy_conn' 1326 so this is precaution that it isn't NULL. And it silences static 1327 analyzers. */ 1328 failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate); 1329 return CURLM_INTERNAL_ERROR; 1330 } 1331 1332 if(multi_ischanged(multi, TRUE)) { 1333 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n")); 1334 Curl_multi_process_pending_handles(multi); 1335 } 1336 1337 if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT && 1338 data->mstate < CURLM_STATE_COMPLETED) 1339 /* Make sure we set the connection's current owner */ 1340 data->easy_conn->data = data; 1341 1342 if(data->easy_conn && 1343 (data->mstate >= CURLM_STATE_CONNECT) && 1344 (data->mstate < CURLM_STATE_COMPLETED)) { 1345 /* we need to wait for the connect state as only then is the start time 1346 stored, but we must not check already completed handles */ 1347 1348 timeout_ms = Curl_timeleft(data, &now, 1349 (data->mstate <= CURLM_STATE_WAITDO)? 1350 TRUE:FALSE); 1351 1352 if(timeout_ms < 0) { 1353 /* Handle timed out */ 1354 if(data->mstate == CURLM_STATE_WAITRESOLVE) 1355 failf(data, "Resolving timed out after %ld milliseconds", 1356 Curl_tvdiff(now, data->progress.t_startsingle)); 1357 else if(data->mstate == CURLM_STATE_WAITCONNECT) 1358 failf(data, "Connection timed out after %ld milliseconds", 1359 Curl_tvdiff(now, data->progress.t_startsingle)); 1360 else { 1361 k = &data->req; 1362 if(k->size != -1) { 1363 failf(data, "Operation timed out after %ld milliseconds with %" 1364 CURL_FORMAT_CURL_OFF_T " out of %" 1365 CURL_FORMAT_CURL_OFF_T " bytes received", 1366 Curl_tvdiff(now, data->progress.t_startsingle), 1367 k->bytecount, k->size); 1368 } 1369 else { 1370 failf(data, "Operation timed out after %ld milliseconds with %" 1371 CURL_FORMAT_CURL_OFF_T " bytes received", 1372 Curl_tvdiff(now, data->progress.t_startsingle), 1373 k->bytecount); 1374 } 1375 } 1376 1377 /* Force connection closed if the connection has indeed been used */ 1378 if(data->mstate > CURLM_STATE_DO) { 1379 connclose(data->easy_conn, "Disconnected with pending data"); 1380 disconnect_conn = TRUE; 1381 } 1382 result = CURLE_OPERATION_TIMEDOUT; 1383 (void)multi_done(&data->easy_conn, result, TRUE); 1384 /* Skip the statemachine and go directly to error handling section. */ 1385 goto statemachine_end; 1386 } 1387 } 1388 1389 switch(data->mstate) { 1390 case CURLM_STATE_INIT: 1391 /* init this transfer. */ 1392 result=Curl_pretransfer(data); 1393 1394 if(!result) { 1395 /* after init, go CONNECT */ 1396 multistate(data, CURLM_STATE_CONNECT); 1397 Curl_pgrsTime(data, TIMER_STARTOP); 1398 rc = CURLM_CALL_MULTI_PERFORM; 1399 } 1400 break; 1401 1402 case CURLM_STATE_CONNECT_PEND: 1403 /* We will stay here until there is a connection available. Then 1404 we try again in the CURLM_STATE_CONNECT state. */ 1405 break; 1406 1407 case CURLM_STATE_CONNECT: 1408 /* Connect. We want to get a connection identifier filled in. */ 1409 Curl_pgrsTime(data, TIMER_STARTSINGLE); 1410 result = Curl_connect(data, &data->easy_conn, 1411 &async, &protocol_connect); 1412 if(CURLE_NO_CONNECTION_AVAILABLE == result) { 1413 /* There was no connection available. We will go to the pending 1414 state and wait for an available connection. */ 1415 multistate(data, CURLM_STATE_CONNECT_PEND); 1416 1417 /* add this handle to the list of connect-pending handles */ 1418 if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data)) 1419 result = CURLE_OUT_OF_MEMORY; 1420 else 1421 result = CURLE_OK; 1422 break; 1423 } 1424 1425 if(!result) { 1426 /* Add this handle to the send or pend pipeline */ 1427 result = Curl_add_handle_to_pipeline(data, data->easy_conn); 1428 if(result) 1429 disconnect_conn = TRUE; 1430 else { 1431 if(async) 1432 /* We're now waiting for an asynchronous name lookup */ 1433 multistate(data, CURLM_STATE_WAITRESOLVE); 1434 else { 1435 /* after the connect has been sent off, go WAITCONNECT unless the 1436 protocol connect is already done and we can go directly to 1437 WAITDO or DO! */ 1438 rc = CURLM_CALL_MULTI_PERFORM; 1439 1440 if(protocol_connect) 1441 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? 1442 CURLM_STATE_WAITDO:CURLM_STATE_DO); 1443 else { 1444#ifndef CURL_DISABLE_HTTP 1445 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) 1446 multistate(data, CURLM_STATE_WAITPROXYCONNECT); 1447 else 1448#endif 1449 multistate(data, CURLM_STATE_WAITCONNECT); 1450 } 1451 } 1452 } 1453 } 1454 break; 1455 1456 case CURLM_STATE_WAITRESOLVE: 1457 /* awaiting an asynch name resolve to complete */ 1458 { 1459 struct Curl_dns_entry *dns = NULL; 1460 struct connectdata *conn = data->easy_conn; 1461 const char *hostname; 1462 1463 if(conn->bits.proxy) 1464 hostname = conn->proxy.name; 1465 else if(conn->bits.conn_to_host) 1466 hostname = conn->conn_to_host.name; 1467 else 1468 hostname = conn->host.name; 1469 1470 /* check if we have the name resolved by now */ 1471 dns = Curl_fetch_addr(conn, hostname, (int)conn->port); 1472 1473 if(dns) { 1474#ifdef CURLRES_ASYNCH 1475 conn->async.dns = dns; 1476 conn->async.done = TRUE; 1477#endif 1478 result = CURLE_OK; 1479 infof(data, "Hostname '%s' was found in DNS cache\n", hostname); 1480 } 1481 1482 if(!dns) 1483 result = Curl_resolver_is_resolved(data->easy_conn, &dns); 1484 1485 /* Update sockets here, because the socket(s) may have been 1486 closed and the application thus needs to be told, even if it 1487 is likely that the same socket(s) will again be used further 1488 down. If the name has not yet been resolved, it is likely 1489 that new sockets have been opened in an attempt to contact 1490 another resolver. */ 1491 singlesocket(multi, data); 1492 1493 if(dns) { 1494 /* Perform the next step in the connection phase, and then move on 1495 to the WAITCONNECT state */ 1496 result = Curl_async_resolved(data->easy_conn, &protocol_connect); 1497 1498 if(result) 1499 /* if Curl_async_resolved() returns failure, the connection struct 1500 is already freed and gone */ 1501 data->easy_conn = NULL; /* no more connection */ 1502 else { 1503 /* call again please so that we get the next socket setup */ 1504 rc = CURLM_CALL_MULTI_PERFORM; 1505 if(protocol_connect) 1506 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? 1507 CURLM_STATE_WAITDO:CURLM_STATE_DO); 1508 else { 1509#ifndef CURL_DISABLE_HTTP 1510 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) 1511 multistate(data, CURLM_STATE_WAITPROXYCONNECT); 1512 else 1513#endif 1514 multistate(data, CURLM_STATE_WAITCONNECT); 1515 } 1516 } 1517 } 1518 1519 if(result) { 1520 /* failure detected */ 1521 disconnect_conn = TRUE; 1522 break; 1523 } 1524 } 1525 break; 1526 1527#ifndef CURL_DISABLE_HTTP 1528 case CURLM_STATE_WAITPROXYCONNECT: 1529 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ 1530 result = Curl_http_connect(data->easy_conn, &protocol_connect); 1531 1532 if(data->easy_conn->bits.proxy_connect_closed) { 1533 rc = CURLM_CALL_MULTI_PERFORM; 1534 /* connect back to proxy again */ 1535 result = CURLE_OK; 1536 multi_done(&data->easy_conn, CURLE_OK, FALSE); 1537 multistate(data, CURLM_STATE_CONNECT); 1538 } 1539 else if(!result) { 1540 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE) { 1541 rc = CURLM_CALL_MULTI_PERFORM; 1542 /* initiate protocol connect phase */ 1543 multistate(data, CURLM_STATE_SENDPROTOCONNECT); 1544 } 1545 } 1546 break; 1547#endif 1548 1549 case CURLM_STATE_WAITCONNECT: 1550 /* awaiting a completion of an asynch TCP connect */ 1551 result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected); 1552 if(connected && !result) { 1553 rc = CURLM_CALL_MULTI_PERFORM; 1554 multistate(data, data->easy_conn->bits.tunnel_proxy? 1555 CURLM_STATE_WAITPROXYCONNECT: 1556 CURLM_STATE_SENDPROTOCONNECT); 1557 } 1558 else if(result) { 1559 /* failure detected */ 1560 /* Just break, the cleaning up is handled all in one place */ 1561 disconnect_conn = TRUE; 1562 break; 1563 } 1564 break; 1565 1566 case CURLM_STATE_SENDPROTOCONNECT: 1567 result = Curl_protocol_connect(data->easy_conn, &protocol_connect); 1568 if(!protocol_connect) 1569 /* switch to waiting state */ 1570 multistate(data, CURLM_STATE_PROTOCONNECT); 1571 else if(!result) { 1572 /* protocol connect has completed, go WAITDO or DO */ 1573 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? 1574 CURLM_STATE_WAITDO:CURLM_STATE_DO); 1575 rc = CURLM_CALL_MULTI_PERFORM; 1576 } 1577 else if(result) { 1578 /* failure detected */ 1579 Curl_posttransfer(data); 1580 multi_done(&data->easy_conn, result, TRUE); 1581 disconnect_conn = TRUE; 1582 } 1583 break; 1584 1585 case CURLM_STATE_PROTOCONNECT: 1586 /* protocol-specific connect phase */ 1587 result = Curl_protocol_connecting(data->easy_conn, &protocol_connect); 1588 if(!result && protocol_connect) { 1589 /* after the connect has completed, go WAITDO or DO */ 1590 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? 1591 CURLM_STATE_WAITDO:CURLM_STATE_DO); 1592 rc = CURLM_CALL_MULTI_PERFORM; 1593 } 1594 else if(result) { 1595 /* failure detected */ 1596 Curl_posttransfer(data); 1597 multi_done(&data->easy_conn, result, TRUE); 1598 disconnect_conn = TRUE; 1599 } 1600 break; 1601 1602 case CURLM_STATE_WAITDO: 1603 /* Wait for our turn to DO when we're pipelining requests */ 1604 if(Curl_pipeline_checkget_write(data, data->easy_conn)) { 1605 /* Grabbed the channel */ 1606 multistate(data, CURLM_STATE_DO); 1607 rc = CURLM_CALL_MULTI_PERFORM; 1608 } 1609 break; 1610 1611 case CURLM_STATE_DO: 1612 if(data->set.connect_only) { 1613 /* keep connection open for application to use the socket */ 1614 connkeep(data->easy_conn, "CONNECT_ONLY"); 1615 multistate(data, CURLM_STATE_DONE); 1616 result = CURLE_OK; 1617 rc = CURLM_CALL_MULTI_PERFORM; 1618 } 1619 else { 1620 /* Perform the protocol's DO action */ 1621 result = multi_do(&data->easy_conn, &dophase_done); 1622 1623 /* When multi_do() returns failure, data->easy_conn might be NULL! */ 1624 1625 if(!result) { 1626 if(!dophase_done) { 1627 /* some steps needed for wildcard matching */ 1628 if(data->set.wildcardmatch) { 1629 struct WildcardData *wc = &data->wildcard; 1630 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { 1631 /* skip some states if it is important */ 1632 multi_done(&data->easy_conn, CURLE_OK, FALSE); 1633 multistate(data, CURLM_STATE_DONE); 1634 rc = CURLM_CALL_MULTI_PERFORM; 1635 break; 1636 } 1637 } 1638 /* DO was not completed in one function call, we must continue 1639 DOING... */ 1640 multistate(data, CURLM_STATE_DOING); 1641 rc = CURLM_OK; 1642 } 1643 1644 /* after DO, go DO_DONE... or DO_MORE */ 1645 else if(data->easy_conn->bits.do_more) { 1646 /* we're supposed to do more, but we need to sit down, relax 1647 and wait a little while first */ 1648 multistate(data, CURLM_STATE_DO_MORE); 1649 rc = CURLM_OK; 1650 } 1651 else { 1652 /* we're done with the DO, now DO_DONE */ 1653 multistate(data, CURLM_STATE_DO_DONE); 1654 rc = CURLM_CALL_MULTI_PERFORM; 1655 } 1656 } 1657 else if((CURLE_SEND_ERROR == result) && 1658 data->easy_conn->bits.reuse) { 1659 /* 1660 * In this situation, a connection that we were trying to use 1661 * may have unexpectedly died. If possible, send the connection 1662 * back to the CONNECT phase so we can try again. 1663 */ 1664 char *newurl = NULL; 1665 followtype follow=FOLLOW_NONE; 1666 CURLcode drc; 1667 bool retry = FALSE; 1668 1669 drc = Curl_retry_request(data->easy_conn, &newurl); 1670 if(drc) { 1671 /* a failure here pretty much implies an out of memory */ 1672 result = drc; 1673 disconnect_conn = TRUE; 1674 } 1675 else 1676 retry = (newurl)?TRUE:FALSE; 1677 1678 Curl_posttransfer(data); 1679 drc = multi_done(&data->easy_conn, result, FALSE); 1680 1681 /* When set to retry the connection, we must to go back to 1682 * the CONNECT state */ 1683 if(retry) { 1684 if(!drc || (drc == CURLE_SEND_ERROR)) { 1685 follow = FOLLOW_RETRY; 1686 drc = Curl_follow(data, newurl, follow); 1687 if(!drc) { 1688 multistate(data, CURLM_STATE_CONNECT); 1689 rc = CURLM_CALL_MULTI_PERFORM; 1690 result = CURLE_OK; 1691 } 1692 else { 1693 /* Follow failed */ 1694 result = drc; 1695 free(newurl); 1696 } 1697 } 1698 else { 1699 /* done didn't return OK or SEND_ERROR */ 1700 result = drc; 1701 free(newurl); 1702 } 1703 } 1704 else { 1705 /* Have error handler disconnect conn if we can't retry */ 1706 disconnect_conn = TRUE; 1707 free(newurl); 1708 } 1709 } 1710 else { 1711 /* failure detected */ 1712 Curl_posttransfer(data); 1713 if(data->easy_conn) 1714 multi_done(&data->easy_conn, result, FALSE); 1715 disconnect_conn = TRUE; 1716 } 1717 } 1718 break; 1719 1720 case CURLM_STATE_DOING: 1721 /* we continue DOING until the DO phase is complete */ 1722 result = Curl_protocol_doing(data->easy_conn, 1723 &dophase_done); 1724 if(!result) { 1725 if(dophase_done) { 1726 /* after DO, go DO_DONE or DO_MORE */ 1727 multistate(data, data->easy_conn->bits.do_more? 1728 CURLM_STATE_DO_MORE: 1729 CURLM_STATE_DO_DONE); 1730 rc = CURLM_CALL_MULTI_PERFORM; 1731 } /* dophase_done */ 1732 } 1733 else { 1734 /* failure detected */ 1735 Curl_posttransfer(data); 1736 multi_done(&data->easy_conn, result, FALSE); 1737 disconnect_conn = TRUE; 1738 } 1739 break; 1740 1741 case CURLM_STATE_DO_MORE: 1742 /* 1743 * When we are connected, DO MORE and then go DO_DONE 1744 */ 1745 result = multi_do_more(data->easy_conn, &control); 1746 1747 /* No need to remove this handle from the send pipeline here since that 1748 is done in multi_done() */ 1749 if(!result) { 1750 if(control) { 1751 /* if positive, advance to DO_DONE 1752 if negative, go back to DOING */ 1753 multistate(data, control==1? 1754 CURLM_STATE_DO_DONE: 1755 CURLM_STATE_DOING); 1756 rc = CURLM_CALL_MULTI_PERFORM; 1757 } 1758 else 1759 /* stay in DO_MORE */ 1760 rc = CURLM_OK; 1761 } 1762 else { 1763 /* failure detected */ 1764 Curl_posttransfer(data); 1765 multi_done(&data->easy_conn, result, FALSE); 1766 disconnect_conn = TRUE; 1767 } 1768 break; 1769 1770 case CURLM_STATE_DO_DONE: 1771 /* Move ourselves from the send to recv pipeline */ 1772 Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn); 1773 /* Check if we can move pending requests to send pipe */ 1774 Curl_multi_process_pending_handles(multi); 1775 1776 /* Only perform the transfer if there's a good socket to work with. 1777 Having both BAD is a signal to skip immediately to DONE */ 1778 if((data->easy_conn->sockfd != CURL_SOCKET_BAD) || 1779 (data->easy_conn->writesockfd != CURL_SOCKET_BAD)) 1780 multistate(data, CURLM_STATE_WAITPERFORM); 1781 else 1782 multistate(data, CURLM_STATE_DONE); 1783 rc = CURLM_CALL_MULTI_PERFORM; 1784 break; 1785 1786 case CURLM_STATE_WAITPERFORM: 1787 /* Wait for our turn to PERFORM */ 1788 if(Curl_pipeline_checkget_read(data, data->easy_conn)) { 1789 /* Grabbed the channel */ 1790 multistate(data, CURLM_STATE_PERFORM); 1791 rc = CURLM_CALL_MULTI_PERFORM; 1792 } 1793 break; 1794 1795 case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */ 1796 /* if both rates are within spec, resume transfer */ 1797 if(Curl_pgrsUpdate(data->easy_conn)) 1798 result = CURLE_ABORTED_BY_CALLBACK; 1799 else 1800 result = Curl_speedcheck(data, now); 1801 1802 if(( (data->set.max_send_speed == 0) || 1803 (data->progress.ulspeed < data->set.max_send_speed)) && 1804 ( (data->set.max_recv_speed == 0) || 1805 (data->progress.dlspeed < data->set.max_recv_speed))) 1806 multistate(data, CURLM_STATE_PERFORM); 1807 break; 1808 1809 case CURLM_STATE_PERFORM: 1810 { 1811 char *newurl = NULL; 1812 bool retry = FALSE; 1813 1814 /* check if over send speed */ 1815 if((data->set.max_send_speed > 0) && 1816 (data->progress.ulspeed > data->set.max_send_speed)) { 1817 int buffersize; 1818 1819 multistate(data, CURLM_STATE_TOOFAST); 1820 1821 /* calculate upload rate-limitation timeout. */ 1822 buffersize = (int)(data->set.buffer_size ? 1823 data->set.buffer_size : BUFSIZE); 1824 timeout_ms = Curl_sleep_time(data->set.max_send_speed, 1825 data->progress.ulspeed, buffersize); 1826 Curl_expire_latest(data, timeout_ms); 1827 break; 1828 } 1829 1830 /* check if over recv speed */ 1831 if((data->set.max_recv_speed > 0) && 1832 (data->progress.dlspeed > data->set.max_recv_speed)) { 1833 int buffersize; 1834 1835 multistate(data, CURLM_STATE_TOOFAST); 1836 1837 /* Calculate download rate-limitation timeout. */ 1838 buffersize = (int)(data->set.buffer_size ? 1839 data->set.buffer_size : BUFSIZE); 1840 timeout_ms = Curl_sleep_time(data->set.max_recv_speed, 1841 data->progress.dlspeed, buffersize); 1842 Curl_expire_latest(data, timeout_ms); 1843 break; 1844 } 1845 1846 /* read/write data if it is ready to do so */ 1847 result = Curl_readwrite(data->easy_conn, data, &done); 1848 1849 k = &data->req; 1850 1851 if(!(k->keepon & KEEP_RECV)) 1852 /* We're done receiving */ 1853 Curl_pipeline_leave_read(data->easy_conn); 1854 1855 if(!(k->keepon & KEEP_SEND)) 1856 /* We're done sending */ 1857 Curl_pipeline_leave_write(data->easy_conn); 1858 1859 if(done || (result == CURLE_RECV_ERROR)) { 1860 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race 1861 * condition and the server closed the re-used connection exactly when 1862 * we wanted to use it, so figure out if that is indeed the case. 1863 */ 1864 CURLcode ret = Curl_retry_request(data->easy_conn, &newurl); 1865 if(!ret) 1866 retry = (newurl)?TRUE:FALSE; 1867 1868 if(retry) { 1869 /* if we are to retry, set the result to OK and consider the 1870 request as done */ 1871 result = CURLE_OK; 1872 done = TRUE; 1873 } 1874 } 1875 1876 if(result) { 1877 /* 1878 * The transfer phase returned error, we mark the connection to get 1879 * closed to prevent being re-used. This is because we can't possibly 1880 * know if the connection is in a good shape or not now. Unless it is 1881 * a protocol which uses two "channels" like FTP, as then the error 1882 * happened in the data connection. 1883 */ 1884 1885 if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) && 1886 result != CURLE_HTTP2_STREAM) 1887 connclose(data->easy_conn, "Transfer returned error"); 1888 1889 Curl_posttransfer(data); 1890 multi_done(&data->easy_conn, result, FALSE); 1891 } 1892 else if(done) { 1893 followtype follow=FOLLOW_NONE; 1894 1895 /* call this even if the readwrite function returned error */ 1896 Curl_posttransfer(data); 1897 1898 /* we're no longer receiving */ 1899 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe); 1900 1901 /* expire the new receiving pipeline head */ 1902 if(data->easy_conn->recv_pipe->head) 1903 Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1); 1904 1905 /* Check if we can move pending requests to send pipe */ 1906 Curl_multi_process_pending_handles(multi); 1907 1908 /* When we follow redirects or is set to retry the connection, we must 1909 to go back to the CONNECT state */ 1910 if(data->req.newurl || retry) { 1911 if(!retry) { 1912 /* if the URL is a follow-location and not just a retried request 1913 then figure out the URL here */ 1914 free(newurl); 1915 newurl = data->req.newurl; 1916 data->req.newurl = NULL; 1917 follow = FOLLOW_REDIR; 1918 } 1919 else 1920 follow = FOLLOW_RETRY; 1921 result = multi_done(&data->easy_conn, CURLE_OK, FALSE); 1922 if(!result) { 1923 result = Curl_follow(data, newurl, follow); 1924 if(!result) { 1925 multistate(data, CURLM_STATE_CONNECT); 1926 rc = CURLM_CALL_MULTI_PERFORM; 1927 newurl = NULL; /* handed over the memory ownership to 1928 Curl_follow(), make sure we don't free() it 1929 here */ 1930 } 1931 } 1932 } 1933 else { 1934 /* after the transfer is done, go DONE */ 1935 1936 /* but first check to see if we got a location info even though we're 1937 not following redirects */ 1938 if(data->req.location) { 1939 free(newurl); 1940 newurl = data->req.location; 1941 data->req.location = NULL; 1942 result = Curl_follow(data, newurl, FOLLOW_FAKE); 1943 if(!result) 1944 newurl = NULL; /* allocation was handed over Curl_follow() */ 1945 else 1946 disconnect_conn = TRUE; 1947 } 1948 1949 multistate(data, CURLM_STATE_DONE); 1950 rc = CURLM_CALL_MULTI_PERFORM; 1951 } 1952 } 1953 1954 free(newurl); 1955 break; 1956 } 1957 1958 case CURLM_STATE_DONE: 1959 /* this state is highly transient, so run another loop after this */ 1960 rc = CURLM_CALL_MULTI_PERFORM; 1961 1962 if(data->easy_conn) { 1963 CURLcode res; 1964 1965 /* Remove ourselves from the receive pipeline, if we are there. */ 1966 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe); 1967 /* Check if we can move pending requests to send pipe */ 1968 Curl_multi_process_pending_handles(multi); 1969 1970 /* post-transfer command */ 1971 res = multi_done(&data->easy_conn, result, FALSE); 1972 1973 /* allow a previously set error code take precedence */ 1974 if(!result) 1975 result = res; 1976 1977 /* 1978 * If there are other handles on the pipeline, multi_done won't set 1979 * easy_conn to NULL. In such a case, curl_multi_remove_handle() can 1980 * access free'd data, if the connection is free'd and the handle 1981 * removed before we perform the processing in CURLM_STATE_COMPLETED 1982 */ 1983 if(data->easy_conn) 1984 data->easy_conn = NULL; 1985 } 1986 1987 if(data->set.wildcardmatch) { 1988 if(data->wildcard.state != CURLWC_DONE) { 1989 /* if a wildcard is set and we are not ending -> lets start again 1990 with CURLM_STATE_INIT */ 1991 multistate(data, CURLM_STATE_INIT); 1992 break; 1993 } 1994 } 1995 1996 /* after we have DONE what we're supposed to do, go COMPLETED, and 1997 it doesn't matter what the multi_done() returned! */ 1998 multistate(data, CURLM_STATE_COMPLETED); 1999 break; 2000 2001 case CURLM_STATE_COMPLETED: 2002 /* this is a completed transfer, it is likely to still be connected */ 2003 2004 /* This node should be delinked from the list now and we should post 2005 an information message that we are complete. */ 2006 2007 /* Important: reset the conn pointer so that we don't point to memory 2008 that could be freed anytime */ 2009 data->easy_conn = NULL; 2010 2011 Curl_expire(data, 0); /* stop all timers */ 2012 break; 2013 2014 case CURLM_STATE_MSGSENT: 2015 data->result = result; 2016 return CURLM_OK; /* do nothing */ 2017 2018 default: 2019 return CURLM_INTERNAL_ERROR; 2020 } 2021 statemachine_end: 2022 2023 if(data->mstate < CURLM_STATE_COMPLETED) { 2024 if(result) { 2025 /* 2026 * If an error was returned, and we aren't in completed state now, 2027 * then we go to completed and consider this transfer aborted. 2028 */ 2029 2030 /* NOTE: no attempt to disconnect connections must be made 2031 in the case blocks above - cleanup happens only here */ 2032 2033 data->state.pipe_broke = FALSE; 2034 2035 /* Check if we can move pending requests to send pipe */ 2036 Curl_multi_process_pending_handles(multi); 2037 2038 if(data->easy_conn) { 2039 /* if this has a connection, unsubscribe from the pipelines */ 2040 Curl_pipeline_leave_write(data->easy_conn); 2041 Curl_pipeline_leave_read(data->easy_conn); 2042 Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe); 2043 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe); 2044 2045 if(disconnect_conn) { 2046 /* Don't attempt to send data over a connection that timed out */ 2047 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT; 2048 /* disconnect properly */ 2049 Curl_disconnect(data->easy_conn, dead_connection); 2050 2051 /* This is where we make sure that the easy_conn pointer is reset. 2052 We don't have to do this in every case block above where a 2053 failure is detected */ 2054 data->easy_conn = NULL; 2055 } 2056 } 2057 else if(data->mstate == CURLM_STATE_CONNECT) { 2058 /* Curl_connect() failed */ 2059 (void)Curl_posttransfer(data); 2060 } 2061 2062 multistate(data, CURLM_STATE_COMPLETED); 2063 } 2064 /* if there's still a connection to use, call the progress function */ 2065 else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) { 2066 /* aborted due to progress callback return code must close the 2067 connection */ 2068 result = CURLE_ABORTED_BY_CALLBACK; 2069 connclose(data->easy_conn, "Aborted by callback"); 2070 2071 /* if not yet in DONE state, go there, otherwise COMPLETED */ 2072 multistate(data, (data->mstate < CURLM_STATE_DONE)? 2073 CURLM_STATE_DONE: CURLM_STATE_COMPLETED); 2074 rc = CURLM_CALL_MULTI_PERFORM; 2075 } 2076 } 2077 2078 if(CURLM_STATE_COMPLETED == data->mstate) { 2079 /* now fill in the Curl_message with this info */ 2080 msg = &data->msg; 2081 2082 msg->extmsg.msg = CURLMSG_DONE; 2083 msg->extmsg.easy_handle = data; 2084 msg->extmsg.data.result = result; 2085 2086 rc = multi_addmsg(multi, msg); 2087 2088 multistate(data, CURLM_STATE_MSGSENT); 2089 } 2090 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); 2091 2092 data->result = result; 2093 2094 2095 return rc; 2096} 2097 2098 2099CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) 2100{ 2101 struct Curl_easy *data; 2102 CURLMcode returncode=CURLM_OK; 2103 struct Curl_tree *t; 2104 struct timeval now = Curl_tvnow(); 2105 2106 if(!GOOD_MULTI_HANDLE(multi)) 2107 return CURLM_BAD_HANDLE; 2108 2109 data=multi->easyp; 2110 while(data) { 2111 CURLMcode result; 2112 SIGPIPE_VARIABLE(pipe_st); 2113 2114 sigpipe_ignore(data, &pipe_st); 2115 result = multi_runsingle(multi, now, data); 2116 sigpipe_restore(&pipe_st); 2117 2118 if(result) 2119 returncode = result; 2120 2121 data = data->next; /* operate on next handle */ 2122 } 2123 2124 /* 2125 * Simply remove all expired timers from the splay since handles are dealt 2126 * with unconditionally by this function and curl_multi_timeout() requires 2127 * that already passed/handled expire times are removed from the splay. 2128 * 2129 * It is important that the 'now' value is set at the entry of this function 2130 * and not for the current time as it may have ticked a little while since 2131 * then and then we risk this loop to remove timers that actually have not 2132 * been handled! 2133 */ 2134 do { 2135 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); 2136 if(t) 2137 /* the removed may have another timeout in queue */ 2138 (void)add_next_timeout(now, multi, t->payload); 2139 2140 } while(t); 2141 2142 *running_handles = multi->num_alive; 2143 2144 if(CURLM_OK >= returncode) 2145 update_timer(multi); 2146 2147 return returncode; 2148} 2149 2150static void close_all_connections(struct Curl_multi *multi) 2151{ 2152 struct connectdata *conn; 2153 2154 conn = Curl_conncache_find_first_connection(&multi->conn_cache); 2155 while(conn) { 2156 SIGPIPE_VARIABLE(pipe_st); 2157 conn->data = multi->closure_handle; 2158 2159 sigpipe_ignore(conn->data, &pipe_st); 2160 conn->data->easy_conn = NULL; /* clear the easy handle's connection 2161 pointer */ 2162 /* This will remove the connection from the cache */ 2163 (void)Curl_disconnect(conn, FALSE); 2164 sigpipe_restore(&pipe_st); 2165 2166 conn = Curl_conncache_find_first_connection(&multi->conn_cache); 2167 } 2168} 2169 2170CURLMcode curl_multi_cleanup(struct Curl_multi *multi) 2171{ 2172 struct Curl_easy *data; 2173 struct Curl_easy *nextdata; 2174 2175 if(GOOD_MULTI_HANDLE(multi)) { 2176 bool restore_pipe = FALSE; 2177 SIGPIPE_VARIABLE(pipe_st); 2178 2179 multi->type = 0; /* not good anymore */ 2180 2181 /* Close all the connections in the connection cache */ 2182 close_all_connections(multi); 2183 2184 if(multi->closure_handle) { 2185 sigpipe_ignore(multi->closure_handle, &pipe_st); 2186 restore_pipe = TRUE; 2187 2188 multi->closure_handle->dns.hostcache = &multi->hostcache; 2189 Curl_hostcache_clean(multi->closure_handle, 2190 multi->closure_handle->dns.hostcache); 2191 2192 Curl_close(multi->closure_handle); 2193 } 2194 2195 Curl_hash_destroy(&multi->sockhash); 2196 Curl_conncache_destroy(&multi->conn_cache); 2197 Curl_llist_destroy(multi->msglist, NULL); 2198 Curl_llist_destroy(multi->pending, NULL); 2199 2200 /* remove all easy handles */ 2201 data = multi->easyp; 2202 while(data) { 2203 nextdata=data->next; 2204 if(data->dns.hostcachetype == HCACHE_MULTI) { 2205 /* clear out the usage of the shared DNS cache */ 2206 Curl_hostcache_clean(data, data->dns.hostcache); 2207 data->dns.hostcache = NULL; 2208 data->dns.hostcachetype = HCACHE_NONE; 2209 } 2210 2211 /* Clear the pointer to the connection cache */ 2212 data->state.conn_cache = NULL; 2213 data->multi = NULL; /* clear the association */ 2214 2215 data = nextdata; 2216 } 2217 2218 Curl_hash_destroy(&multi->hostcache); 2219 2220 /* Free the blacklists by setting them to NULL */ 2221 Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl); 2222 Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl); 2223 2224 free(multi); 2225 if(restore_pipe) 2226 sigpipe_restore(&pipe_st); 2227 2228 return CURLM_OK; 2229 } 2230 else 2231 return CURLM_BAD_HANDLE; 2232} 2233 2234/* 2235 * curl_multi_info_read() 2236 * 2237 * This function is the primary way for a multi/multi_socket application to 2238 * figure out if a transfer has ended. We MUST make this function as fast as 2239 * possible as it will be polled frequently and we MUST NOT scan any lists in 2240 * here to figure out things. We must scale fine to thousands of handles and 2241 * beyond. The current design is fully O(1). 2242 */ 2243 2244CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) 2245{ 2246 struct Curl_message *msg; 2247 2248 *msgs_in_queue = 0; /* default to none */ 2249 2250 if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) { 2251 /* there is one or more messages in the list */ 2252 struct curl_llist_element *e; 2253 2254 /* extract the head of the list to return */ 2255 e = multi->msglist->head; 2256 2257 msg = e->ptr; 2258 2259 /* remove the extracted entry */ 2260 Curl_llist_remove(multi->msglist, e, NULL); 2261 2262 *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist)); 2263 2264 return &msg->extmsg; 2265 } 2266 else 2267 return NULL; 2268} 2269 2270/* 2271 * singlesocket() checks what sockets we deal with and their "action state" 2272 * and if we have a different state in any of those sockets from last time we 2273 * call the callback accordingly. 2274 */ 2275static void singlesocket(struct Curl_multi *multi, 2276 struct Curl_easy *data) 2277{ 2278 curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; 2279 int i; 2280 struct Curl_sh_entry *entry; 2281 curl_socket_t s; 2282 int num; 2283 unsigned int curraction; 2284 2285 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) 2286 socks[i] = CURL_SOCKET_BAD; 2287 2288 /* Fill in the 'current' struct with the state as it is now: what sockets to 2289 supervise and for what actions */ 2290 curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE); 2291 2292 /* We have 0 .. N sockets already and we get to know about the 0 .. M 2293 sockets we should have from now on. Detect the differences, remove no 2294 longer supervised ones and add new ones */ 2295 2296 /* walk over the sockets we got right now */ 2297 for(i=0; (i< MAX_SOCKSPEREASYHANDLE) && 2298 (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); 2299 i++) { 2300 int action = CURL_POLL_NONE; 2301 2302 s = socks[i]; 2303 2304 /* get it from the hash */ 2305 entry = sh_getentry(&multi->sockhash, s); 2306 2307 if(curraction & GETSOCK_READSOCK(i)) 2308 action |= CURL_POLL_IN; 2309 if(curraction & GETSOCK_WRITESOCK(i)) 2310 action |= CURL_POLL_OUT; 2311 2312 if(entry) { 2313 /* yeps, already present so check if it has the same action set */ 2314 if(entry->action == action) 2315 /* same, continue */ 2316 continue; 2317 } 2318 else { 2319 /* this is a socket we didn't have before, add it! */ 2320 entry = sh_addentry(&multi->sockhash, s, data); 2321 if(!entry) 2322 /* fatal */ 2323 return; 2324 } 2325 2326 /* we know (entry != NULL) at this point, see the logic above */ 2327 if(multi->socket_cb) 2328 multi->socket_cb(data, 2329 s, 2330 action, 2331 multi->socket_userp, 2332 entry->socketp); 2333 2334 entry->action = action; /* store the current action state */ 2335 } 2336 2337 num = i; /* number of sockets */ 2338 2339 /* when we've walked over all the sockets we should have right now, we must 2340 make sure to detect sockets that are removed */ 2341 for(i=0; i< data->numsocks; i++) { 2342 int j; 2343 s = data->sockets[i]; 2344 for(j=0; j<num; j++) { 2345 if(s == socks[j]) { 2346 /* this is still supervised */ 2347 s = CURL_SOCKET_BAD; 2348 break; 2349 } 2350 } 2351 2352 entry = sh_getentry(&multi->sockhash, s); 2353 if(entry) { 2354 /* this socket has been removed. Tell the app to remove it */ 2355 bool remove_sock_from_hash = TRUE; 2356 2357 /* check if the socket to be removed serves a connection which has 2358 other easy-s in a pipeline. In this case the socket should not be 2359 removed. */ 2360 struct connectdata *easy_conn = data->easy_conn; 2361 if(easy_conn) { 2362 if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) { 2363 /* the handle should not be removed from the pipe yet */ 2364 remove_sock_from_hash = FALSE; 2365 2366 /* Update the sockhash entry to instead point to the next in line 2367 for the recv_pipe, or the first (in case this particular easy 2368 isn't already) */ 2369 if(entry->easy == data) { 2370 if(Curl_recvpipe_head(data, easy_conn)) 2371 entry->easy = easy_conn->recv_pipe->head->next->ptr; 2372 else 2373 entry->easy = easy_conn->recv_pipe->head->ptr; 2374 } 2375 } 2376 if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) { 2377 /* the handle should not be removed from the pipe yet */ 2378 remove_sock_from_hash = FALSE; 2379 2380 /* Update the sockhash entry to instead point to the next in line 2381 for the send_pipe, or the first (in case this particular easy 2382 isn't already) */ 2383 if(entry->easy == data) { 2384 if(Curl_sendpipe_head(data, easy_conn)) 2385 entry->easy = easy_conn->send_pipe->head->next->ptr; 2386 else 2387 entry->easy = easy_conn->send_pipe->head->ptr; 2388 } 2389 } 2390 /* Don't worry about overwriting recv_pipe head with send_pipe_head, 2391 when action will be asked on the socket (see multi_socket()), the 2392 head of the correct pipe will be taken according to the 2393 action. */ 2394 } 2395 2396 if(remove_sock_from_hash) { 2397 /* in this case 'entry' is always non-NULL */ 2398 if(multi->socket_cb) 2399 multi->socket_cb(data, 2400 s, 2401 CURL_POLL_REMOVE, 2402 multi->socket_userp, 2403 entry->socketp); 2404 sh_delentry(&multi->sockhash, s); 2405 } 2406 } /* if sockhash entry existed */ 2407 } /* for loop over numsocks */ 2408 2409 memcpy(data->sockets, socks, num*sizeof(curl_socket_t)); 2410 data->numsocks = num; 2411} 2412 2413/* 2414 * Curl_multi_closed() 2415 * 2416 * Used by the connect code to tell the multi_socket code that one of the 2417 * sockets we were using is about to be closed. This function will then 2418 * remove it from the sockethash for this handle to make the multi_socket API 2419 * behave properly, especially for the case when libcurl will create another 2420 * socket again and it gets the same file descriptor number. 2421 */ 2422 2423void Curl_multi_closed(struct connectdata *conn, curl_socket_t s) 2424{ 2425 struct Curl_multi *multi = conn->data->multi; 2426 if(multi) { 2427 /* this is set if this connection is part of a handle that is added to 2428 a multi handle, and only then this is necessary */ 2429 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); 2430 2431 if(entry) { 2432 if(multi->socket_cb) 2433 multi->socket_cb(conn->data, s, CURL_POLL_REMOVE, 2434 multi->socket_userp, 2435 entry->socketp); 2436 2437 /* now remove it from the socket hash */ 2438 sh_delentry(&multi->sockhash, s); 2439 } 2440 } 2441} 2442 2443 2444 2445/* 2446 * add_next_timeout() 2447 * 2448 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called 2449 * when it has just been removed from the splay tree because the timeout has 2450 * expired. This function is then to advance in the list to pick the next 2451 * timeout to use (skip the already expired ones) and add this node back to 2452 * the splay tree again. 2453 * 2454 * The splay tree only has each sessionhandle as a single node and the nearest 2455 * timeout is used to sort it on. 2456 */ 2457static CURLMcode add_next_timeout(struct timeval now, 2458 struct Curl_multi *multi, 2459 struct Curl_easy *d) 2460{ 2461 struct timeval *tv = &d->state.expiretime; 2462 struct curl_llist *list = d->state.timeoutlist; 2463 struct curl_llist_element *e; 2464 2465 /* move over the timeout list for this specific handle and remove all 2466 timeouts that are now passed tense and store the next pending 2467 timeout in *tv */ 2468 for(e = list->head; e;) { 2469 struct curl_llist_element *n = e->next; 2470 long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now); 2471 if(diff <= 0) 2472 /* remove outdated entry */ 2473 Curl_llist_remove(list, e, NULL); 2474 else 2475 /* the list is sorted so get out on the first mismatch */ 2476 break; 2477 e = n; 2478 } 2479 e = list->head; 2480 if(!e) { 2481 /* clear the expire times within the handles that we remove from the 2482 splay tree */ 2483 tv->tv_sec = 0; 2484 tv->tv_usec = 0; 2485 } 2486 else { 2487 /* copy the first entry to 'tv' */ 2488 memcpy(tv, e->ptr, sizeof(*tv)); 2489 2490 /* remove first entry from list */ 2491 Curl_llist_remove(list, e, NULL); 2492 2493 /* insert this node again into the splay */ 2494 multi->timetree = Curl_splayinsert(*tv, multi->timetree, 2495 &d->state.timenode); 2496 } 2497 return CURLM_OK; 2498} 2499 2500static CURLMcode multi_socket(struct Curl_multi *multi, 2501 bool checkall, 2502 curl_socket_t s, 2503 int ev_bitmask, 2504 int *running_handles) 2505{ 2506 CURLMcode result = CURLM_OK; 2507 struct Curl_easy *data = NULL; 2508 struct Curl_tree *t; 2509 struct timeval now = Curl_tvnow(); 2510 2511 if(checkall) { 2512 /* *perform() deals with running_handles on its own */ 2513 result = curl_multi_perform(multi, running_handles); 2514 2515 /* walk through each easy handle and do the socket state change magic 2516 and callbacks */ 2517 if(result != CURLM_BAD_HANDLE) { 2518 data=multi->easyp; 2519 while(data) { 2520 singlesocket(multi, data); 2521 data = data->next; 2522 } 2523 } 2524 2525 /* or should we fall-through and do the timer-based stuff? */ 2526 return result; 2527 } 2528 else if(s != CURL_SOCKET_TIMEOUT) { 2529 2530 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); 2531 2532 if(!entry) 2533 /* Unmatched socket, we can't act on it but we ignore this fact. In 2534 real-world tests it has been proved that libevent can in fact give 2535 the application actions even though the socket was just previously 2536 asked to get removed, so thus we better survive stray socket actions 2537 and just move on. */ 2538 ; 2539 else { 2540 SIGPIPE_VARIABLE(pipe_st); 2541 2542 data = entry->easy; 2543 2544 if(data->magic != CURLEASY_MAGIC_NUMBER) 2545 /* bad bad bad bad bad bad bad */ 2546 return CURLM_INTERNAL_ERROR; 2547 2548 /* If the pipeline is enabled, take the handle which is in the head of 2549 the pipeline. If we should write into the socket, take the send_pipe 2550 head. If we should read from the socket, take the recv_pipe head. */ 2551 if(data->easy_conn) { 2552 if((ev_bitmask & CURL_POLL_OUT) && 2553 data->easy_conn->send_pipe && 2554 data->easy_conn->send_pipe->head) 2555 data = data->easy_conn->send_pipe->head->ptr; 2556 else if((ev_bitmask & CURL_POLL_IN) && 2557 data->easy_conn->recv_pipe && 2558 data->easy_conn->recv_pipe->head) 2559 data = data->easy_conn->recv_pipe->head->ptr; 2560 } 2561 2562 if(data->easy_conn && 2563 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK)) 2564 /* set socket event bitmask if they're not locked */ 2565 data->easy_conn->cselect_bits = ev_bitmask; 2566 2567 sigpipe_ignore(data, &pipe_st); 2568 result = multi_runsingle(multi, now, data); 2569 sigpipe_restore(&pipe_st); 2570 2571 if(data->easy_conn && 2572 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK)) 2573 /* clear the bitmask only if not locked */ 2574 data->easy_conn->cselect_bits = 0; 2575 2576 if(CURLM_OK >= result) 2577 /* get the socket(s) and check if the state has been changed since 2578 last */ 2579 singlesocket(multi, data); 2580 2581 /* Now we fall-through and do the timer-based stuff, since we don't want 2582 to force the user to have to deal with timeouts as long as at least 2583 one connection in fact has traffic. */ 2584 2585 data = NULL; /* set data to NULL again to avoid calling 2586 multi_runsingle() in case there's no need to */ 2587 now = Curl_tvnow(); /* get a newer time since the multi_runsingle() loop 2588 may have taken some time */ 2589 } 2590 } 2591 else { 2592 /* Asked to run due to time-out. Clear the 'lastcall' variable to force 2593 update_timer() to trigger a callback to the app again even if the same 2594 timeout is still the one to run after this call. That handles the case 2595 when the application asks libcurl to run the timeout prematurely. */ 2596 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); 2597 } 2598 2599 /* 2600 * The loop following here will go on as long as there are expire-times left 2601 * to process in the splay and 'data' will be re-assigned for every expired 2602 * handle we deal with. 2603 */ 2604 do { 2605 /* the first loop lap 'data' can be NULL */ 2606 if(data) { 2607 SIGPIPE_VARIABLE(pipe_st); 2608 2609 sigpipe_ignore(data, &pipe_st); 2610 result = multi_runsingle(multi, now, data); 2611 sigpipe_restore(&pipe_st); 2612 2613 if(CURLM_OK >= result) 2614 /* get the socket(s) and check if the state has been changed since 2615 last */ 2616 singlesocket(multi, data); 2617 } 2618 2619 /* Check if there's one (more) expired timer to deal with! This function 2620 extracts a matching node if there is one */ 2621 2622 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); 2623 if(t) { 2624 data = t->payload; /* assign this for next loop */ 2625 (void)add_next_timeout(now, multi, t->payload); 2626 } 2627 2628 } while(t); 2629 2630 *running_handles = multi->num_alive; 2631 return result; 2632} 2633 2634#undef curl_multi_setopt 2635CURLMcode curl_multi_setopt(struct Curl_multi *multi, 2636 CURLMoption option, ...) 2637{ 2638 CURLMcode res = CURLM_OK; 2639 va_list param; 2640 2641 if(!GOOD_MULTI_HANDLE(multi)) 2642 return CURLM_BAD_HANDLE; 2643 2644 va_start(param, option); 2645 2646 switch(option) { 2647 case CURLMOPT_SOCKETFUNCTION: 2648 multi->socket_cb = va_arg(param, curl_socket_callback); 2649 break; 2650 case CURLMOPT_SOCKETDATA: 2651 multi->socket_userp = va_arg(param, void *); 2652 break; 2653 case CURLMOPT_PUSHFUNCTION: 2654 multi->push_cb = va_arg(param, curl_push_callback); 2655 break; 2656 case CURLMOPT_PUSHDATA: 2657 multi->push_userp = va_arg(param, void *); 2658 break; 2659 case CURLMOPT_PIPELINING: 2660 multi->pipelining = va_arg(param, long); 2661 break; 2662 case CURLMOPT_TIMERFUNCTION: 2663 multi->timer_cb = va_arg(param, curl_multi_timer_callback); 2664 break; 2665 case CURLMOPT_TIMERDATA: 2666 multi->timer_userp = va_arg(param, void *); 2667 break; 2668 case CURLMOPT_MAXCONNECTS: 2669 multi->maxconnects = va_arg(param, long); 2670 break; 2671 case CURLMOPT_MAX_HOST_CONNECTIONS: 2672 multi->max_host_connections = va_arg(param, long); 2673 break; 2674 case CURLMOPT_MAX_PIPELINE_LENGTH: 2675 multi->max_pipeline_length = va_arg(param, long); 2676 break; 2677 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: 2678 multi->content_length_penalty_size = va_arg(param, long); 2679 break; 2680 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE: 2681 multi->chunk_length_penalty_size = va_arg(param, long); 2682 break; 2683 case CURLMOPT_PIPELINING_SITE_BL: 2684 res = Curl_pipeline_set_site_blacklist(va_arg(param, char **), 2685 &multi->pipelining_site_bl); 2686 break; 2687 case CURLMOPT_PIPELINING_SERVER_BL: 2688 res = Curl_pipeline_set_server_blacklist(va_arg(param, char **), 2689 &multi->pipelining_server_bl); 2690 break; 2691 case CURLMOPT_MAX_TOTAL_CONNECTIONS: 2692 multi->max_total_connections = va_arg(param, long); 2693 break; 2694 default: 2695 res = CURLM_UNKNOWN_OPTION; 2696 break; 2697 } 2698 va_end(param); 2699 return res; 2700} 2701 2702/* we define curl_multi_socket() in the public multi.h header */ 2703#undef curl_multi_socket 2704 2705CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, 2706 int *running_handles) 2707{ 2708 CURLMcode result = multi_socket(multi, FALSE, s, 0, running_handles); 2709 if(CURLM_OK >= result) 2710 update_timer(multi); 2711 return result; 2712} 2713 2714CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, 2715 int ev_bitmask, int *running_handles) 2716{ 2717 CURLMcode result = multi_socket(multi, FALSE, s, 2718 ev_bitmask, running_handles); 2719 if(CURLM_OK >= result) 2720 update_timer(multi); 2721 return result; 2722} 2723 2724CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) 2725 2726{ 2727 CURLMcode result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, 2728 running_handles); 2729 if(CURLM_OK >= result) 2730 update_timer(multi); 2731 return result; 2732} 2733 2734static CURLMcode multi_timeout(struct Curl_multi *multi, 2735 long *timeout_ms) 2736{ 2737 static struct timeval tv_zero = {0, 0}; 2738 2739 if(multi->timetree) { 2740 /* we have a tree of expire times */ 2741 struct timeval now = Curl_tvnow(); 2742 2743 /* splay the lowest to the bottom */ 2744 multi->timetree = Curl_splay(tv_zero, multi->timetree); 2745 2746 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) { 2747 /* some time left before expiration */ 2748 *timeout_ms = curlx_tvdiff(multi->timetree->key, now); 2749 if(!*timeout_ms) 2750 /* 2751 * Since we only provide millisecond resolution on the returned value 2752 * and the diff might be less than one millisecond here, we don't 2753 * return zero as that may cause short bursts of busyloops on fast 2754 * processors while the diff is still present but less than one 2755 * millisecond! instead we return 1 until the time is ripe. 2756 */ 2757 *timeout_ms=1; 2758 } 2759 else 2760 /* 0 means immediately */ 2761 *timeout_ms = 0; 2762 } 2763 else 2764 *timeout_ms = -1; 2765 2766 return CURLM_OK; 2767} 2768 2769CURLMcode curl_multi_timeout(struct Curl_multi *multi, 2770 long *timeout_ms) 2771{ 2772 /* First, make some basic checks that the CURLM handle is a good handle */ 2773 if(!GOOD_MULTI_HANDLE(multi)) 2774 return CURLM_BAD_HANDLE; 2775 2776 return multi_timeout(multi, timeout_ms); 2777} 2778 2779/* 2780 * Tell the application it should update its timers, if it subscribes to the 2781 * update timer callback. 2782 */ 2783static int update_timer(struct Curl_multi *multi) 2784{ 2785 long timeout_ms; 2786 2787 if(!multi->timer_cb) 2788 return 0; 2789 if(multi_timeout(multi, &timeout_ms)) { 2790 return -1; 2791 } 2792 if(timeout_ms < 0) { 2793 static const struct timeval none={0, 0}; 2794 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) { 2795 multi->timer_lastcall = none; 2796 /* there's no timeout now but there was one previously, tell the app to 2797 disable it */ 2798 return multi->timer_cb(multi, -1, multi->timer_userp); 2799 } 2800 return 0; 2801 } 2802 2803 /* When multi_timeout() is done, multi->timetree points to the node with the 2804 * timeout we got the (relative) time-out time for. We can thus easily check 2805 * if this is the same (fixed) time as we got in a previous call and then 2806 * avoid calling the callback again. */ 2807 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0) 2808 return 0; 2809 2810 multi->timer_lastcall = multi->timetree->key; 2811 2812 return multi->timer_cb(multi, timeout_ms, multi->timer_userp); 2813} 2814 2815/* 2816 * multi_freetimeout() 2817 * 2818 * Callback used by the llist system when a single timeout list entry is 2819 * destroyed. 2820 */ 2821static void multi_freetimeout(void *user, void *entryptr) 2822{ 2823 (void)user; 2824 2825 /* the entry was plain malloc()'ed */ 2826 free(entryptr); 2827} 2828 2829/* 2830 * multi_addtimeout() 2831 * 2832 * Add a timestamp to the list of timeouts. Keep the list sorted so that head 2833 * of list is always the timeout nearest in time. 2834 * 2835 */ 2836static CURLMcode 2837multi_addtimeout(struct curl_llist *timeoutlist, 2838 struct timeval *stamp) 2839{ 2840 struct curl_llist_element *e; 2841 struct timeval *timedup; 2842 struct curl_llist_element *prev = NULL; 2843 2844 timedup = malloc(sizeof(*timedup)); 2845 if(!timedup) 2846 return CURLM_OUT_OF_MEMORY; 2847 2848 /* copy the timestamp */ 2849 memcpy(timedup, stamp, sizeof(*timedup)); 2850 2851 if(Curl_llist_count(timeoutlist)) { 2852 /* find the correct spot in the list */ 2853 for(e = timeoutlist->head; e; e = e->next) { 2854 struct timeval *checktime = e->ptr; 2855 long diff = curlx_tvdiff(*checktime, *timedup); 2856 if(diff > 0) 2857 break; 2858 prev = e; 2859 } 2860 2861 } 2862 /* else 2863 this is the first timeout on the list */ 2864 2865 if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) { 2866 free(timedup); 2867 return CURLM_OUT_OF_MEMORY; 2868 } 2869 2870 return CURLM_OK; 2871} 2872 2873/* 2874 * Curl_expire() 2875 * 2876 * given a number of milliseconds from now to use to set the 'act before 2877 * this'-time for the transfer, to be extracted by curl_multi_timeout() 2878 * 2879 * Note that the timeout will be added to a queue of timeouts if it defines a 2880 * moment in time that is later than the current head of queue. 2881 * 2882 * Pass zero to clear all timeout values for this handle. 2883*/ 2884void Curl_expire(struct Curl_easy *data, long milli) 2885{ 2886 struct Curl_multi *multi = data->multi; 2887 struct timeval *nowp = &data->state.expiretime; 2888 int rc; 2889 2890 /* this is only interesting while there is still an associated multi struct 2891 remaining! */ 2892 if(!multi) 2893 return; 2894 2895 if(!milli) { 2896 /* No timeout, clear the time data. */ 2897 if(nowp->tv_sec || nowp->tv_usec) { 2898 /* Since this is an cleared time, we must remove the previous entry from 2899 the splay tree */ 2900 struct curl_llist *list = data->state.timeoutlist; 2901 2902 rc = Curl_splayremovebyaddr(multi->timetree, 2903 &data->state.timenode, 2904 &multi->timetree); 2905 if(rc) 2906 infof(data, "Internal error clearing splay node = %d\n", rc); 2907 2908 /* flush the timeout list too */ 2909 while(list->size > 0) 2910 Curl_llist_remove(list, list->tail, NULL); 2911 2912#ifdef DEBUGBUILD 2913 infof(data, "Expire cleared\n"); 2914#endif 2915 nowp->tv_sec = 0; 2916 nowp->tv_usec = 0; 2917 } 2918 } 2919 else { 2920 struct timeval set; 2921 2922 set = Curl_tvnow(); 2923 set.tv_sec += milli/1000; 2924 set.tv_usec += (milli%1000)*1000; 2925 2926 if(set.tv_usec >= 1000000) { 2927 set.tv_sec++; 2928 set.tv_usec -= 1000000; 2929 } 2930 2931 if(nowp->tv_sec || nowp->tv_usec) { 2932 /* This means that the struct is added as a node in the splay tree. 2933 Compare if the new time is earlier, and only remove-old/add-new if it 2934 is. */ 2935 long diff = curlx_tvdiff(set, *nowp); 2936 if(diff > 0) { 2937 /* the new expire time was later so just add it to the queue 2938 and get out */ 2939 multi_addtimeout(data->state.timeoutlist, &set); 2940 return; 2941 } 2942 2943 /* the new time is newer than the presently set one, so add the current 2944 to the queue and update the head */ 2945 multi_addtimeout(data->state.timeoutlist, nowp); 2946 2947 /* Since this is an updated time, we must remove the previous entry from 2948 the splay tree first and then re-add the new value */ 2949 rc = Curl_splayremovebyaddr(multi->timetree, 2950 &data->state.timenode, 2951 &multi->timetree); 2952 if(rc) 2953 infof(data, "Internal error removing splay node = %d\n", rc); 2954 } 2955 2956 *nowp = set; 2957 data->state.timenode.payload = data; 2958 multi->timetree = Curl_splayinsert(*nowp, 2959 multi->timetree, 2960 &data->state.timenode); 2961 } 2962#if 0 2963 Curl_splayprint(multi->timetree, 0, TRUE); 2964#endif 2965} 2966 2967/* 2968 * Curl_expire_latest() 2969 * 2970 * This is like Curl_expire() but will only add a timeout node to the list of 2971 * timers if there is no timeout that will expire before the given time. 2972 * 2973 * Use this function if the code logic risks calling this function many times 2974 * or if there's no particular conditional wait in the code for this specific 2975 * time-out period to expire. 2976 * 2977 */ 2978void Curl_expire_latest(struct Curl_easy *data, long milli) 2979{ 2980 struct timeval *expire = &data->state.expiretime; 2981 2982 struct timeval set; 2983 2984 set = Curl_tvnow(); 2985 set.tv_sec += milli / 1000; 2986 set.tv_usec += (milli % 1000) * 1000; 2987 2988 if(set.tv_usec >= 1000000) { 2989 set.tv_sec++; 2990 set.tv_usec -= 1000000; 2991 } 2992 2993 if(expire->tv_sec || expire->tv_usec) { 2994 /* This means that the struct is added as a node in the splay tree. 2995 Compare if the new time is earlier, and only remove-old/add-new if it 2996 is. */ 2997 long diff = curlx_tvdiff(set, *expire); 2998 if(diff > 0) 2999 /* the new expire time was later than the top time, so just skip this */ 3000 return; 3001 } 3002 3003 /* Just add the timeout like normal */ 3004 Curl_expire(data, milli); 3005} 3006 3007CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, 3008 void *hashp) 3009{ 3010 struct Curl_sh_entry *there = NULL; 3011 3012 there = sh_getentry(&multi->sockhash, s); 3013 3014 if(!there) 3015 return CURLM_BAD_SOCKET; 3016 3017 there->socketp = hashp; 3018 3019 return CURLM_OK; 3020} 3021 3022size_t Curl_multi_max_host_connections(struct Curl_multi *multi) 3023{ 3024 return multi ? multi->max_host_connections : 0; 3025} 3026 3027size_t Curl_multi_max_total_connections(struct Curl_multi *multi) 3028{ 3029 return multi ? multi->max_total_connections : 0; 3030} 3031 3032curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi) 3033{ 3034 return multi ? multi->content_length_penalty_size : 0; 3035} 3036 3037curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi) 3038{ 3039 return multi ? multi->chunk_length_penalty_size : 0; 3040} 3041 3042struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi) 3043{ 3044 return multi->pipelining_site_bl; 3045} 3046 3047struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi) 3048{ 3049 return multi->pipelining_server_bl; 3050} 3051 3052void Curl_multi_process_pending_handles(struct Curl_multi *multi) 3053{ 3054 struct curl_llist_element *e = multi->pending->head; 3055 3056 while(e) { 3057 struct Curl_easy *data = e->ptr; 3058 struct curl_llist_element *next = e->next; 3059 3060 if(data->mstate == CURLM_STATE_CONNECT_PEND) { 3061 multistate(data, CURLM_STATE_CONNECT); 3062 3063 /* Remove this node from the list */ 3064 Curl_llist_remove(multi->pending, e, NULL); 3065 3066 /* Make sure that the handle will be processed soonish. */ 3067 Curl_expire_latest(data, 1); 3068 } 3069 3070 e = next; /* operate on next handle */ 3071 } 3072} 3073 3074#ifdef DEBUGBUILD 3075void Curl_multi_dump(struct Curl_multi *multi) 3076{ 3077 struct Curl_easy *data; 3078 int i; 3079 fprintf(stderr, "* Multi status: %d handles, %d alive\n", 3080 multi->num_easy, multi->num_alive); 3081 for(data=multi->easyp; data; data = data->next) { 3082 if(data->mstate < CURLM_STATE_COMPLETED) { 3083 /* only display handles that are not completed */ 3084 fprintf(stderr, "handle %p, state %s, %d sockets\n", 3085 (void *)data, 3086 statename[data->mstate], data->numsocks); 3087 for(i=0; i < data->numsocks; i++) { 3088 curl_socket_t s = data->sockets[i]; 3089 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); 3090 3091 fprintf(stderr, "%d ", (int)s); 3092 if(!entry) { 3093 fprintf(stderr, "INTERNAL CONFUSION\n"); 3094 continue; 3095 } 3096 fprintf(stderr, "[%s %s] ", 3097 entry->action&CURL_POLL_IN?"RECVING":"", 3098 entry->action&CURL_POLL_OUT?"SENDING":""); 3099 } 3100 if(data->numsocks) 3101 fprintf(stderr, "\n"); 3102 } 3103 } 3104} 3105#endif 3106