1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #include <curl/curl.h>
41 #include "speedcheck.h"
42 #include "conncache.h"
43 #include "multihandle.h"
46 #include "vtls/vtls.h"
48 #include "http_proxy.h"
49 /* The last 3 #include files should be in this order */
50 #include "curl_printf.h"
51 #include "curl_memory.h"
55 CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
56 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
57 CURL handle takes 45-50 K memory, therefore this 3K are not significant.
59 #ifndef CURL_SOCKET_HASH_TABLE_SIZE
60 #define CURL_SOCKET_HASH_TABLE_SIZE 911
63 #ifndef CURL_CONNECTION_HASH_SIZE
64 #define CURL_CONNECTION_HASH_SIZE 97
67 #define CURL_MULTI_HANDLE 0x000bab1e
69 #define GOOD_MULTI_HANDLE(x) \
70 ((x) && (x)->type == CURL_MULTI_HANDLE)
72 static CURLMcode singlesocket(struct Curl_multi *multi,
73 struct Curl_easy *data);
74 static int update_timer(struct Curl_multi *multi);
76 static CURLMcode add_next_timeout(struct curltime now,
77 struct Curl_multi *multi,
79 static CURLMcode multi_timeout(struct Curl_multi *multi,
81 static void process_pending_handles(struct Curl_multi *multi);
84 static const char * const statename[]={
107 /* function pointer called once when switching TO a state */
108 typedef void (*init_multistate_func)(struct Curl_easy *data);
110 static void Curl_init_completed(struct Curl_easy *data)
112 /* this is a completed transfer */
114 /* Important: reset the conn pointer so that we don't point to memory
115 that could be freed anytime */
116 data->easy_conn = NULL;
117 Curl_expire_clear(data); /* stop all timers */
120 /* always use this function to change state, to make debugging easier */
121 static void mstate(struct Curl_easy *data, CURLMstate state
127 CURLMstate oldstate = data->mstate;
128 static const init_multistate_func finit[CURLM_STATE_LAST] = {
130 NULL, /* CONNECT_PEND */
131 Curl_init_CONNECT, /* CONNECT */
132 NULL, /* WAITRESOLVE */
133 NULL, /* WAITCONNECT */
134 NULL, /* WAITPROXYCONNECT */
135 NULL, /* SENDPROTOCONNECT */
136 NULL, /* PROTOCONNECT */
138 Curl_connect_free, /* DO */
142 NULL, /* WAITPERFORM */
146 Curl_init_completed, /* COMPLETED */
150 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
154 if(oldstate == state)
155 /* don't bother when the new state is the same as the old state */
158 data->mstate = state;
160 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
161 if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
162 data->mstate < CURLM_STATE_COMPLETED) {
163 long connection_id = -5000;
166 connection_id = data->easy_conn->connection_id;
169 "STATE: %s => %s handle %p; line %d (connection #%ld)\n",
170 statename[oldstate], statename[data->mstate],
171 (void *)data, lineno, connection_id);
175 if(state == CURLM_STATE_COMPLETED)
176 /* changing to COMPLETED means there's one less easy handle 'alive' */
177 data->multi->num_alive--;
179 /* if this state has an init-function, run it */
185 #define multistate(x,y) mstate(x,y)
187 #define multistate(x,y) mstate(x,y, __LINE__)
191 * We add one of these structs to the sockhash for a particular socket
194 struct Curl_sh_entry {
195 struct Curl_easy *easy;
196 int action; /* what action READ/WRITE this socket waits for */
197 curl_socket_t socket; /* mainly to ease debugging */
198 void *socketp; /* settable by users with curl_multi_assign() */
200 /* bits for 'action' having no bits means this socket is not expecting any
205 /* look up a given socket in the socket hash, skip invalid sockets */
206 static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
209 if(s != CURL_SOCKET_BAD)
210 /* only look for proper sockets */
211 return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
215 /* make sure this socket is present in the hash for this handle */
216 static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
218 struct Curl_easy *data)
220 struct Curl_sh_entry *there = sh_getentry(sh, s);
221 struct Curl_sh_entry *check;
224 /* it is present, return fine */
227 /* not present, add it */
228 check = calloc(1, sizeof(struct Curl_sh_entry));
230 return NULL; /* major failure */
235 /* make/add new hash entry */
236 if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
238 return NULL; /* major failure */
241 return check; /* things are good in sockhash land */
245 /* delete the given socket + handle from the hash */
246 static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
248 /* We remove the hash entry. This will end up in a call to
250 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
254 * free a sockhash entry
256 static void sh_freeentry(void *freethis)
258 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
263 static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
265 (void) k1_len; (void) k2_len;
267 return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2));
270 static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
272 curl_socket_t fd = *((curl_socket_t *) key);
275 return (fd % slots_num);
279 * sh_init() creates a new socket hash and returns the handle for it.
281 * Quote from README.multi_socket:
283 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
284 * is somewhat of a bottle neck. Its current implementation may be a bit too
285 * limiting. It simply has a fixed-size array, and on each entry in the array
286 * it has a linked list with entries. So the hash only checks which list to
287 * scan through. The code I had used so for used a list with merely 7 slots
288 * (as that is what the DNS hash uses) but with 7000 connections that would
289 * make an average of 1000 nodes in each list to run through. I upped that to
290 * 97 slots (I believe a prime is suitable) and noticed a significant speed
291 * increase. I need to reconsider the hash implementation or use a rather
292 * large default value like this. At 9000 connections I was still below 10us
296 static int sh_init(struct curl_hash *hash, int hashsize)
298 return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
305 * Called when a transfer is completed. Adds the given msg pointer to
306 * the list kept in the multi handle.
308 static CURLMcode multi_addmsg(struct Curl_multi *multi,
309 struct Curl_message *msg)
311 Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg,
319 * Callback used by the llist system when a single list entry is destroyed.
321 static void multi_freeamsg(void *a, void *b)
327 struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
328 int chashsize) /* connection hash */
330 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
335 multi->type = CURL_MULTI_HANDLE;
337 if(Curl_mk_dnscache(&multi->hostcache))
340 if(sh_init(&multi->sockhash, hashsize))
343 if(Curl_conncache_init(&multi->conn_cache, chashsize))
346 Curl_llist_init(&multi->msglist, multi_freeamsg);
347 Curl_llist_init(&multi->pending, multi_freeamsg);
349 multi->max_pipeline_length = 5;
350 multi->pipelining = CURLPIPE_MULTIPLEX;
352 /* -1 means it not set by user, use the default value */
353 multi->maxconnects = -1;
358 Curl_hash_destroy(&multi->sockhash);
359 Curl_hash_destroy(&multi->hostcache);
360 Curl_conncache_destroy(&multi->conn_cache);
361 Curl_llist_destroy(&multi->msglist, NULL);
362 Curl_llist_destroy(&multi->pending, NULL);
368 struct Curl_multi *curl_multi_init(void)
370 return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
371 CURL_CONNECTION_HASH_SIZE);
374 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
375 struct Curl_easy *data)
377 /* First, make some basic checks that the CURLM handle is a good handle */
378 if(!GOOD_MULTI_HANDLE(multi))
379 return CURLM_BAD_HANDLE;
381 /* Verify that we got a somewhat good easy handle too */
382 if(!GOOD_EASY_HANDLE(data))
383 return CURLM_BAD_EASY_HANDLE;
385 /* Prevent users from adding same easy handle more than once and prevent
386 adding to more than one multi stack */
388 return CURLM_ADDED_ALREADY;
390 if(multi->in_callback)
391 return CURLM_RECURSIVE_API_CALL;
393 /* Initialize timeout list for this handle */
394 Curl_llist_init(&data->state.timeoutlist, NULL);
397 * No failure allowed in this function beyond this point. And no
398 * modification of easy nor multi handle allowed before this except for
399 * potential multi's connection cache growing which won't be undone in this
400 * function no matter what.
402 if(data->set.errorbuffer)
403 data->set.errorbuffer[0] = 0;
405 /* set the easy handle */
406 multistate(data, CURLM_STATE_INIT);
408 if((data->set.global_dns_cache) &&
409 (data->dns.hostcachetype != HCACHE_GLOBAL)) {
410 /* global dns cache was requested but still isn't */
411 struct curl_hash *global = Curl_global_host_cache_init();
413 /* only do this if the global cache init works */
414 data->dns.hostcache = global;
415 data->dns.hostcachetype = HCACHE_GLOBAL;
418 /* for multi interface connections, we share DNS cache automatically if the
419 easy handle's one is currently not set. */
420 else if(!data->dns.hostcache ||
421 (data->dns.hostcachetype == HCACHE_NONE)) {
422 data->dns.hostcache = &multi->hostcache;
423 data->dns.hostcachetype = HCACHE_MULTI;
426 /* Point to the shared or multi handle connection cache */
427 if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT)))
428 data->state.conn_cache = &data->share->conn_cache;
430 data->state.conn_cache = &multi->conn_cache;
433 /* Do the same for PSL. */
434 if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
435 data->psl = &data->share->psl;
437 data->psl = &multi->psl;
440 /* This adds the new entry at the 'end' of the doubly-linked circular
441 list of Curl_easy structs to try and maintain a FIFO queue so
442 the pipelined requests are in order. */
444 /* We add this new entry last in the list. */
446 data->next = NULL; /* end of the line */
448 struct Curl_easy *last = multi->easylp;
451 multi->easylp = data; /* the new last node */
454 /* first node, make prev NULL! */
456 multi->easylp = multi->easyp = data; /* both first and last */
459 /* make the Curl_easy refer back to this multi handle */
462 /* Set the timeout for this handle to expire really soon so that it will
463 be taken care of even when this handle is added in the midst of operation
464 when only the curl_multi_socket() API is used. During that flow, only
465 sockets that time-out or have actions will be dealt with. Since this
466 handle has no action yet, we make sure it times out to get things to
468 Curl_expire(data, 0, EXPIRE_RUN_NOW);
470 /* increase the node-counter */
473 /* increase the alive-counter */
476 /* A somewhat crude work-around for a little glitch in update_timer() that
477 happens if the lastcall time is set to the same time when the handle is
478 removed as when the next handle is added, as then the check in
479 update_timer() that prevents calling the application multiple times with
480 the same timer info will not trigger and then the new handle's timeout
481 will not be notified to the app.
483 The work-around is thus simply to clear the 'lastcall' variable to force
484 update_timer() to always trigger a callback to the app when a new easy
486 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
488 /* The closure handle only ever has default timeouts set. To improve the
489 state somewhat we clone the timeouts from each added handle so that the
490 closure handle always has the same timeouts as the most recently added
492 data->state.conn_cache->closure_handle->set.timeout = data->set.timeout;
493 data->state.conn_cache->closure_handle->set.server_response_timeout =
494 data->set.server_response_timeout;
495 data->state.conn_cache->closure_handle->set.no_signal =
503 /* Debug-function, used like this:
505 * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
507 * Enable the hash print function first by editing hash.c
509 static void debug_print_sock_hash(void *p)
511 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
513 fprintf(stderr, " [easy %p/magic %x/socket %d]",
514 (void *)sh->data, sh->data->magic, (int)sh->socket);
518 static CURLcode multi_done(struct connectdata **connp,
519 CURLcode status, /* an error if this is called
520 after an error was detected */
524 struct connectdata *conn;
525 struct Curl_easy *data;
533 DEBUGF(infof(data, "multi_done\n"));
536 /* Stop if multi_done() has already been called */
539 /* Stop the resolver and free its own resources (but not dns_entry yet). */
540 Curl_resolver_kill(conn);
542 Curl_getoff_all_pipelines(data, conn);
544 /* Cleanup possible redirect junk */
545 Curl_safefree(data->req.newurl);
546 Curl_safefree(data->req.location);
549 case CURLE_ABORTED_BY_CALLBACK:
550 case CURLE_READ_ERROR:
551 case CURLE_WRITE_ERROR:
552 /* When we're aborted due to a callback return code it basically have to
553 be counted as premature as there is trouble ahead if we don't. We have
554 many callbacks and protocols work differently, we could potentially do
555 this more fine-grained in the future. */
561 /* this calls the protocol-specific function pointer previously set */
562 if(conn->handler->done)
563 result = conn->handler->done(conn, status, premature);
567 if(CURLE_ABORTED_BY_CALLBACK != result) {
568 /* avoid this if we already aborted by callback to avoid this calling
570 CURLcode rc = Curl_pgrsDone(conn);
572 result = CURLE_ABORTED_BY_CALLBACK;
575 process_pending_handles(data->multi); /* connection / multiplex */
577 if(conn->send_pipe.size || conn->recv_pipe.size) {
578 /* Stop if pipeline is not empty . */
579 data->easy_conn = NULL;
580 DEBUGF(infof(data, "Connection still in use %zu/%zu, "
581 "no more multi_done now!\n",
582 conn->send_pipe.size, conn->recv_pipe.size));
586 data->state.done = TRUE; /* called just now! */
588 if(conn->dns_entry) {
589 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
590 conn->dns_entry = NULL;
592 Curl_hostcache_prune(data);
593 Curl_safefree(data->state.ulbuf);
595 /* if the transfer was completed in a paused state there can be buffered
597 for(i = 0; i < data->state.tempcount; i++) {
598 free(data->state.tempwrite[i].buf);
600 data->state.tempcount = 0;
602 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
603 forced us to close this connection. This is ignored for requests taking
604 place in a NTLM authentication handshake
606 if conn->bits.close is TRUE, it means that the connection should be
607 closed in spite of all our efforts to be nice, due to protocol
608 restrictions in our or the server's end
610 if premature is TRUE, it means this connection was said to be DONE before
611 the entire request operation is complete and thus we can't know in what
612 state it is for re-using, so we're forced to close it. In a perfect world
613 we can add code that keep track of if we really must close it here or not,
614 but currently we have no such detail knowledge.
617 if((data->set.reuse_forbid
618 #if defined(USE_NTLM)
619 && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
620 conn->proxyntlm.state == NTLMSTATE_TYPE2)
622 ) || conn->bits.close
623 || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
624 CURLcode res2 = Curl_disconnect(data, conn, premature);
626 /* If we had an error already, make sure we return that one. But
627 if we got a new error, return that. */
633 /* create string before returning the connection */
634 snprintf(buffer, sizeof(buffer),
635 "Connection #%ld to host %s left intact",
637 conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
638 conn->bits.httpproxy ? conn->http_proxy.host.dispname :
639 conn->bits.conn_to_host ? conn->conn_to_host.dispname :
640 conn->host.dispname);
642 /* the connection is no longer in use by this transfer */
643 if(Curl_conncache_return_conn(conn)) {
644 /* remember the most recently used connection */
645 data->state.lastconnect = conn;
646 infof(data, "%s\n", buffer);
649 data->state.lastconnect = NULL;
652 *connp = NULL; /* to make the caller of this function better detect that
653 this was either closed or handed over to the connection
654 cache here, and therefore cannot be used from this point on
656 Curl_free_request_state(data);
660 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
661 struct Curl_easy *data)
663 struct Curl_easy *easy = data;
666 struct curl_llist_element *e;
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;
672 /* Verify that we got a somewhat good easy handle too */
673 if(!GOOD_EASY_HANDLE(data))
674 return CURLM_BAD_EASY_HANDLE;
676 /* Prevent users from trying to remove same easy handle more than once */
678 return CURLM_OK; /* it is already removed so let's say it is fine! */
680 if(multi->in_callback)
681 return CURLM_RECURSIVE_API_CALL;
683 premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
684 easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
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. */
690 /* this handle is "alive" so we need to count down the total number of
691 alive connections when this is removed */
695 if(data->easy_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->easy_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
704 streamclose(data->easy_conn, "Removed with partial response");
705 easy_owns_conn = TRUE;
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);
713 if(data->easy_conn) {
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 */
719 /* multi_done() clears the conn->data field to lose the association
720 between the easy handle and the connection
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->easy_conn, data->result, premature);
727 /* Clear connection pipelines, if multi_done above was not called */
728 Curl_getoff_all_pipelines(data, data->easy_conn);
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);
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;
743 Curl_wildcard_dtor(&data->wildcard);
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);
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;
753 /* change state without using multistate(), only to make singlesocket() do
755 data->mstate = CURLM_STATE_COMPLETED;
756 singlesocket(multi, easy); /* to let the application know what sockets that
757 vanish with this handle */
759 /* Remove the association between the connection and the handle */
760 if(data->easy_conn) {
761 data->easy_conn->data = NULL;
762 data->easy_conn = NULL;
766 /* Remove the PSL association. */
767 if(data->psl == &multi->psl)
771 data->multi = NULL; /* clear the association to this multi handle */
773 /* make sure there's no pending message in the queue sent from this easy
776 for(e = multi->msglist.head; e; e = e->next) {
777 struct Curl_message *msg = e->ptr;
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 */
786 /* make the previous node point to our next */
788 data->prev->next = data->next;
790 multi->easyp = data->next; /* point to first node */
792 /* make our next point to our previous node */
794 data->next->prev = data->prev;
796 multi->easylp = data->prev; /* point to last node */
799 We do not touch the easy handle here! */
800 multi->num_easy--; /* one less to care about now */
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)
809 return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
812 void Curl_multi_handlePipeBreak(struct Curl_easy *data)
814 data->easy_conn = NULL;
817 static int waitconnect_getsock(struct connectdata *conn,
826 return GETSOCK_BLANK;
829 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
830 return Curl_ssl_getsock(conn, sock, numsocks);
833 for(i = 0; i<2; i++) {
834 if(conn->tempsock[i] != CURL_SOCKET_BAD) {
835 sock[s] = conn->tempsock[i];
836 rc |= GETSOCK_WRITESOCK(s++);
843 static int waitproxyconnect_getsock(struct connectdata *conn,
848 return GETSOCK_BLANK;
850 sock[0] = conn->sock[FIRSTSOCKET];
852 /* when we've sent a CONNECT to a proxy, we should rather wait for the
853 socket to become readable to be able to get the response headers */
854 if(conn->connect_state)
855 return GETSOCK_READSOCK(0);
857 return GETSOCK_WRITESOCK(0);
860 static int domore_getsock(struct connectdata *conn,
861 curl_socket_t *socks,
864 if(conn && conn->handler->domore_getsock)
865 return conn->handler->domore_getsock(conn, socks, numsocks);
866 return GETSOCK_BLANK;
869 /* returns bitmapped flags for this handle and its sockets */
870 static int multi_getsock(struct Curl_easy *data,
871 curl_socket_t *socks, /* points to numsocks number
875 /* The no connection case can happen when this is called from
876 curl_multi_remove_handle() => singlesocket() => multi_getsock().
881 if(data->mstate > CURLM_STATE_CONNECT &&
882 data->mstate < CURLM_STATE_COMPLETED) {
883 /* Set up ownership correctly */
884 data->easy_conn->data = data;
887 switch(data->mstate) {
889 #if 0 /* switch back on these cases to get the compiler to check for all enums
891 case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
892 case CURLM_STATE_COMPLETED:
893 case CURLM_STATE_MSGSENT:
894 case CURLM_STATE_INIT:
895 case CURLM_STATE_CONNECT:
896 case CURLM_STATE_WAITDO:
897 case CURLM_STATE_DONE:
898 case CURLM_STATE_LAST:
899 /* this will get called with CURLM_STATE_COMPLETED when a handle is
904 case CURLM_STATE_WAITRESOLVE:
905 return Curl_resolv_getsock(data->easy_conn, socks, numsocks);
907 case CURLM_STATE_PROTOCONNECT:
908 case CURLM_STATE_SENDPROTOCONNECT:
909 return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
912 case CURLM_STATE_DOING:
913 return Curl_doing_getsock(data->easy_conn, socks, numsocks);
915 case CURLM_STATE_WAITPROXYCONNECT:
916 return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
918 case CURLM_STATE_WAITCONNECT:
919 return waitconnect_getsock(data->easy_conn, socks, numsocks);
921 case CURLM_STATE_DO_MORE:
922 return domore_getsock(data->easy_conn, socks, numsocks);
924 case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
925 to waiting for the same as the *PERFORM
927 case CURLM_STATE_PERFORM:
928 case CURLM_STATE_WAITPERFORM:
929 return Curl_single_getsock(data->easy_conn, socks, numsocks);
934 CURLMcode curl_multi_fdset(struct Curl_multi *multi,
935 fd_set *read_fd_set, fd_set *write_fd_set,
936 fd_set *exc_fd_set, int *max_fd)
938 /* Scan through all the easy handles to get the file descriptors set.
939 Some easy handles may not have connected to the remote host yet,
940 and then we must make sure that is done. */
941 struct Curl_easy *data;
942 int this_max_fd = -1;
943 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
945 (void)exc_fd_set; /* not used */
947 if(!GOOD_MULTI_HANDLE(multi))
948 return CURLM_BAD_HANDLE;
950 if(multi->in_callback)
951 return CURLM_RECURSIVE_API_CALL;
955 int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
957 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
958 curl_socket_t s = CURL_SOCKET_BAD;
960 if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
961 FD_SET(sockbunch[i], read_fd_set);
964 if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
965 FD_SET(sockbunch[i], write_fd_set);
968 if(s == CURL_SOCKET_BAD)
969 /* this socket is unused, break out of loop */
971 if((int)s > this_max_fd)
972 this_max_fd = (int)s;
975 data = data->next; /* check next handle */
978 *max_fd = this_max_fd;
983 #define NUM_POLLS_ON_STACK 10
985 CURLMcode Curl_multi_wait(struct Curl_multi *multi,
986 struct curl_waitfd extra_fds[],
987 unsigned int extra_nfds,
990 bool *gotsocket) /* if any socket was checked */
992 struct Curl_easy *data;
993 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
996 unsigned int nfds = 0;
997 unsigned int curlfds;
998 struct pollfd *ufds = NULL;
999 bool ufds_malloc = FALSE;
1000 long timeout_internal;
1002 struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
1007 if(!GOOD_MULTI_HANDLE(multi))
1008 return CURLM_BAD_HANDLE;
1010 if(multi->in_callback)
1011 return CURLM_RECURSIVE_API_CALL;
1013 /* Count up how many fds we have from the multi handle */
1014 data = multi->easyp;
1016 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1018 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1019 curl_socket_t s = CURL_SOCKET_BAD;
1021 if(bitmap & GETSOCK_READSOCK(i)) {
1025 if(bitmap & GETSOCK_WRITESOCK(i)) {
1029 if(s == CURL_SOCKET_BAD) {
1034 data = data->next; /* check next handle */
1037 /* If the internally desired timeout is actually shorter than requested from
1038 the outside, then use the shorter time! But only if the internal timer
1039 is actually larger than -1! */
1040 (void)multi_timeout(multi, &timeout_internal);
1041 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
1042 timeout_ms = (int)timeout_internal;
1044 curlfds = nfds; /* number of internal file descriptors */
1045 nfds += extra_nfds; /* add the externally provided ones */
1048 if(nfds > NUM_POLLS_ON_STACK) {
1049 /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
1050 big, so at 2^29 sockets this value might wrap. When a process gets
1051 the capability to actually handle over 500 million sockets this
1052 calculation needs a integer overflow check. */
1053 ufds = malloc(nfds * sizeof(struct pollfd));
1055 return CURLM_OUT_OF_MEMORY;
1059 ufds = &a_few_on_stack[0];
1063 /* only do the second loop if we found descriptors in the first stage run
1067 /* Add the curl handles to our pollfds first */
1068 data = multi->easyp;
1070 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1072 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1073 curl_socket_t s = CURL_SOCKET_BAD;
1075 if(bitmap & GETSOCK_READSOCK(i)) {
1076 ufds[nfds].fd = sockbunch[i];
1077 ufds[nfds].events = POLLIN;
1081 if(bitmap & GETSOCK_WRITESOCK(i)) {
1082 ufds[nfds].fd = sockbunch[i];
1083 ufds[nfds].events = POLLOUT;
1087 if(s == CURL_SOCKET_BAD) {
1092 data = data->next; /* check next handle */
1096 /* Add external file descriptions from poll-like struct curl_waitfd */
1097 for(i = 0; i < extra_nfds; i++) {
1098 ufds[nfds].fd = extra_fds[i].fd;
1099 ufds[nfds].events = 0;
1100 if(extra_fds[i].events & CURL_WAIT_POLLIN)
1101 ufds[nfds].events |= POLLIN;
1102 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1103 ufds[nfds].events |= POLLPRI;
1104 if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1105 ufds[nfds].events |= POLLOUT;
1112 pollrc = Curl_poll(ufds, nfds, timeout_ms);
1116 /* copy revents results from the poll to the curl_multi_wait poll
1117 struct, the bit values of the actual underlying poll() implementation
1118 may not be the same as the ones in the public libcurl API! */
1119 for(i = 0; i < extra_nfds; i++) {
1120 unsigned short mask = 0;
1121 unsigned r = ufds[curlfds + i].revents;
1124 mask |= CURL_WAIT_POLLIN;
1126 mask |= CURL_WAIT_POLLOUT;
1128 mask |= CURL_WAIT_POLLPRI;
1130 extra_fds[i].revents = mask;
1139 if(gotsocket && (extra_fds || curlfds))
1140 /* if any socket was checked */
1146 CURLMcode curl_multi_wait(struct Curl_multi *multi,
1147 struct curl_waitfd extra_fds[],
1148 unsigned int extra_nfds,
1152 return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL);
1155 * Curl_multi_connchanged() is called to tell that there is a connection in
1156 * this multi handle that has changed state (pipelining become possible, the
1157 * number of allowed streams changed or similar), and a subsequent use of this
1158 * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1161 void Curl_multi_connchanged(struct Curl_multi *multi)
1163 multi->recheckstate = TRUE;
1167 * multi_ischanged() is called
1169 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1170 * => CONNECT action.
1172 * Set 'clear' to TRUE to have it also clear the state variable.
1174 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1176 bool retval = multi->recheckstate;
1178 multi->recheckstate = FALSE;
1182 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1183 struct Curl_easy *data,
1184 struct connectdata *conn)
1188 if(multi->in_callback)
1189 return CURLM_RECURSIVE_API_CALL;
1191 rc = curl_multi_add_handle(multi, data);
1193 struct SingleRequest *k = &data->req;
1195 /* pass in NULL for 'conn' here since we don't want to init the
1196 connection, only this transfer */
1197 Curl_init_do(data, NULL);
1199 /* take this handle to the perform state right away */
1200 multistate(data, CURLM_STATE_PERFORM);
1201 data->easy_conn = conn;
1202 k->keepon |= KEEP_RECV; /* setup to receive! */
1207 static CURLcode multi_reconnect_request(struct connectdata **connp)
1209 CURLcode result = CURLE_OK;
1210 struct connectdata *conn = *connp;
1211 struct Curl_easy *data = conn->data;
1213 /* This was a re-use of a connection and we got a write error in the
1214 * DO-phase. Then we DISCONNECT this connection and have another attempt to
1215 * CONNECT and then DO again! The retry cannot possibly find another
1216 * connection to re-use, since we only keep one possible connection for
1219 infof(data, "Re-used connection seems dead, get a new one\n");
1221 connclose(conn, "Reconnect dead connection"); /* enforce close */
1222 result = multi_done(&conn, result, FALSE); /* we are so done with this */
1224 /* conn may no longer be a good pointer, clear it to avoid mistakes by
1229 * We need to check for CURLE_SEND_ERROR here as well. This could happen
1230 * when the request failed on a FTP connection and thus multi_done() itself
1231 * tried to use the connection (again).
1233 if(!result || (CURLE_SEND_ERROR == result)) {
1235 bool protocol_done = TRUE;
1237 /* Now, redo the connect and get a new connection */
1238 result = Curl_connect(data, connp, &async, &protocol_done);
1240 /* We have connected or sent away a name resolve query fine */
1242 conn = *connp; /* setup conn to again point to something nice */
1244 /* Now, if async is TRUE here, we need to wait for the name
1246 result = Curl_resolver_wait_resolv(conn, NULL);
1250 /* Resolved, continue with the connection */
1251 result = Curl_once_resolved(conn, &protocol_done);
1262 * do_complete is called when the DO actions are complete.
1264 * We init chunking and trailer bits to their default values here immediately
1265 * before receiving any header data for the current request in the pipeline.
1267 static void do_complete(struct connectdata *conn)
1269 conn->data->req.chunk = FALSE;
1270 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
1271 conn->sockfd:conn->writesockfd) + 1;
1272 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
1275 static CURLcode multi_do(struct connectdata **connp, bool *done)
1277 CURLcode result = CURLE_OK;
1278 struct connectdata *conn = *connp;
1279 struct Curl_easy *data = conn->data;
1281 if(conn->handler->do_it) {
1282 /* generic protocol-specific function pointer set in curl_connect() */
1283 result = conn->handler->do_it(conn, done);
1285 /* This was formerly done in transfer.c, but we better do it here */
1286 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
1288 * If the connection is using an easy handle, call reconnect
1289 * to re-establish the connection. Otherwise, let the multi logic
1290 * figure out how to re-establish the connection.
1293 result = multi_reconnect_request(connp);
1296 /* ... finally back to actually retry the DO phase */
1297 conn = *connp; /* re-assign conn since multi_reconnect_request
1298 creates a new connection */
1299 result = conn->handler->do_it(conn, done);
1306 if(!result && *done)
1307 /* do_complete must be called after the protocol-specific DO function */
1314 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1315 * second stage DO state which (wrongly) was introduced to support FTP's
1316 * second connection.
1318 * TODO: A future libcurl should be able to work away this state.
1320 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1321 * DOING state there's more work to do!
1324 static CURLcode multi_do_more(struct connectdata *conn, int *complete)
1326 CURLcode result = CURLE_OK;
1330 if(conn->handler->do_more)
1331 result = conn->handler->do_more(conn, complete);
1333 if(!result && (*complete == 1))
1334 /* do_complete must be called after the protocol-specific DO function */
1340 static CURLMcode multi_runsingle(struct Curl_multi *multi,
1341 struct curltime now,
1342 struct Curl_easy *data)
1344 struct Curl_message *msg = NULL;
1347 bool protocol_connect = FALSE;
1348 bool dophase_done = FALSE;
1351 CURLcode result = CURLE_OK;
1352 struct SingleRequest *k;
1354 time_t recv_timeout_ms;
1355 timediff_t send_timeout_ms;
1358 if(!GOOD_EASY_HANDLE(data))
1359 return CURLM_BAD_EASY_HANDLE;
1362 /* A "stream" here is a logical stream if the protocol can handle that
1363 (HTTP/2), or the full connection for older protocols */
1364 bool stream_error = FALSE;
1367 if(!data->easy_conn &&
1368 data->mstate > CURLM_STATE_CONNECT &&
1369 data->mstate < CURLM_STATE_DONE) {
1370 /* In all these states, the code will blindly access 'data->easy_conn'
1371 so this is precaution that it isn't NULL. And it silences static
1373 failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
1374 return CURLM_INTERNAL_ERROR;
1377 if(multi_ischanged(multi, TRUE)) {
1378 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
1379 process_pending_handles(multi); /* pipelined/multiplexed */
1382 if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
1383 data->mstate < CURLM_STATE_COMPLETED) {
1384 /* Make sure we set the connection's current owner */
1385 data->easy_conn->data = data;
1388 if(data->easy_conn &&
1389 (data->mstate >= CURLM_STATE_CONNECT) &&
1390 (data->mstate < CURLM_STATE_COMPLETED)) {
1391 /* we need to wait for the connect state as only then is the start time
1392 stored, but we must not check already completed handles */
1393 timeout_ms = Curl_timeleft(data, &now,
1394 (data->mstate <= CURLM_STATE_WAITDO)?
1397 if(timeout_ms < 0) {
1398 /* Handle timed out */
1399 if(data->mstate == CURLM_STATE_WAITRESOLVE)
1400 failf(data, "Resolving timed out after %ld milliseconds",
1401 Curl_timediff(now, data->progress.t_startsingle));
1402 else if(data->mstate == CURLM_STATE_WAITCONNECT)
1403 failf(data, "Connection timed out after %ld milliseconds",
1404 Curl_timediff(now, data->progress.t_startsingle));
1408 failf(data, "Operation timed out after %ld milliseconds with %"
1409 CURL_FORMAT_CURL_OFF_T " out of %"
1410 CURL_FORMAT_CURL_OFF_T " bytes received",
1411 Curl_timediff(now, data->progress.t_startsingle),
1412 k->bytecount, k->size);
1415 failf(data, "Operation timed out after %ld milliseconds with %"
1416 CURL_FORMAT_CURL_OFF_T " bytes received",
1417 Curl_timediff(now, data->progress.t_startsingle),
1422 /* Force connection closed if the connection has indeed been used */
1423 if(data->mstate > CURLM_STATE_DO) {
1424 streamclose(data->easy_conn, "Disconnected with pending data");
1425 stream_error = TRUE;
1427 result = CURLE_OPERATION_TIMEDOUT;
1428 (void)multi_done(&data->easy_conn, result, TRUE);
1429 /* Skip the statemachine and go directly to error handling section. */
1430 goto statemachine_end;
1434 switch(data->mstate) {
1435 case CURLM_STATE_INIT:
1436 /* init this transfer. */
1437 result = Curl_pretransfer(data);
1440 /* after init, go CONNECT */
1441 multistate(data, CURLM_STATE_CONNECT);
1442 Curl_pgrsTime(data, TIMER_STARTOP);
1443 rc = CURLM_CALL_MULTI_PERFORM;
1447 case CURLM_STATE_CONNECT_PEND:
1448 /* We will stay here until there is a connection available. Then
1449 we try again in the CURLM_STATE_CONNECT state. */
1452 case CURLM_STATE_CONNECT:
1453 /* Connect. We want to get a connection identifier filled in. */
1454 Curl_pgrsTime(data, TIMER_STARTSINGLE);
1455 result = Curl_connect(data, &data->easy_conn,
1456 &async, &protocol_connect);
1457 if(CURLE_NO_CONNECTION_AVAILABLE == result) {
1458 /* There was no connection available. We will go to the pending
1459 state and wait for an available connection. */
1460 multistate(data, CURLM_STATE_CONNECT_PEND);
1462 /* add this handle to the list of connect-pending handles */
1463 Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
1464 &data->connect_queue);
1470 /* Add this handle to the send or pend pipeline */
1471 result = Curl_add_handle_to_pipeline(data, data->easy_conn);
1473 stream_error = TRUE;
1476 /* We're now waiting for an asynchronous name lookup */
1477 multistate(data, CURLM_STATE_WAITRESOLVE);
1479 /* after the connect has been sent off, go WAITCONNECT unless the
1480 protocol connect is already done and we can go directly to
1482 rc = CURLM_CALL_MULTI_PERFORM;
1484 if(protocol_connect)
1485 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1486 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1488 #ifndef CURL_DISABLE_HTTP
1489 if(Curl_connect_ongoing(data->easy_conn))
1490 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1493 multistate(data, CURLM_STATE_WAITCONNECT);
1500 case CURLM_STATE_WAITRESOLVE:
1501 /* awaiting an asynch name resolve to complete */
1503 struct Curl_dns_entry *dns = NULL;
1504 struct connectdata *conn = data->easy_conn;
1505 const char *hostname;
1507 if(conn->bits.httpproxy)
1508 hostname = conn->http_proxy.host.name;
1509 else if(conn->bits.conn_to_host)
1510 hostname = conn->conn_to_host.name;
1512 hostname = conn->host.name;
1514 /* check if we have the name resolved by now */
1515 dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
1518 #ifdef CURLRES_ASYNCH
1519 conn->async.dns = dns;
1520 conn->async.done = TRUE;
1523 infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
1527 result = Curl_resolv_check(data->easy_conn, &dns);
1529 /* Update sockets here, because the socket(s) may have been
1530 closed and the application thus needs to be told, even if it
1531 is likely that the same socket(s) will again be used further
1532 down. If the name has not yet been resolved, it is likely
1533 that new sockets have been opened in an attempt to contact
1534 another resolver. */
1535 singlesocket(multi, data);
1538 /* Perform the next step in the connection phase, and then move on
1539 to the WAITCONNECT state */
1540 result = Curl_once_resolved(data->easy_conn, &protocol_connect);
1543 /* if Curl_once_resolved() returns failure, the connection struct
1544 is already freed and gone */
1545 data->easy_conn = NULL; /* no more connection */
1547 /* call again please so that we get the next socket setup */
1548 rc = CURLM_CALL_MULTI_PERFORM;
1549 if(protocol_connect)
1550 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1551 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1553 #ifndef CURL_DISABLE_HTTP
1554 if(Curl_connect_ongoing(data->easy_conn))
1555 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1558 multistate(data, CURLM_STATE_WAITCONNECT);
1564 /* failure detected */
1565 stream_error = TRUE;
1571 #ifndef CURL_DISABLE_HTTP
1572 case CURLM_STATE_WAITPROXYCONNECT:
1573 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
1574 result = Curl_http_connect(data->easy_conn, &protocol_connect);
1576 if(data->easy_conn->bits.proxy_connect_closed) {
1577 rc = CURLM_CALL_MULTI_PERFORM;
1578 /* connect back to proxy again */
1580 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1581 multistate(data, CURLM_STATE_CONNECT);
1584 if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
1585 data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
1586 Curl_connect_complete(data->easy_conn)) {
1587 rc = CURLM_CALL_MULTI_PERFORM;
1588 /* initiate protocol connect phase */
1589 multistate(data, CURLM_STATE_SENDPROTOCONNECT);
1593 stream_error = TRUE;
1597 case CURLM_STATE_WAITCONNECT:
1598 /* awaiting a completion of an asynch TCP connect */
1599 result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
1600 if(connected && !result) {
1601 #ifndef CURL_DISABLE_HTTP
1602 if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
1603 !data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
1604 Curl_connect_ongoing(data->easy_conn)) {
1605 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1609 rc = CURLM_CALL_MULTI_PERFORM;
1610 multistate(data, data->easy_conn->bits.tunnel_proxy?
1611 CURLM_STATE_WAITPROXYCONNECT:
1612 CURLM_STATE_SENDPROTOCONNECT);
1615 /* failure detected */
1616 /* Just break, the cleaning up is handled all in one place */
1617 stream_error = TRUE;
1622 case CURLM_STATE_SENDPROTOCONNECT:
1623 result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
1624 if(!result && !protocol_connect)
1625 /* switch to waiting state */
1626 multistate(data, CURLM_STATE_PROTOCONNECT);
1628 /* protocol connect has completed, go WAITDO or DO */
1629 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1630 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1631 rc = CURLM_CALL_MULTI_PERFORM;
1634 /* failure detected */
1635 Curl_posttransfer(data);
1636 multi_done(&data->easy_conn, result, TRUE);
1637 stream_error = TRUE;
1641 case CURLM_STATE_PROTOCONNECT:
1642 /* protocol-specific connect phase */
1643 result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
1644 if(!result && protocol_connect) {
1645 /* after the connect has completed, go WAITDO or DO */
1646 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1647 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1648 rc = CURLM_CALL_MULTI_PERFORM;
1651 /* failure detected */
1652 Curl_posttransfer(data);
1653 multi_done(&data->easy_conn, result, TRUE);
1654 stream_error = TRUE;
1658 case CURLM_STATE_WAITDO:
1659 /* Wait for our turn to DO when we're pipelining requests */
1660 if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
1661 /* Grabbed the channel */
1662 multistate(data, CURLM_STATE_DO);
1663 rc = CURLM_CALL_MULTI_PERFORM;
1667 case CURLM_STATE_DO:
1668 if(data->set.connect_only) {
1669 /* keep connection open for application to use the socket */
1670 connkeep(data->easy_conn, "CONNECT_ONLY");
1671 multistate(data, CURLM_STATE_DONE);
1673 rc = CURLM_CALL_MULTI_PERFORM;
1676 /* Perform the protocol's DO action */
1677 result = multi_do(&data->easy_conn, &dophase_done);
1679 /* When multi_do() returns failure, data->easy_conn might be NULL! */
1683 /* some steps needed for wildcard matching */
1684 if(data->state.wildcardmatch) {
1685 struct WildcardData *wc = &data->wildcard;
1686 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
1687 /* skip some states if it is important */
1688 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1689 multistate(data, CURLM_STATE_DONE);
1690 rc = CURLM_CALL_MULTI_PERFORM;
1694 /* DO was not completed in one function call, we must continue
1696 multistate(data, CURLM_STATE_DOING);
1700 /* after DO, go DO_DONE... or DO_MORE */
1701 else if(data->easy_conn->bits.do_more) {
1702 /* we're supposed to do more, but we need to sit down, relax
1703 and wait a little while first */
1704 multistate(data, CURLM_STATE_DO_MORE);
1708 /* we're done with the DO, now DO_DONE */
1709 multistate(data, CURLM_STATE_DO_DONE);
1710 rc = CURLM_CALL_MULTI_PERFORM;
1713 else if((CURLE_SEND_ERROR == result) &&
1714 data->easy_conn->bits.reuse) {
1716 * In this situation, a connection that we were trying to use
1717 * may have unexpectedly died. If possible, send the connection
1718 * back to the CONNECT phase so we can try again.
1720 char *newurl = NULL;
1721 followtype follow = FOLLOW_NONE;
1724 drc = Curl_retry_request(data->easy_conn, &newurl);
1726 /* a failure here pretty much implies an out of memory */
1728 stream_error = TRUE;
1731 Curl_posttransfer(data);
1732 drc = multi_done(&data->easy_conn, result, FALSE);
1734 /* When set to retry the connection, we must to go back to
1735 * the CONNECT state */
1737 if(!drc || (drc == CURLE_SEND_ERROR)) {
1738 follow = FOLLOW_RETRY;
1739 drc = Curl_follow(data, newurl, follow);
1741 multistate(data, CURLM_STATE_CONNECT);
1742 rc = CURLM_CALL_MULTI_PERFORM;
1751 /* done didn't return OK or SEND_ERROR */
1756 /* Have error handler disconnect conn if we can't retry */
1757 stream_error = TRUE;
1762 /* failure detected */
1763 Curl_posttransfer(data);
1765 multi_done(&data->easy_conn, result, FALSE);
1766 stream_error = TRUE;
1771 case CURLM_STATE_DOING:
1772 /* we continue DOING until the DO phase is complete */
1773 result = Curl_protocol_doing(data->easy_conn,
1777 /* after DO, go DO_DONE or DO_MORE */
1778 multistate(data, data->easy_conn->bits.do_more?
1779 CURLM_STATE_DO_MORE:
1780 CURLM_STATE_DO_DONE);
1781 rc = CURLM_CALL_MULTI_PERFORM;
1782 } /* dophase_done */
1785 /* failure detected */
1786 Curl_posttransfer(data);
1787 multi_done(&data->easy_conn, result, FALSE);
1788 stream_error = TRUE;
1792 case CURLM_STATE_DO_MORE:
1794 * When we are connected, DO MORE and then go DO_DONE
1796 result = multi_do_more(data->easy_conn, &control);
1798 /* No need to remove this handle from the send pipeline here since that
1799 is done in multi_done() */
1802 /* if positive, advance to DO_DONE
1803 if negative, go back to DOING */
1804 multistate(data, control == 1?
1805 CURLM_STATE_DO_DONE:
1807 rc = CURLM_CALL_MULTI_PERFORM;
1810 /* stay in DO_MORE */
1814 /* failure detected */
1815 Curl_posttransfer(data);
1816 multi_done(&data->easy_conn, result, FALSE);
1817 stream_error = TRUE;
1821 case CURLM_STATE_DO_DONE:
1822 /* Move ourselves from the send to recv pipeline */
1823 Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
1825 if(data->easy_conn->bits.multiplex || data->easy_conn->send_pipe.size)
1826 /* Check if we can move pending requests to send pipe */
1827 process_pending_handles(multi); /* pipelined/multiplexed */
1829 /* Only perform the transfer if there's a good socket to work with.
1830 Having both BAD is a signal to skip immediately to DONE */
1831 if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
1832 (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
1833 multistate(data, CURLM_STATE_WAITPERFORM);
1835 if(data->state.wildcardmatch &&
1836 ((data->easy_conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
1837 data->wildcard.state = CURLWC_DONE;
1839 multistate(data, CURLM_STATE_DONE);
1841 rc = CURLM_CALL_MULTI_PERFORM;
1844 case CURLM_STATE_WAITPERFORM:
1845 /* Wait for our turn to PERFORM */
1846 if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
1847 /* Grabbed the channel */
1848 multistate(data, CURLM_STATE_PERFORM);
1849 rc = CURLM_CALL_MULTI_PERFORM;
1853 case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1854 /* if both rates are within spec, resume transfer */
1855 if(Curl_pgrsUpdate(data->easy_conn))
1856 result = CURLE_ABORTED_BY_CALLBACK;
1858 result = Curl_speedcheck(data, now);
1861 send_timeout_ms = 0;
1862 if(data->set.max_send_speed > 0)
1864 Curl_pgrsLimitWaitTime(data->progress.uploaded,
1865 data->progress.ul_limit_size,
1866 data->set.max_send_speed,
1867 data->progress.ul_limit_start,
1870 recv_timeout_ms = 0;
1871 if(data->set.max_recv_speed > 0)
1873 Curl_pgrsLimitWaitTime(data->progress.downloaded,
1874 data->progress.dl_limit_size,
1875 data->set.max_recv_speed,
1876 data->progress.dl_limit_start,
1879 if(!send_timeout_ms && !recv_timeout_ms) {
1880 multistate(data, CURLM_STATE_PERFORM);
1881 Curl_ratelimit(data, now);
1883 else if(send_timeout_ms >= recv_timeout_ms)
1884 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
1886 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
1890 case CURLM_STATE_PERFORM:
1892 char *newurl = NULL;
1894 bool comeback = FALSE;
1896 /* check if over send speed */
1897 send_timeout_ms = 0;
1898 if(data->set.max_send_speed > 0)
1899 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
1900 data->progress.ul_limit_size,
1901 data->set.max_send_speed,
1902 data->progress.ul_limit_start,
1905 /* check if over recv speed */
1906 recv_timeout_ms = 0;
1907 if(data->set.max_recv_speed > 0)
1908 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
1909 data->progress.dl_limit_size,
1910 data->set.max_recv_speed,
1911 data->progress.dl_limit_start,
1914 if(send_timeout_ms || recv_timeout_ms) {
1915 Curl_ratelimit(data, now);
1916 multistate(data, CURLM_STATE_TOOFAST);
1917 if(send_timeout_ms >= recv_timeout_ms)
1918 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
1920 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
1924 /* read/write data if it is ready to do so */
1925 result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
1929 if(!(k->keepon & KEEP_RECV))
1930 /* We're done receiving */
1931 Curl_pipeline_leave_read(data->easy_conn);
1933 if(!(k->keepon & KEEP_SEND))
1934 /* We're done sending */
1935 Curl_pipeline_leave_write(data->easy_conn);
1937 if(done || (result == CURLE_RECV_ERROR)) {
1938 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
1939 * condition and the server closed the re-used connection exactly when
1940 * we wanted to use it, so figure out if that is indeed the case.
1942 CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
1944 retry = (newurl)?TRUE:FALSE;
1949 /* if we are to retry, set the result to OK and consider the
1958 * The transfer phase returned error, we mark the connection to get
1959 * closed to prevent being re-used. This is because we can't possibly
1960 * know if the connection is in a good shape or not now. Unless it is
1961 * a protocol which uses two "channels" like FTP, as then the error
1962 * happened in the data connection.
1965 if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
1966 result != CURLE_HTTP2_STREAM)
1967 streamclose(data->easy_conn, "Transfer returned error");
1969 Curl_posttransfer(data);
1970 multi_done(&data->easy_conn, result, TRUE);
1973 followtype follow = FOLLOW_NONE;
1975 /* call this even if the readwrite function returned error */
1976 Curl_posttransfer(data);
1978 /* we're no longer receiving */
1979 Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
1981 /* expire the new receiving pipeline head */
1982 if(data->easy_conn->recv_pipe.head)
1983 Curl_expire(data->easy_conn->recv_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
1985 /* When we follow redirects or is set to retry the connection, we must
1986 to go back to the CONNECT state */
1987 if(data->req.newurl || retry) {
1989 /* if the URL is a follow-location and not just a retried request
1990 then figure out the URL here */
1992 newurl = data->req.newurl;
1993 data->req.newurl = NULL;
1994 follow = FOLLOW_REDIR;
1997 follow = FOLLOW_RETRY;
1998 result = multi_done(&data->easy_conn, CURLE_OK, FALSE);
2000 result = Curl_follow(data, newurl, follow);
2002 multistate(data, CURLM_STATE_CONNECT);
2003 rc = CURLM_CALL_MULTI_PERFORM;
2009 /* after the transfer is done, go DONE */
2011 /* but first check to see if we got a location info even though we're
2012 not following redirects */
2013 if(data->req.location) {
2015 newurl = data->req.location;
2016 data->req.location = NULL;
2017 result = Curl_follow(data, newurl, FOLLOW_FAKE);
2020 stream_error = TRUE;
2021 result = multi_done(&data->easy_conn, result, TRUE);
2026 multistate(data, CURLM_STATE_DONE);
2027 rc = CURLM_CALL_MULTI_PERFORM;
2032 rc = CURLM_CALL_MULTI_PERFORM;
2036 case CURLM_STATE_DONE:
2037 /* this state is highly transient, so run another loop after this */
2038 rc = CURLM_CALL_MULTI_PERFORM;
2040 if(data->easy_conn) {
2043 /* Remove ourselves from the receive pipeline, if we are there. */
2044 Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
2046 if(data->easy_conn->bits.multiplex || data->easy_conn->send_pipe.size)
2047 /* Check if we can move pending requests to connection */
2048 process_pending_handles(multi); /* pipelined/multiplexing */
2050 /* post-transfer command */
2051 res = multi_done(&data->easy_conn, result, FALSE);
2053 /* allow a previously set error code take precedence */
2058 * If there are other handles on the pipeline, multi_done won't set
2059 * easy_conn to NULL. In such a case, curl_multi_remove_handle() can
2060 * access free'd data, if the connection is free'd and the handle
2061 * removed before we perform the processing in CURLM_STATE_COMPLETED
2064 data->easy_conn = NULL;
2067 if(data->state.wildcardmatch) {
2068 if(data->wildcard.state != CURLWC_DONE) {
2069 /* if a wildcard is set and we are not ending -> lets start again
2070 with CURLM_STATE_INIT */
2071 multistate(data, CURLM_STATE_INIT);
2076 /* after we have DONE what we're supposed to do, go COMPLETED, and
2077 it doesn't matter what the multi_done() returned! */
2078 multistate(data, CURLM_STATE_COMPLETED);
2081 case CURLM_STATE_COMPLETED:
2084 case CURLM_STATE_MSGSENT:
2085 data->result = result;
2086 return CURLM_OK; /* do nothing */
2089 return CURLM_INTERNAL_ERROR;
2093 if(data->mstate < CURLM_STATE_COMPLETED) {
2096 * If an error was returned, and we aren't in completed state now,
2097 * then we go to completed and consider this transfer aborted.
2100 /* NOTE: no attempt to disconnect connections must be made
2101 in the case blocks above - cleanup happens only here */
2103 /* Check if we can move pending requests to send pipe */
2104 process_pending_handles(multi); /* connection */
2106 if(data->easy_conn) {
2107 /* if this has a connection, unsubscribe from the pipelines */
2108 Curl_pipeline_leave_write(data->easy_conn);
2109 Curl_pipeline_leave_read(data->easy_conn);
2110 Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
2111 Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
2114 /* Don't attempt to send data over a connection that timed out */
2115 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2116 /* disconnect properly */
2117 Curl_disconnect(data, data->easy_conn, dead_connection);
2119 /* This is where we make sure that the easy_conn pointer is reset.
2120 We don't have to do this in every case block above where a
2121 failure is detected */
2122 data->easy_conn = NULL;
2125 else if(data->mstate == CURLM_STATE_CONNECT) {
2126 /* Curl_connect() failed */
2127 (void)Curl_posttransfer(data);
2130 multistate(data, CURLM_STATE_COMPLETED);
2131 rc = CURLM_CALL_MULTI_PERFORM;
2133 /* if there's still a connection to use, call the progress function */
2134 else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
2135 /* aborted due to progress callback return code must close the
2137 result = CURLE_ABORTED_BY_CALLBACK;
2138 streamclose(data->easy_conn, "Aborted by callback");
2140 /* if not yet in DONE state, go there, otherwise COMPLETED */
2141 multistate(data, (data->mstate < CURLM_STATE_DONE)?
2142 CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
2143 rc = CURLM_CALL_MULTI_PERFORM;
2147 if(CURLM_STATE_COMPLETED == data->mstate) {
2148 if(data->set.fmultidone) {
2149 /* signal via callback instead */
2150 data->set.fmultidone(data, result);
2153 /* now fill in the Curl_message with this info */
2156 msg->extmsg.msg = CURLMSG_DONE;
2157 msg->extmsg.easy_handle = data;
2158 msg->extmsg.data.result = result;
2160 rc = multi_addmsg(multi, msg);
2161 DEBUGASSERT(!data->easy_conn);
2163 multistate(data, CURLM_STATE_MSGSENT);
2165 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2167 data->result = result;
2172 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
2174 struct Curl_easy *data;
2175 CURLMcode returncode = CURLM_OK;
2176 struct Curl_tree *t;
2177 struct curltime now = Curl_now();
2179 if(!GOOD_MULTI_HANDLE(multi))
2180 return CURLM_BAD_HANDLE;
2182 if(multi->in_callback)
2183 return CURLM_RECURSIVE_API_CALL;
2185 data = multi->easyp;
2188 SIGPIPE_VARIABLE(pipe_st);
2190 sigpipe_ignore(data, &pipe_st);
2191 result = multi_runsingle(multi, now, data);
2192 sigpipe_restore(&pipe_st);
2195 returncode = result;
2197 data = data->next; /* operate on next handle */
2201 * Simply remove all expired timers from the splay since handles are dealt
2202 * with unconditionally by this function and curl_multi_timeout() requires
2203 * that already passed/handled expire times are removed from the splay.
2205 * It is important that the 'now' value is set at the entry of this function
2206 * and not for the current time as it may have ticked a little while since
2207 * then and then we risk this loop to remove timers that actually have not
2211 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2213 /* the removed may have another timeout in queue */
2214 (void)add_next_timeout(now, multi, t->payload);
2218 *running_handles = multi->num_alive;
2220 if(CURLM_OK >= returncode)
2221 update_timer(multi);
2226 CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
2228 struct Curl_easy *data;
2229 struct Curl_easy *nextdata;
2231 if(GOOD_MULTI_HANDLE(multi)) {
2232 if(multi->in_callback)
2233 return CURLM_RECURSIVE_API_CALL;
2235 multi->type = 0; /* not good anymore */
2237 /* Firsrt remove all remaining easy handles */
2238 data = multi->easyp;
2240 nextdata = data->next;
2241 if(!data->state.done && data->easy_conn)
2242 /* if DONE was never called for this handle */
2243 (void)multi_done(&data->easy_conn, CURLE_OK, TRUE);
2244 if(data->dns.hostcachetype == HCACHE_MULTI) {
2245 /* clear out the usage of the shared DNS cache */
2246 Curl_hostcache_clean(data, data->dns.hostcache);
2247 data->dns.hostcache = NULL;
2248 data->dns.hostcachetype = HCACHE_NONE;
2251 /* Clear the pointer to the connection cache */
2252 data->state.conn_cache = NULL;
2253 data->multi = NULL; /* clear the association */
2256 if(data->psl == &multi->psl)
2263 /* Close all the connections in the connection cache */
2264 Curl_conncache_close_all_connections(&multi->conn_cache);
2266 Curl_hash_destroy(&multi->sockhash);
2267 Curl_conncache_destroy(&multi->conn_cache);
2268 Curl_llist_destroy(&multi->msglist, NULL);
2269 Curl_llist_destroy(&multi->pending, NULL);
2271 Curl_hash_destroy(&multi->hostcache);
2272 Curl_psl_destroy(&multi->psl);
2274 /* Free the blacklists by setting them to NULL */
2275 Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
2276 Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
2282 return CURLM_BAD_HANDLE;
2286 * curl_multi_info_read()
2288 * This function is the primary way for a multi/multi_socket application to
2289 * figure out if a transfer has ended. We MUST make this function as fast as
2290 * possible as it will be polled frequently and we MUST NOT scan any lists in
2291 * here to figure out things. We must scale fine to thousands of handles and
2292 * beyond. The current design is fully O(1).
2295 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
2297 struct Curl_message *msg;
2299 *msgs_in_queue = 0; /* default to none */
2301 if(GOOD_MULTI_HANDLE(multi) &&
2302 !multi->in_callback &&
2303 Curl_llist_count(&multi->msglist)) {
2304 /* there is one or more messages in the list */
2305 struct curl_llist_element *e;
2307 /* extract the head of the list to return */
2308 e = multi->msglist.head;
2312 /* remove the extracted entry */
2313 Curl_llist_remove(&multi->msglist, e, NULL);
2315 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
2317 return &msg->extmsg;
2323 * singlesocket() checks what sockets we deal with and their "action state"
2324 * and if we have a different state in any of those sockets from last time we
2325 * call the callback accordingly.
2327 static CURLMcode singlesocket(struct Curl_multi *multi,
2328 struct Curl_easy *data)
2330 curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
2332 struct Curl_sh_entry *entry;
2335 unsigned int curraction;
2337 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
2338 socks[i] = CURL_SOCKET_BAD;
2340 /* Fill in the 'current' struct with the state as it is now: what sockets to
2341 supervise and for what actions */
2342 curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
2344 /* We have 0 .. N sockets already and we get to know about the 0 .. M
2345 sockets we should have from now on. Detect the differences, remove no
2346 longer supervised ones and add new ones */
2348 /* walk over the sockets we got right now */
2349 for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) &&
2350 (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
2352 int action = CURL_POLL_NONE;
2356 /* get it from the hash */
2357 entry = sh_getentry(&multi->sockhash, s);
2359 if(curraction & GETSOCK_READSOCK(i))
2360 action |= CURL_POLL_IN;
2361 if(curraction & GETSOCK_WRITESOCK(i))
2362 action |= CURL_POLL_OUT;
2365 /* yeps, already present so check if it has the same action set */
2366 if(entry->action == action)
2367 /* same, continue */
2371 /* this is a socket we didn't have before, add it! */
2372 entry = sh_addentry(&multi->sockhash, s, data);
2375 return CURLM_OUT_OF_MEMORY;
2378 /* we know (entry != NULL) at this point, see the logic above */
2379 if(multi->socket_cb)
2380 multi->socket_cb(data,
2383 multi->socket_userp,
2386 entry->action = action; /* store the current action state */
2389 num = i; /* number of sockets */
2391 /* when we've walked over all the sockets we should have right now, we must
2392 make sure to detect sockets that are removed */
2393 for(i = 0; i< data->numsocks; i++) {
2395 s = data->sockets[i];
2396 for(j = 0; j<num; j++) {
2398 /* this is still supervised */
2399 s = CURL_SOCKET_BAD;
2404 entry = sh_getentry(&multi->sockhash, s);
2406 /* this socket has been removed. Tell the app to remove it */
2407 bool remove_sock_from_hash = TRUE;
2409 /* check if the socket to be removed serves a connection which has
2410 other easy-s in a pipeline. In this case the socket should not be
2412 struct connectdata *easy_conn = data->easy_conn;
2414 if(easy_conn->recv_pipe.size > 1) {
2415 /* the handle should not be removed from the pipe yet */
2416 remove_sock_from_hash = FALSE;
2418 /* Update the sockhash entry to instead point to the next in line
2419 for the recv_pipe, or the first (in case this particular easy
2421 if(entry->easy == data) {
2422 if(Curl_recvpipe_head(data, easy_conn))
2423 entry->easy = easy_conn->recv_pipe.head->next->ptr;
2425 entry->easy = easy_conn->recv_pipe.head->ptr;
2428 if(easy_conn->send_pipe.size > 1) {
2429 /* the handle should not be removed from the pipe yet */
2430 remove_sock_from_hash = FALSE;
2432 /* Update the sockhash entry to instead point to the next in line
2433 for the send_pipe, or the first (in case this particular easy
2435 if(entry->easy == data) {
2436 if(Curl_sendpipe_head(data, easy_conn))
2437 entry->easy = easy_conn->send_pipe.head->next->ptr;
2439 entry->easy = easy_conn->send_pipe.head->ptr;
2442 /* Don't worry about overwriting recv_pipe head with send_pipe_head,
2443 when action will be asked on the socket (see multi_socket()), the
2444 head of the correct pipe will be taken according to the
2448 if(remove_sock_from_hash) {
2449 /* in this case 'entry' is always non-NULL */
2450 if(multi->socket_cb)
2451 multi->socket_cb(data,
2454 multi->socket_userp,
2456 sh_delentry(&multi->sockhash, s);
2458 } /* if sockhash entry existed */
2459 } /* for loop over numsocks */
2461 memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
2462 data->numsocks = num;
2466 void Curl_updatesocket(struct Curl_easy *data)
2468 singlesocket(data->multi, data);
2473 * Curl_multi_closed()
2475 * Used by the connect code to tell the multi_socket code that one of the
2476 * sockets we were using is about to be closed. This function will then
2477 * remove it from the sockethash for this handle to make the multi_socket API
2478 * behave properly, especially for the case when libcurl will create another
2479 * socket again and it gets the same file descriptor number.
2482 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
2485 /* if there's still an easy handle associated with this connection */
2486 struct Curl_multi *multi = conn->data->multi;
2488 /* this is set if this connection is part of a handle that is added to
2489 a multi handle, and only then this is necessary */
2490 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2493 if(multi->socket_cb)
2494 multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
2495 multi->socket_userp,
2498 /* now remove it from the socket hash */
2499 sh_delentry(&multi->sockhash, s);
2506 * add_next_timeout()
2508 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
2509 * when it has just been removed from the splay tree because the timeout has
2510 * expired. This function is then to advance in the list to pick the next
2511 * timeout to use (skip the already expired ones) and add this node back to
2512 * the splay tree again.
2514 * The splay tree only has each sessionhandle as a single node and the nearest
2515 * timeout is used to sort it on.
2517 static CURLMcode add_next_timeout(struct curltime now,
2518 struct Curl_multi *multi,
2519 struct Curl_easy *d)
2521 struct curltime *tv = &d->state.expiretime;
2522 struct curl_llist *list = &d->state.timeoutlist;
2523 struct curl_llist_element *e;
2524 struct time_node *node = NULL;
2526 /* move over the timeout list for this specific handle and remove all
2527 timeouts that are now passed tense and store the next pending
2529 for(e = list->head; e;) {
2530 struct curl_llist_element *n = e->next;
2532 node = (struct time_node *)e->ptr;
2533 diff = Curl_timediff(node->time, now);
2535 /* remove outdated entry */
2536 Curl_llist_remove(list, e, NULL);
2538 /* the list is sorted so get out on the first mismatch */
2544 /* clear the expire times within the handles that we remove from the
2550 /* copy the first entry to 'tv' */
2551 memcpy(tv, &node->time, sizeof(*tv));
2553 /* Insert this node again into the splay. Keep the timer in the list in
2554 case we need to recompute future timers. */
2555 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2556 &d->state.timenode);
2561 static CURLMcode multi_socket(struct Curl_multi *multi,
2565 int *running_handles)
2567 CURLMcode result = CURLM_OK;
2568 struct Curl_easy *data = NULL;
2569 struct Curl_tree *t;
2570 struct curltime now = Curl_now();
2573 /* *perform() deals with running_handles on its own */
2574 result = curl_multi_perform(multi, running_handles);
2576 /* walk through each easy handle and do the socket state change magic
2578 if(result != CURLM_BAD_HANDLE) {
2579 data = multi->easyp;
2580 while(data && !result) {
2581 result = singlesocket(multi, data);
2586 /* or should we fall-through and do the timer-based stuff? */
2589 if(s != CURL_SOCKET_TIMEOUT) {
2591 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2594 /* Unmatched socket, we can't act on it but we ignore this fact. In
2595 real-world tests it has been proved that libevent can in fact give
2596 the application actions even though the socket was just previously
2597 asked to get removed, so thus we better survive stray socket actions
2598 and just move on. */
2601 SIGPIPE_VARIABLE(pipe_st);
2605 if(data->magic != CURLEASY_MAGIC_NUMBER)
2606 /* bad bad bad bad bad bad bad */
2607 return CURLM_INTERNAL_ERROR;
2609 /* If the pipeline is enabled, take the handle which is in the head of
2610 the pipeline. If we should write into the socket, take the send_pipe
2611 head. If we should read from the socket, take the recv_pipe head. */
2612 if(data->easy_conn) {
2613 if((ev_bitmask & CURL_POLL_OUT) &&
2614 data->easy_conn->send_pipe.head)
2615 data = data->easy_conn->send_pipe.head->ptr;
2616 else if((ev_bitmask & CURL_POLL_IN) &&
2617 data->easy_conn->recv_pipe.head)
2618 data = data->easy_conn->recv_pipe.head->ptr;
2621 if(data->easy_conn &&
2622 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2623 /* set socket event bitmask if they're not locked */
2624 data->easy_conn->cselect_bits = ev_bitmask;
2626 sigpipe_ignore(data, &pipe_st);
2627 result = multi_runsingle(multi, now, data);
2628 sigpipe_restore(&pipe_st);
2630 if(data->easy_conn &&
2631 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2632 /* clear the bitmask only if not locked */
2633 data->easy_conn->cselect_bits = 0;
2635 if(CURLM_OK >= result) {
2636 /* get the socket(s) and check if the state has been changed since
2638 result = singlesocket(multi, data);
2643 /* Now we fall-through and do the timer-based stuff, since we don't want
2644 to force the user to have to deal with timeouts as long as at least
2645 one connection in fact has traffic. */
2647 data = NULL; /* set data to NULL again to avoid calling
2648 multi_runsingle() in case there's no need to */
2649 now = Curl_now(); /* get a newer time since the multi_runsingle() loop
2650 may have taken some time */
2654 /* Asked to run due to time-out. Clear the 'lastcall' variable to force
2655 update_timer() to trigger a callback to the app again even if the same
2656 timeout is still the one to run after this call. That handles the case
2657 when the application asks libcurl to run the timeout prematurely. */
2658 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
2662 * The loop following here will go on as long as there are expire-times left
2663 * to process in the splay and 'data' will be re-assigned for every expired
2664 * handle we deal with.
2667 /* the first loop lap 'data' can be NULL */
2669 SIGPIPE_VARIABLE(pipe_st);
2671 sigpipe_ignore(data, &pipe_st);
2672 result = multi_runsingle(multi, now, data);
2673 sigpipe_restore(&pipe_st);
2675 if(CURLM_OK >= result) {
2676 /* get the socket(s) and check if the state has been changed since
2678 result = singlesocket(multi, data);
2684 /* Check if there's one (more) expired timer to deal with! This function
2685 extracts a matching node if there is one */
2687 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2689 data = t->payload; /* assign this for next loop */
2690 (void)add_next_timeout(now, multi, t->payload);
2695 *running_handles = multi->num_alive;
2699 #undef curl_multi_setopt
2700 CURLMcode curl_multi_setopt(struct Curl_multi *multi,
2701 CURLMoption option, ...)
2703 CURLMcode res = CURLM_OK;
2706 if(!GOOD_MULTI_HANDLE(multi))
2707 return CURLM_BAD_HANDLE;
2709 if(multi->in_callback)
2710 return CURLM_RECURSIVE_API_CALL;
2712 va_start(param, option);
2715 case CURLMOPT_SOCKETFUNCTION:
2716 multi->socket_cb = va_arg(param, curl_socket_callback);
2718 case CURLMOPT_SOCKETDATA:
2719 multi->socket_userp = va_arg(param, void *);
2721 case CURLMOPT_PUSHFUNCTION:
2722 multi->push_cb = va_arg(param, curl_push_callback);
2724 case CURLMOPT_PUSHDATA:
2725 multi->push_userp = va_arg(param, void *);
2727 case CURLMOPT_PIPELINING:
2728 multi->pipelining = va_arg(param, long) & CURLPIPE_MULTIPLEX;
2730 case CURLMOPT_TIMERFUNCTION:
2731 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
2733 case CURLMOPT_TIMERDATA:
2734 multi->timer_userp = va_arg(param, void *);
2736 case CURLMOPT_MAXCONNECTS:
2737 multi->maxconnects = va_arg(param, long);
2739 case CURLMOPT_MAX_HOST_CONNECTIONS:
2740 multi->max_host_connections = va_arg(param, long);
2742 case CURLMOPT_MAX_PIPELINE_LENGTH:
2743 multi->max_pipeline_length = va_arg(param, long);
2745 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
2746 multi->content_length_penalty_size = va_arg(param, long);
2748 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
2749 multi->chunk_length_penalty_size = va_arg(param, long);
2751 case CURLMOPT_PIPELINING_SITE_BL:
2752 res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
2753 &multi->pipelining_site_bl);
2755 case CURLMOPT_PIPELINING_SERVER_BL:
2756 res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
2757 &multi->pipelining_server_bl);
2759 case CURLMOPT_MAX_TOTAL_CONNECTIONS:
2760 multi->max_total_connections = va_arg(param, long);
2763 res = CURLM_UNKNOWN_OPTION;
2770 /* we define curl_multi_socket() in the public multi.h header */
2771 #undef curl_multi_socket
2773 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
2774 int *running_handles)
2777 if(multi->in_callback)
2778 return CURLM_RECURSIVE_API_CALL;
2779 result = multi_socket(multi, FALSE, s, 0, running_handles);
2780 if(CURLM_OK >= result)
2781 update_timer(multi);
2785 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
2786 int ev_bitmask, int *running_handles)
2789 if(multi->in_callback)
2790 return CURLM_RECURSIVE_API_CALL;
2791 result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
2792 if(CURLM_OK >= result)
2793 update_timer(multi);
2797 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
2801 if(multi->in_callback)
2802 return CURLM_RECURSIVE_API_CALL;
2803 result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
2804 if(CURLM_OK >= result)
2805 update_timer(multi);
2809 static CURLMcode multi_timeout(struct Curl_multi *multi,
2812 static struct curltime tv_zero = {0, 0};
2814 if(multi->timetree) {
2815 /* we have a tree of expire times */
2816 struct curltime now = Curl_now();
2818 /* splay the lowest to the bottom */
2819 multi->timetree = Curl_splay(tv_zero, multi->timetree);
2821 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
2822 /* some time left before expiration */
2823 timediff_t diff = Curl_timediff(multi->timetree->key, now);
2826 * Since we only provide millisecond resolution on the returned value
2827 * and the diff might be less than one millisecond here, we don't
2828 * return zero as that may cause short bursts of busyloops on fast
2829 * processors while the diff is still present but less than one
2830 * millisecond! instead we return 1 until the time is ripe.
2834 /* this should be safe even on 64 bit archs, as we don't use that
2835 overly long timeouts */
2836 *timeout_ms = (long)diff;
2839 /* 0 means immediately */
2848 CURLMcode curl_multi_timeout(struct Curl_multi *multi,
2851 /* First, make some basic checks that the CURLM handle is a good handle */
2852 if(!GOOD_MULTI_HANDLE(multi))
2853 return CURLM_BAD_HANDLE;
2855 if(multi->in_callback)
2856 return CURLM_RECURSIVE_API_CALL;
2858 return multi_timeout(multi, timeout_ms);
2862 * Tell the application it should update its timers, if it subscribes to the
2863 * update timer callback.
2865 static int update_timer(struct Curl_multi *multi)
2869 if(!multi->timer_cb)
2871 if(multi_timeout(multi, &timeout_ms)) {
2874 if(timeout_ms < 0) {
2875 static const struct curltime none = {0, 0};
2876 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
2877 multi->timer_lastcall = none;
2878 /* there's no timeout now but there was one previously, tell the app to
2880 return multi->timer_cb(multi, -1, multi->timer_userp);
2885 /* When multi_timeout() is done, multi->timetree points to the node with the
2886 * timeout we got the (relative) time-out time for. We can thus easily check
2887 * if this is the same (fixed) time as we got in a previous call and then
2888 * avoid calling the callback again. */
2889 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
2892 multi->timer_lastcall = multi->timetree->key;
2894 return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
2898 * multi_deltimeout()
2900 * Remove a given timestamp from the list of timeouts.
2903 multi_deltimeout(struct Curl_easy *data, expire_id eid)
2905 struct curl_llist_element *e;
2906 struct curl_llist *timeoutlist = &data->state.timeoutlist;
2907 /* find and remove the specific node from the list */
2908 for(e = timeoutlist->head; e; e = e->next) {
2909 struct time_node *n = (struct time_node *)e->ptr;
2911 Curl_llist_remove(timeoutlist, e, NULL);
2918 * multi_addtimeout()
2920 * Add a timestamp to the list of timeouts. Keep the list sorted so that head
2921 * of list is always the timeout nearest in time.
2925 multi_addtimeout(struct Curl_easy *data,
2926 struct curltime *stamp,
2929 struct curl_llist_element *e;
2930 struct time_node *node;
2931 struct curl_llist_element *prev = NULL;
2933 struct curl_llist *timeoutlist = &data->state.timeoutlist;
2935 node = &data->state.expires[eid];
2937 /* copy the timestamp and id */
2938 memcpy(&node->time, stamp, sizeof(*stamp));
2939 node->eid = eid; /* also marks it as in use */
2941 n = Curl_llist_count(timeoutlist);
2943 /* find the correct spot in the list */
2944 for(e = timeoutlist->head; e; e = e->next) {
2945 struct time_node *check = (struct time_node *)e->ptr;
2946 timediff_t diff = Curl_timediff(check->time, node->time);
2954 this is the first timeout on the list */
2956 Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
2963 * given a number of milliseconds from now to use to set the 'act before
2964 * this'-time for the transfer, to be extracted by curl_multi_timeout()
2966 * The timeout will be added to a queue of timeouts if it defines a moment in
2967 * time that is later than the current head of queue.
2969 * Expire replaces a former timeout using the same id if already set.
2971 void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
2973 struct Curl_multi *multi = data->multi;
2974 struct curltime *nowp = &data->state.expiretime;
2975 struct curltime set;
2977 /* this is only interesting while there is still an associated multi struct
2982 DEBUGASSERT(id < EXPIRE_LAST);
2985 set.tv_sec += milli/1000;
2986 set.tv_usec += (unsigned int)(milli%1000)*1000;
2988 if(set.tv_usec >= 1000000) {
2990 set.tv_usec -= 1000000;
2993 /* Remove any timer with the same id just in case. */
2994 multi_deltimeout(data, id);
2996 /* Add it to the timer list. It must stay in the list until it has expired
2997 in case we need to recompute the minimum timer later. */
2998 multi_addtimeout(data, &set, id);
3000 if(nowp->tv_sec || nowp->tv_usec) {
3001 /* This means that the struct is added as a node in the splay tree.
3002 Compare if the new time is earlier, and only remove-old/add-new if it
3004 timediff_t diff = Curl_timediff(set, *nowp);
3008 /* The current splay tree entry is sooner than this new expiry time.
3009 We don't need to update our splay tree entry. */
3013 /* Since this is an updated time, we must remove the previous entry from
3014 the splay tree first and then re-add the new value */
3015 rc = Curl_splayremovebyaddr(multi->timetree,
3016 &data->state.timenode,
3019 infof(data, "Internal error removing splay node = %d\n", rc);
3022 /* Indicate that we are in the splay tree and insert the new timer expiry
3023 value since it is our local minimum. */
3025 data->state.timenode.payload = data;
3026 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
3027 &data->state.timenode);
3031 * Curl_expire_done()
3033 * Removes the expire timer. Marks it as done.
3036 void Curl_expire_done(struct Curl_easy *data, expire_id id)
3038 /* remove the timer, if there */
3039 multi_deltimeout(data, id);
3043 * Curl_expire_clear()
3045 * Clear ALL timeout values for this handle.
3047 void Curl_expire_clear(struct Curl_easy *data)
3049 struct Curl_multi *multi = data->multi;
3050 struct curltime *nowp = &data->state.expiretime;
3052 /* this is only interesting while there is still an associated multi struct
3057 if(nowp->tv_sec || nowp->tv_usec) {
3058 /* Since this is an cleared time, we must remove the previous entry from
3060 struct curl_llist *list = &data->state.timeoutlist;
3063 rc = Curl_splayremovebyaddr(multi->timetree,
3064 &data->state.timenode,
3067 infof(data, "Internal error clearing splay node = %d\n", rc);
3069 /* flush the timeout list too */
3070 while(list->size > 0) {
3071 Curl_llist_remove(list, list->tail, NULL);
3075 infof(data, "Expire cleared\n");
3085 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
3088 struct Curl_sh_entry *there = NULL;
3090 if(multi->in_callback)
3091 return CURLM_RECURSIVE_API_CALL;
3093 there = sh_getentry(&multi->sockhash, s);
3096 return CURLM_BAD_SOCKET;
3098 there->socketp = hashp;
3103 size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
3105 return multi ? multi->max_host_connections : 0;
3108 size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
3110 return multi ? multi->max_total_connections : 0;
3113 curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
3115 return multi ? multi->content_length_penalty_size : 0;
3118 curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
3120 return multi ? multi->chunk_length_penalty_size : 0;
3123 struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
3125 return &multi->pipelining_site_bl;
3128 struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
3130 return &multi->pipelining_server_bl;
3133 static void process_pending_handles(struct Curl_multi *multi)
3135 struct curl_llist_element *e = multi->pending.head;
3137 struct Curl_easy *data = e->ptr;
3139 DEBUGASSERT(data->mstate == CURLM_STATE_CONNECT_PEND);
3141 multistate(data, CURLM_STATE_CONNECT);
3143 /* Remove this node from the list */
3144 Curl_llist_remove(&multi->pending, e, NULL);
3146 /* Make sure that the handle will be processed soonish. */
3147 Curl_expire(data, 0, EXPIRE_RUN_NOW);
3151 void Curl_set_in_callback(struct Curl_easy *data, bool value)
3153 /* might get called when there is no data pointer! */
3155 if(data->multi_easy)
3156 data->multi_easy->in_callback = value;
3157 else if(data->multi)
3158 data->multi->in_callback = value;
3162 bool Curl_is_in_callback(struct Curl_easy *easy)
3164 return ((easy->multi && easy->multi->in_callback) ||
3165 (easy->multi_easy && easy->multi_easy->in_callback));
3169 void Curl_multi_dump(struct Curl_multi *multi)
3171 struct Curl_easy *data;
3173 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
3174 multi->num_easy, multi->num_alive);
3175 for(data = multi->easyp; data; data = data->next) {
3176 if(data->mstate < CURLM_STATE_COMPLETED) {
3177 /* only display handles that are not completed */
3178 fprintf(stderr, "handle %p, state %s, %d sockets\n",
3180 statename[data->mstate], data->numsocks);
3181 for(i = 0; i < data->numsocks; i++) {
3182 curl_socket_t s = data->sockets[i];
3183 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3185 fprintf(stderr, "%d ", (int)s);
3187 fprintf(stderr, "INTERNAL CONFUSION\n");
3190 fprintf(stderr, "[%s %s] ",
3191 entry->action&CURL_POLL_IN?"RECVING":"",
3192 entry->action&CURL_POLL_OUT?"SENDING":"");
3195 fprintf(stderr, "\n");