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