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