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