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 */
761 data->easy_conn = NULL;
764 /* Remove the PSL association. */
765 if(data->psl == &multi->psl)
769 data->multi = NULL; /* clear the association to this multi handle */
771 /* make sure there's no pending message in the queue sent from this easy
774 for(e = multi->msglist.head; e; e = e->next) {
775 struct Curl_message *msg = e->ptr;
777 if(msg->extmsg.easy_handle == easy) {
778 Curl_llist_remove(&multi->msglist, e, NULL);
779 /* there can only be one from this specific handle */
784 /* make the previous node point to our next */
786 data->prev->next = data->next;
788 multi->easyp = data->next; /* point to first node */
790 /* make our next point to our previous node */
792 data->next->prev = data->prev;
794 multi->easylp = data->prev; /* point to last node */
797 We do not touch the easy handle here! */
798 multi->num_easy--; /* one less to care about now */
804 /* Return TRUE if the application asked for a certain set of pipelining */
805 bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
807 return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
810 void Curl_multi_handlePipeBreak(struct Curl_easy *data)
812 data->easy_conn = NULL;
815 static int waitconnect_getsock(struct connectdata *conn,
824 return GETSOCK_BLANK;
827 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
828 return Curl_ssl_getsock(conn, sock, numsocks);
831 for(i = 0; i<2; i++) {
832 if(conn->tempsock[i] != CURL_SOCKET_BAD) {
833 sock[s] = conn->tempsock[i];
834 rc |= GETSOCK_WRITESOCK(s++);
841 static int waitproxyconnect_getsock(struct connectdata *conn,
846 return GETSOCK_BLANK;
848 sock[0] = conn->sock[FIRSTSOCKET];
850 /* when we've sent a CONNECT to a proxy, we should rather wait for the
851 socket to become readable to be able to get the response headers */
852 if(conn->connect_state)
853 return GETSOCK_READSOCK(0);
855 return GETSOCK_WRITESOCK(0);
858 static int domore_getsock(struct connectdata *conn,
859 curl_socket_t *socks,
862 if(conn && conn->handler->domore_getsock)
863 return conn->handler->domore_getsock(conn, socks, numsocks);
864 return GETSOCK_BLANK;
867 /* returns bitmapped flags for this handle and its sockets */
868 static int multi_getsock(struct Curl_easy *data,
869 curl_socket_t *socks, /* points to numsocks number
873 /* The no connection case can happen when this is called from
874 curl_multi_remove_handle() => singlesocket() => multi_getsock().
879 if(data->mstate > CURLM_STATE_CONNECT &&
880 data->mstate < CURLM_STATE_COMPLETED) {
881 /* Set up ownership correctly */
882 data->easy_conn->data = data;
885 switch(data->mstate) {
887 #if 0 /* switch back on these cases to get the compiler to check for all enums
889 case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
890 case CURLM_STATE_COMPLETED:
891 case CURLM_STATE_MSGSENT:
892 case CURLM_STATE_INIT:
893 case CURLM_STATE_CONNECT:
894 case CURLM_STATE_WAITDO:
895 case CURLM_STATE_DONE:
896 case CURLM_STATE_LAST:
897 /* this will get called with CURLM_STATE_COMPLETED when a handle is
902 case CURLM_STATE_WAITRESOLVE:
903 return Curl_resolv_getsock(data->easy_conn, socks, numsocks);
905 case CURLM_STATE_PROTOCONNECT:
906 case CURLM_STATE_SENDPROTOCONNECT:
907 return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
910 case CURLM_STATE_DOING:
911 return Curl_doing_getsock(data->easy_conn, socks, numsocks);
913 case CURLM_STATE_WAITPROXYCONNECT:
914 return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
916 case CURLM_STATE_WAITCONNECT:
917 return waitconnect_getsock(data->easy_conn, socks, numsocks);
919 case CURLM_STATE_DO_MORE:
920 return domore_getsock(data->easy_conn, socks, numsocks);
922 case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
923 to waiting for the same as the *PERFORM
925 case CURLM_STATE_PERFORM:
926 case CURLM_STATE_WAITPERFORM:
927 return Curl_single_getsock(data->easy_conn, socks, numsocks);
932 CURLMcode curl_multi_fdset(struct Curl_multi *multi,
933 fd_set *read_fd_set, fd_set *write_fd_set,
934 fd_set *exc_fd_set, int *max_fd)
936 /* Scan through all the easy handles to get the file descriptors set.
937 Some easy handles may not have connected to the remote host yet,
938 and then we must make sure that is done. */
939 struct Curl_easy *data;
940 int this_max_fd = -1;
941 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
943 (void)exc_fd_set; /* not used */
945 if(!GOOD_MULTI_HANDLE(multi))
946 return CURLM_BAD_HANDLE;
948 if(multi->in_callback)
949 return CURLM_RECURSIVE_API_CALL;
953 int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
955 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
956 curl_socket_t s = CURL_SOCKET_BAD;
958 if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
959 FD_SET(sockbunch[i], read_fd_set);
962 if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
963 FD_SET(sockbunch[i], write_fd_set);
966 if(s == CURL_SOCKET_BAD)
967 /* this socket is unused, break out of loop */
969 if((int)s > this_max_fd)
970 this_max_fd = (int)s;
973 data = data->next; /* check next handle */
976 *max_fd = this_max_fd;
981 #define NUM_POLLS_ON_STACK 10
983 CURLMcode Curl_multi_wait(struct Curl_multi *multi,
984 struct curl_waitfd extra_fds[],
985 unsigned int extra_nfds,
988 bool *gotsocket) /* if any socket was checked */
990 struct Curl_easy *data;
991 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
994 unsigned int nfds = 0;
995 unsigned int curlfds;
996 struct pollfd *ufds = NULL;
997 bool ufds_malloc = FALSE;
998 long timeout_internal;
1000 struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
1005 if(!GOOD_MULTI_HANDLE(multi))
1006 return CURLM_BAD_HANDLE;
1008 if(multi->in_callback)
1009 return CURLM_RECURSIVE_API_CALL;
1011 /* Count up how many fds we have from the multi handle */
1012 data = multi->easyp;
1014 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1016 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1017 curl_socket_t s = CURL_SOCKET_BAD;
1019 if(bitmap & GETSOCK_READSOCK(i)) {
1023 if(bitmap & GETSOCK_WRITESOCK(i)) {
1027 if(s == CURL_SOCKET_BAD) {
1032 data = data->next; /* check next handle */
1035 /* If the internally desired timeout is actually shorter than requested from
1036 the outside, then use the shorter time! But only if the internal timer
1037 is actually larger than -1! */
1038 (void)multi_timeout(multi, &timeout_internal);
1039 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
1040 timeout_ms = (int)timeout_internal;
1042 curlfds = nfds; /* number of internal file descriptors */
1043 nfds += extra_nfds; /* add the externally provided ones */
1046 if(nfds > NUM_POLLS_ON_STACK) {
1047 /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
1048 big, so at 2^29 sockets this value might wrap. When a process gets
1049 the capability to actually handle over 500 million sockets this
1050 calculation needs a integer overflow check. */
1051 ufds = malloc(nfds * sizeof(struct pollfd));
1053 return CURLM_OUT_OF_MEMORY;
1057 ufds = &a_few_on_stack[0];
1061 /* only do the second loop if we found descriptors in the first stage run
1065 /* Add the curl handles to our pollfds first */
1066 data = multi->easyp;
1068 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1070 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1071 curl_socket_t s = CURL_SOCKET_BAD;
1073 if(bitmap & GETSOCK_READSOCK(i)) {
1074 ufds[nfds].fd = sockbunch[i];
1075 ufds[nfds].events = POLLIN;
1079 if(bitmap & GETSOCK_WRITESOCK(i)) {
1080 ufds[nfds].fd = sockbunch[i];
1081 ufds[nfds].events = POLLOUT;
1085 if(s == CURL_SOCKET_BAD) {
1090 data = data->next; /* check next handle */
1094 /* Add external file descriptions from poll-like struct curl_waitfd */
1095 for(i = 0; i < extra_nfds; i++) {
1096 ufds[nfds].fd = extra_fds[i].fd;
1097 ufds[nfds].events = 0;
1098 if(extra_fds[i].events & CURL_WAIT_POLLIN)
1099 ufds[nfds].events |= POLLIN;
1100 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1101 ufds[nfds].events |= POLLPRI;
1102 if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1103 ufds[nfds].events |= POLLOUT;
1110 pollrc = Curl_poll(ufds, nfds, timeout_ms);
1114 /* copy revents results from the poll to the curl_multi_wait poll
1115 struct, the bit values of the actual underlying poll() implementation
1116 may not be the same as the ones in the public libcurl API! */
1117 for(i = 0; i < extra_nfds; i++) {
1118 unsigned short mask = 0;
1119 unsigned r = ufds[curlfds + i].revents;
1122 mask |= CURL_WAIT_POLLIN;
1124 mask |= CURL_WAIT_POLLOUT;
1126 mask |= CURL_WAIT_POLLPRI;
1128 extra_fds[i].revents = mask;
1137 if(gotsocket && (extra_fds || curlfds))
1138 /* if any socket was checked */
1144 CURLMcode curl_multi_wait(struct Curl_multi *multi,
1145 struct curl_waitfd extra_fds[],
1146 unsigned int extra_nfds,
1150 return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL);
1153 * Curl_multi_connchanged() is called to tell that there is a connection in
1154 * this multi handle that has changed state (pipelining become possible, the
1155 * number of allowed streams changed or similar), and a subsequent use of this
1156 * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1159 void Curl_multi_connchanged(struct Curl_multi *multi)
1161 multi->recheckstate = TRUE;
1165 * multi_ischanged() is called
1167 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1168 * => CONNECT action.
1170 * Set 'clear' to TRUE to have it also clear the state variable.
1172 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1174 bool retval = multi->recheckstate;
1176 multi->recheckstate = FALSE;
1180 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1181 struct Curl_easy *data,
1182 struct connectdata *conn)
1186 if(multi->in_callback)
1187 return CURLM_RECURSIVE_API_CALL;
1189 rc = curl_multi_add_handle(multi, data);
1191 struct SingleRequest *k = &data->req;
1193 /* pass in NULL for 'conn' here since we don't want to init the
1194 connection, only this transfer */
1195 Curl_init_do(data, NULL);
1197 /* take this handle to the perform state right away */
1198 multistate(data, CURLM_STATE_PERFORM);
1199 data->easy_conn = conn;
1200 k->keepon |= KEEP_RECV; /* setup to receive! */
1205 static CURLcode multi_reconnect_request(struct connectdata **connp)
1207 CURLcode result = CURLE_OK;
1208 struct connectdata *conn = *connp;
1209 struct Curl_easy *data = conn->data;
1211 /* This was a re-use of a connection and we got a write error in the
1212 * DO-phase. Then we DISCONNECT this connection and have another attempt to
1213 * CONNECT and then DO again! The retry cannot possibly find another
1214 * connection to re-use, since we only keep one possible connection for
1217 infof(data, "Re-used connection seems dead, get a new one\n");
1219 connclose(conn, "Reconnect dead connection"); /* enforce close */
1220 result = multi_done(&conn, result, FALSE); /* we are so done with this */
1222 /* conn may no longer be a good pointer, clear it to avoid mistakes by
1227 * We need to check for CURLE_SEND_ERROR here as well. This could happen
1228 * when the request failed on a FTP connection and thus multi_done() itself
1229 * tried to use the connection (again).
1231 if(!result || (CURLE_SEND_ERROR == result)) {
1233 bool protocol_done = TRUE;
1235 /* Now, redo the connect and get a new connection */
1236 result = Curl_connect(data, connp, &async, &protocol_done);
1238 /* We have connected or sent away a name resolve query fine */
1240 conn = *connp; /* setup conn to again point to something nice */
1242 /* Now, if async is TRUE here, we need to wait for the name
1244 result = Curl_resolver_wait_resolv(conn, NULL);
1248 /* Resolved, continue with the connection */
1249 result = Curl_once_resolved(conn, &protocol_done);
1260 * do_complete is called when the DO actions are complete.
1262 * We init chunking and trailer bits to their default values here immediately
1263 * before receiving any header data for the current request in the pipeline.
1265 static void do_complete(struct connectdata *conn)
1267 conn->data->req.chunk = FALSE;
1268 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
1269 conn->sockfd:conn->writesockfd) + 1;
1270 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
1273 static CURLcode multi_do(struct connectdata **connp, bool *done)
1275 CURLcode result = CURLE_OK;
1276 struct connectdata *conn = *connp;
1277 struct Curl_easy *data = conn->data;
1279 if(conn->handler->do_it) {
1280 /* generic protocol-specific function pointer set in curl_connect() */
1281 result = conn->handler->do_it(conn, done);
1283 /* This was formerly done in transfer.c, but we better do it here */
1284 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
1286 * If the connection is using an easy handle, call reconnect
1287 * to re-establish the connection. Otherwise, let the multi logic
1288 * figure out how to re-establish the connection.
1291 result = multi_reconnect_request(connp);
1294 /* ... finally back to actually retry the DO phase */
1295 conn = *connp; /* re-assign conn since multi_reconnect_request
1296 creates a new connection */
1297 result = conn->handler->do_it(conn, done);
1304 if(!result && *done)
1305 /* do_complete must be called after the protocol-specific DO function */
1312 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1313 * second stage DO state which (wrongly) was introduced to support FTP's
1314 * second connection.
1316 * TODO: A future libcurl should be able to work away this state.
1318 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1319 * DOING state there's more work to do!
1322 static CURLcode multi_do_more(struct connectdata *conn, int *complete)
1324 CURLcode result = CURLE_OK;
1328 if(conn->handler->do_more)
1329 result = conn->handler->do_more(conn, complete);
1331 if(!result && (*complete == 1))
1332 /* do_complete must be called after the protocol-specific DO function */
1338 static CURLMcode multi_runsingle(struct Curl_multi *multi,
1339 struct curltime now,
1340 struct Curl_easy *data)
1342 struct Curl_message *msg = NULL;
1345 bool protocol_connect = FALSE;
1346 bool dophase_done = FALSE;
1349 CURLcode result = CURLE_OK;
1350 struct SingleRequest *k;
1352 time_t recv_timeout_ms;
1353 timediff_t send_timeout_ms;
1356 if(!GOOD_EASY_HANDLE(data))
1357 return CURLM_BAD_EASY_HANDLE;
1360 /* A "stream" here is a logical stream if the protocol can handle that
1361 (HTTP/2), or the full connection for older protocols */
1362 bool stream_error = FALSE;
1365 if(!data->easy_conn &&
1366 data->mstate > CURLM_STATE_CONNECT &&
1367 data->mstate < CURLM_STATE_DONE) {
1368 /* In all these states, the code will blindly access 'data->easy_conn'
1369 so this is precaution that it isn't NULL. And it silences static
1371 failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
1372 return CURLM_INTERNAL_ERROR;
1375 if(multi_ischanged(multi, TRUE)) {
1376 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
1377 process_pending_handles(multi); /* pipelined/multiplexed */
1380 if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
1381 data->mstate < CURLM_STATE_COMPLETED) {
1382 /* Make sure we set the connection's current owner */
1383 data->easy_conn->data = data;
1386 if(data->easy_conn &&
1387 (data->mstate >= CURLM_STATE_CONNECT) &&
1388 (data->mstate < CURLM_STATE_COMPLETED)) {
1389 /* we need to wait for the connect state as only then is the start time
1390 stored, but we must not check already completed handles */
1391 timeout_ms = Curl_timeleft(data, &now,
1392 (data->mstate <= CURLM_STATE_WAITDO)?
1395 if(timeout_ms < 0) {
1396 /* Handle timed out */
1397 if(data->mstate == CURLM_STATE_WAITRESOLVE)
1398 failf(data, "Resolving timed out after %ld milliseconds",
1399 Curl_timediff(now, data->progress.t_startsingle));
1400 else if(data->mstate == CURLM_STATE_WAITCONNECT)
1401 failf(data, "Connection timed out after %ld milliseconds",
1402 Curl_timediff(now, data->progress.t_startsingle));
1406 failf(data, "Operation timed out after %ld milliseconds with %"
1407 CURL_FORMAT_CURL_OFF_T " out of %"
1408 CURL_FORMAT_CURL_OFF_T " bytes received",
1409 Curl_timediff(now, data->progress.t_startsingle),
1410 k->bytecount, k->size);
1413 failf(data, "Operation timed out after %ld milliseconds with %"
1414 CURL_FORMAT_CURL_OFF_T " bytes received",
1415 Curl_timediff(now, data->progress.t_startsingle),
1420 /* Force connection closed if the connection has indeed been used */
1421 if(data->mstate > CURLM_STATE_DO) {
1422 streamclose(data->easy_conn, "Disconnected with pending data");
1423 stream_error = TRUE;
1425 result = CURLE_OPERATION_TIMEDOUT;
1426 (void)multi_done(&data->easy_conn, result, TRUE);
1427 /* Skip the statemachine and go directly to error handling section. */
1428 goto statemachine_end;
1432 switch(data->mstate) {
1433 case CURLM_STATE_INIT:
1434 /* init this transfer. */
1435 result = Curl_pretransfer(data);
1438 /* after init, go CONNECT */
1439 multistate(data, CURLM_STATE_CONNECT);
1440 Curl_pgrsTime(data, TIMER_STARTOP);
1441 rc = CURLM_CALL_MULTI_PERFORM;
1445 case CURLM_STATE_CONNECT_PEND:
1446 /* We will stay here until there is a connection available. Then
1447 we try again in the CURLM_STATE_CONNECT state. */
1450 case CURLM_STATE_CONNECT:
1451 /* Connect. We want to get a connection identifier filled in. */
1452 Curl_pgrsTime(data, TIMER_STARTSINGLE);
1453 result = Curl_connect(data, &data->easy_conn,
1454 &async, &protocol_connect);
1455 if(CURLE_NO_CONNECTION_AVAILABLE == result) {
1456 /* There was no connection available. We will go to the pending
1457 state and wait for an available connection. */
1458 multistate(data, CURLM_STATE_CONNECT_PEND);
1460 /* add this handle to the list of connect-pending handles */
1461 Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
1462 &data->connect_queue);
1468 /* Add this handle to the send or pend pipeline */
1469 result = Curl_add_handle_to_pipeline(data, data->easy_conn);
1471 stream_error = TRUE;
1474 /* We're now waiting for an asynchronous name lookup */
1475 multistate(data, CURLM_STATE_WAITRESOLVE);
1477 /* after the connect has been sent off, go WAITCONNECT unless the
1478 protocol connect is already done and we can go directly to
1480 rc = CURLM_CALL_MULTI_PERFORM;
1482 if(protocol_connect)
1483 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1484 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1486 #ifndef CURL_DISABLE_HTTP
1487 if(Curl_connect_ongoing(data->easy_conn))
1488 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1491 multistate(data, CURLM_STATE_WAITCONNECT);
1498 case CURLM_STATE_WAITRESOLVE:
1499 /* awaiting an asynch name resolve to complete */
1501 struct Curl_dns_entry *dns = NULL;
1502 struct connectdata *conn = data->easy_conn;
1503 const char *hostname;
1505 if(conn->bits.httpproxy)
1506 hostname = conn->http_proxy.host.name;
1507 else if(conn->bits.conn_to_host)
1508 hostname = conn->conn_to_host.name;
1510 hostname = conn->host.name;
1512 /* check if we have the name resolved by now */
1513 dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
1516 #ifdef CURLRES_ASYNCH
1517 conn->async.dns = dns;
1518 conn->async.done = TRUE;
1521 infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
1525 result = Curl_resolv_check(data->easy_conn, &dns);
1527 /* Update sockets here, because the socket(s) may have been
1528 closed and the application thus needs to be told, even if it
1529 is likely that the same socket(s) will again be used further
1530 down. If the name has not yet been resolved, it is likely
1531 that new sockets have been opened in an attempt to contact
1532 another resolver. */
1533 singlesocket(multi, data);
1536 /* Perform the next step in the connection phase, and then move on
1537 to the WAITCONNECT state */
1538 result = Curl_once_resolved(data->easy_conn, &protocol_connect);
1541 /* if Curl_once_resolved() returns failure, the connection struct
1542 is already freed and gone */
1543 data->easy_conn = NULL; /* no more connection */
1545 /* call again please so that we get the next socket setup */
1546 rc = CURLM_CALL_MULTI_PERFORM;
1547 if(protocol_connect)
1548 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1549 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1551 #ifndef CURL_DISABLE_HTTP
1552 if(Curl_connect_ongoing(data->easy_conn))
1553 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1556 multistate(data, CURLM_STATE_WAITCONNECT);
1562 /* failure detected */
1563 stream_error = TRUE;
1569 #ifndef CURL_DISABLE_HTTP
1570 case CURLM_STATE_WAITPROXYCONNECT:
1571 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
1572 result = Curl_http_connect(data->easy_conn, &protocol_connect);
1574 if(data->easy_conn->bits.proxy_connect_closed) {
1575 rc = CURLM_CALL_MULTI_PERFORM;
1576 /* connect back to proxy again */
1578 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1579 multistate(data, CURLM_STATE_CONNECT);
1582 if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
1583 data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
1584 Curl_connect_complete(data->easy_conn)) {
1585 rc = CURLM_CALL_MULTI_PERFORM;
1586 /* initiate protocol connect phase */
1587 multistate(data, CURLM_STATE_SENDPROTOCONNECT);
1591 stream_error = TRUE;
1595 case CURLM_STATE_WAITCONNECT:
1596 /* awaiting a completion of an asynch TCP connect */
1597 result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
1598 if(connected && !result) {
1599 #ifndef CURL_DISABLE_HTTP
1600 if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
1601 !data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
1602 Curl_connect_ongoing(data->easy_conn)) {
1603 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1607 rc = CURLM_CALL_MULTI_PERFORM;
1608 multistate(data, data->easy_conn->bits.tunnel_proxy?
1609 CURLM_STATE_WAITPROXYCONNECT:
1610 CURLM_STATE_SENDPROTOCONNECT);
1613 /* failure detected */
1614 /* Just break, the cleaning up is handled all in one place */
1615 stream_error = TRUE;
1620 case CURLM_STATE_SENDPROTOCONNECT:
1621 result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
1622 if(!result && !protocol_connect)
1623 /* switch to waiting state */
1624 multistate(data, CURLM_STATE_PROTOCONNECT);
1626 /* protocol connect has completed, go WAITDO or DO */
1627 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1628 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1629 rc = CURLM_CALL_MULTI_PERFORM;
1632 /* failure detected */
1633 Curl_posttransfer(data);
1634 multi_done(&data->easy_conn, result, TRUE);
1635 stream_error = TRUE;
1639 case CURLM_STATE_PROTOCONNECT:
1640 /* protocol-specific connect phase */
1641 result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
1642 if(!result && protocol_connect) {
1643 /* after the connect has completed, go WAITDO or DO */
1644 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1645 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1646 rc = CURLM_CALL_MULTI_PERFORM;
1649 /* failure detected */
1650 Curl_posttransfer(data);
1651 multi_done(&data->easy_conn, result, TRUE);
1652 stream_error = TRUE;
1656 case CURLM_STATE_WAITDO:
1657 /* Wait for our turn to DO when we're pipelining requests */
1658 if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
1659 /* Grabbed the channel */
1660 multistate(data, CURLM_STATE_DO);
1661 rc = CURLM_CALL_MULTI_PERFORM;
1665 case CURLM_STATE_DO:
1666 if(data->set.connect_only) {
1667 /* keep connection open for application to use the socket */
1668 connkeep(data->easy_conn, "CONNECT_ONLY");
1669 multistate(data, CURLM_STATE_DONE);
1671 rc = CURLM_CALL_MULTI_PERFORM;
1674 /* Perform the protocol's DO action */
1675 result = multi_do(&data->easy_conn, &dophase_done);
1677 /* When multi_do() returns failure, data->easy_conn might be NULL! */
1681 /* some steps needed for wildcard matching */
1682 if(data->state.wildcardmatch) {
1683 struct WildcardData *wc = &data->wildcard;
1684 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
1685 /* skip some states if it is important */
1686 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1687 multistate(data, CURLM_STATE_DONE);
1688 rc = CURLM_CALL_MULTI_PERFORM;
1692 /* DO was not completed in one function call, we must continue
1694 multistate(data, CURLM_STATE_DOING);
1698 /* after DO, go DO_DONE... or DO_MORE */
1699 else if(data->easy_conn->bits.do_more) {
1700 /* we're supposed to do more, but we need to sit down, relax
1701 and wait a little while first */
1702 multistate(data, CURLM_STATE_DO_MORE);
1706 /* we're done with the DO, now DO_DONE */
1707 multistate(data, CURLM_STATE_DO_DONE);
1708 rc = CURLM_CALL_MULTI_PERFORM;
1711 else if((CURLE_SEND_ERROR == result) &&
1712 data->easy_conn->bits.reuse) {
1714 * In this situation, a connection that we were trying to use
1715 * may have unexpectedly died. If possible, send the connection
1716 * back to the CONNECT phase so we can try again.
1718 char *newurl = NULL;
1719 followtype follow = FOLLOW_NONE;
1722 drc = Curl_retry_request(data->easy_conn, &newurl);
1724 /* a failure here pretty much implies an out of memory */
1726 stream_error = TRUE;
1729 Curl_posttransfer(data);
1730 drc = multi_done(&data->easy_conn, result, FALSE);
1732 /* When set to retry the connection, we must to go back to
1733 * the CONNECT state */
1735 if(!drc || (drc == CURLE_SEND_ERROR)) {
1736 follow = FOLLOW_RETRY;
1737 drc = Curl_follow(data, newurl, follow);
1739 multistate(data, CURLM_STATE_CONNECT);
1740 rc = CURLM_CALL_MULTI_PERFORM;
1749 /* done didn't return OK or SEND_ERROR */
1754 /* Have error handler disconnect conn if we can't retry */
1755 stream_error = TRUE;
1760 /* failure detected */
1761 Curl_posttransfer(data);
1763 multi_done(&data->easy_conn, result, FALSE);
1764 stream_error = TRUE;
1769 case CURLM_STATE_DOING:
1770 /* we continue DOING until the DO phase is complete */
1771 result = Curl_protocol_doing(data->easy_conn,
1775 /* after DO, go DO_DONE or DO_MORE */
1776 multistate(data, data->easy_conn->bits.do_more?
1777 CURLM_STATE_DO_MORE:
1778 CURLM_STATE_DO_DONE);
1779 rc = CURLM_CALL_MULTI_PERFORM;
1780 } /* dophase_done */
1783 /* failure detected */
1784 Curl_posttransfer(data);
1785 multi_done(&data->easy_conn, result, FALSE);
1786 stream_error = TRUE;
1790 case CURLM_STATE_DO_MORE:
1792 * When we are connected, DO MORE and then go DO_DONE
1794 result = multi_do_more(data->easy_conn, &control);
1796 /* No need to remove this handle from the send pipeline here since that
1797 is done in multi_done() */
1800 /* if positive, advance to DO_DONE
1801 if negative, go back to DOING */
1802 multistate(data, control == 1?
1803 CURLM_STATE_DO_DONE:
1805 rc = CURLM_CALL_MULTI_PERFORM;
1808 /* stay in DO_MORE */
1812 /* failure detected */
1813 Curl_posttransfer(data);
1814 multi_done(&data->easy_conn, result, FALSE);
1815 stream_error = TRUE;
1819 case CURLM_STATE_DO_DONE:
1820 /* Move ourselves from the send to recv pipeline */
1821 Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
1823 if(data->easy_conn->bits.multiplex || data->easy_conn->send_pipe.size)
1824 /* Check if we can move pending requests to send pipe */
1825 process_pending_handles(multi); /* pipelined/multiplexed */
1827 /* Only perform the transfer if there's a good socket to work with.
1828 Having both BAD is a signal to skip immediately to DONE */
1829 if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
1830 (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
1831 multistate(data, CURLM_STATE_WAITPERFORM);
1833 if(data->state.wildcardmatch &&
1834 ((data->easy_conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
1835 data->wildcard.state = CURLWC_DONE;
1837 multistate(data, CURLM_STATE_DONE);
1839 rc = CURLM_CALL_MULTI_PERFORM;
1842 case CURLM_STATE_WAITPERFORM:
1843 /* Wait for our turn to PERFORM */
1844 if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
1845 /* Grabbed the channel */
1846 multistate(data, CURLM_STATE_PERFORM);
1847 rc = CURLM_CALL_MULTI_PERFORM;
1851 case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1852 /* if both rates are within spec, resume transfer */
1853 if(Curl_pgrsUpdate(data->easy_conn))
1854 result = CURLE_ABORTED_BY_CALLBACK;
1856 result = Curl_speedcheck(data, now);
1859 send_timeout_ms = 0;
1860 if(data->set.max_send_speed > 0)
1862 Curl_pgrsLimitWaitTime(data->progress.uploaded,
1863 data->progress.ul_limit_size,
1864 data->set.max_send_speed,
1865 data->progress.ul_limit_start,
1868 recv_timeout_ms = 0;
1869 if(data->set.max_recv_speed > 0)
1871 Curl_pgrsLimitWaitTime(data->progress.downloaded,
1872 data->progress.dl_limit_size,
1873 data->set.max_recv_speed,
1874 data->progress.dl_limit_start,
1877 if(!send_timeout_ms && !recv_timeout_ms) {
1878 multistate(data, CURLM_STATE_PERFORM);
1879 Curl_ratelimit(data, now);
1881 else if(send_timeout_ms >= recv_timeout_ms)
1882 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
1884 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
1888 case CURLM_STATE_PERFORM:
1890 char *newurl = NULL;
1892 bool comeback = FALSE;
1894 /* check if over send speed */
1895 send_timeout_ms = 0;
1896 if(data->set.max_send_speed > 0)
1897 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
1898 data->progress.ul_limit_size,
1899 data->set.max_send_speed,
1900 data->progress.ul_limit_start,
1903 /* check if over recv speed */
1904 recv_timeout_ms = 0;
1905 if(data->set.max_recv_speed > 0)
1906 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
1907 data->progress.dl_limit_size,
1908 data->set.max_recv_speed,
1909 data->progress.dl_limit_start,
1912 if(send_timeout_ms || recv_timeout_ms) {
1913 Curl_ratelimit(data, now);
1914 multistate(data, CURLM_STATE_TOOFAST);
1915 if(send_timeout_ms >= recv_timeout_ms)
1916 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
1918 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
1922 /* read/write data if it is ready to do so */
1923 result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
1927 if(!(k->keepon & KEEP_RECV))
1928 /* We're done receiving */
1929 Curl_pipeline_leave_read(data->easy_conn);
1931 if(!(k->keepon & KEEP_SEND))
1932 /* We're done sending */
1933 Curl_pipeline_leave_write(data->easy_conn);
1935 if(done || (result == CURLE_RECV_ERROR)) {
1936 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
1937 * condition and the server closed the re-used connection exactly when
1938 * we wanted to use it, so figure out if that is indeed the case.
1940 CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
1942 retry = (newurl)?TRUE:FALSE;
1947 /* if we are to retry, set the result to OK and consider the
1956 * The transfer phase returned error, we mark the connection to get
1957 * closed to prevent being re-used. This is because we can't possibly
1958 * know if the connection is in a good shape or not now. Unless it is
1959 * a protocol which uses two "channels" like FTP, as then the error
1960 * happened in the data connection.
1963 if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
1964 result != CURLE_HTTP2_STREAM)
1965 streamclose(data->easy_conn, "Transfer returned error");
1967 Curl_posttransfer(data);
1968 multi_done(&data->easy_conn, result, TRUE);
1971 followtype follow = FOLLOW_NONE;
1973 /* call this even if the readwrite function returned error */
1974 Curl_posttransfer(data);
1976 /* we're no longer receiving */
1977 Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
1979 /* expire the new receiving pipeline head */
1980 if(data->easy_conn->recv_pipe.head)
1981 Curl_expire(data->easy_conn->recv_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
1983 /* When we follow redirects or is set to retry the connection, we must
1984 to go back to the CONNECT state */
1985 if(data->req.newurl || retry) {
1987 /* if the URL is a follow-location and not just a retried request
1988 then figure out the URL here */
1990 newurl = data->req.newurl;
1991 data->req.newurl = NULL;
1992 follow = FOLLOW_REDIR;
1995 follow = FOLLOW_RETRY;
1996 result = multi_done(&data->easy_conn, CURLE_OK, FALSE);
1998 result = Curl_follow(data, newurl, follow);
2000 multistate(data, CURLM_STATE_CONNECT);
2001 rc = CURLM_CALL_MULTI_PERFORM;
2007 /* after the transfer is done, go DONE */
2009 /* but first check to see if we got a location info even though we're
2010 not following redirects */
2011 if(data->req.location) {
2013 newurl = data->req.location;
2014 data->req.location = NULL;
2015 result = Curl_follow(data, newurl, FOLLOW_FAKE);
2018 stream_error = TRUE;
2019 result = multi_done(&data->easy_conn, result, TRUE);
2024 multistate(data, CURLM_STATE_DONE);
2025 rc = CURLM_CALL_MULTI_PERFORM;
2030 rc = CURLM_CALL_MULTI_PERFORM;
2034 case CURLM_STATE_DONE:
2035 /* this state is highly transient, so run another loop after this */
2036 rc = CURLM_CALL_MULTI_PERFORM;
2038 if(data->easy_conn) {
2041 /* Remove ourselves from the receive pipeline, if we are there. */
2042 Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
2044 if(data->easy_conn->bits.multiplex || data->easy_conn->send_pipe.size)
2045 /* Check if we can move pending requests to connection */
2046 process_pending_handles(multi); /* pipelined/multiplexing */
2048 /* post-transfer command */
2049 res = multi_done(&data->easy_conn, result, FALSE);
2051 /* allow a previously set error code take precedence */
2056 * If there are other handles on the pipeline, multi_done won't set
2057 * easy_conn to NULL. In such a case, curl_multi_remove_handle() can
2058 * access free'd data, if the connection is free'd and the handle
2059 * removed before we perform the processing in CURLM_STATE_COMPLETED
2062 data->easy_conn = NULL;
2065 if(data->state.wildcardmatch) {
2066 if(data->wildcard.state != CURLWC_DONE) {
2067 /* if a wildcard is set and we are not ending -> lets start again
2068 with CURLM_STATE_INIT */
2069 multistate(data, CURLM_STATE_INIT);
2074 /* after we have DONE what we're supposed to do, go COMPLETED, and
2075 it doesn't matter what the multi_done() returned! */
2076 multistate(data, CURLM_STATE_COMPLETED);
2079 case CURLM_STATE_COMPLETED:
2082 case CURLM_STATE_MSGSENT:
2083 data->result = result;
2084 return CURLM_OK; /* do nothing */
2087 return CURLM_INTERNAL_ERROR;
2091 if(data->mstate < CURLM_STATE_COMPLETED) {
2094 * If an error was returned, and we aren't in completed state now,
2095 * then we go to completed and consider this transfer aborted.
2098 /* NOTE: no attempt to disconnect connections must be made
2099 in the case blocks above - cleanup happens only here */
2101 /* Check if we can move pending requests to send pipe */
2102 process_pending_handles(multi); /* connection */
2104 if(data->easy_conn) {
2105 /* if this has a connection, unsubscribe from the pipelines */
2106 Curl_pipeline_leave_write(data->easy_conn);
2107 Curl_pipeline_leave_read(data->easy_conn);
2108 Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
2109 Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
2112 /* Don't attempt to send data over a connection that timed out */
2113 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2114 /* disconnect properly */
2115 Curl_disconnect(data, data->easy_conn, dead_connection);
2117 /* This is where we make sure that the easy_conn pointer is reset.
2118 We don't have to do this in every case block above where a
2119 failure is detected */
2120 data->easy_conn = NULL;
2123 else if(data->mstate == CURLM_STATE_CONNECT) {
2124 /* Curl_connect() failed */
2125 (void)Curl_posttransfer(data);
2128 multistate(data, CURLM_STATE_COMPLETED);
2129 rc = CURLM_CALL_MULTI_PERFORM;
2131 /* if there's still a connection to use, call the progress function */
2132 else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
2133 /* aborted due to progress callback return code must close the
2135 result = CURLE_ABORTED_BY_CALLBACK;
2136 streamclose(data->easy_conn, "Aborted by callback");
2138 /* if not yet in DONE state, go there, otherwise COMPLETED */
2139 multistate(data, (data->mstate < CURLM_STATE_DONE)?
2140 CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
2141 rc = CURLM_CALL_MULTI_PERFORM;
2145 if(CURLM_STATE_COMPLETED == data->mstate) {
2146 if(data->set.fmultidone) {
2147 /* signal via callback instead */
2148 data->set.fmultidone(data, result);
2151 /* now fill in the Curl_message with this info */
2154 msg->extmsg.msg = CURLMSG_DONE;
2155 msg->extmsg.easy_handle = data;
2156 msg->extmsg.data.result = result;
2158 rc = multi_addmsg(multi, msg);
2159 DEBUGASSERT(!data->easy_conn);
2161 multistate(data, CURLM_STATE_MSGSENT);
2163 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2165 data->result = result;
2170 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
2172 struct Curl_easy *data;
2173 CURLMcode returncode = CURLM_OK;
2174 struct Curl_tree *t;
2175 struct curltime now = Curl_now();
2177 if(!GOOD_MULTI_HANDLE(multi))
2178 return CURLM_BAD_HANDLE;
2180 if(multi->in_callback)
2181 return CURLM_RECURSIVE_API_CALL;
2183 data = multi->easyp;
2186 SIGPIPE_VARIABLE(pipe_st);
2188 sigpipe_ignore(data, &pipe_st);
2189 result = multi_runsingle(multi, now, data);
2190 sigpipe_restore(&pipe_st);
2193 returncode = result;
2195 data = data->next; /* operate on next handle */
2199 * Simply remove all expired timers from the splay since handles are dealt
2200 * with unconditionally by this function and curl_multi_timeout() requires
2201 * that already passed/handled expire times are removed from the splay.
2203 * It is important that the 'now' value is set at the entry of this function
2204 * and not for the current time as it may have ticked a little while since
2205 * then and then we risk this loop to remove timers that actually have not
2209 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2211 /* the removed may have another timeout in queue */
2212 (void)add_next_timeout(now, multi, t->payload);
2216 *running_handles = multi->num_alive;
2218 if(CURLM_OK >= returncode)
2219 update_timer(multi);
2224 CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
2226 struct Curl_easy *data;
2227 struct Curl_easy *nextdata;
2229 if(GOOD_MULTI_HANDLE(multi)) {
2230 if(multi->in_callback)
2231 return CURLM_RECURSIVE_API_CALL;
2233 multi->type = 0; /* not good anymore */
2235 /* Firsrt remove all remaining easy handles */
2236 data = multi->easyp;
2238 nextdata = data->next;
2239 if(!data->state.done && data->easy_conn)
2240 /* if DONE was never called for this handle */
2241 (void)multi_done(&data->easy_conn, CURLE_OK, TRUE);
2242 if(data->dns.hostcachetype == HCACHE_MULTI) {
2243 /* clear out the usage of the shared DNS cache */
2244 Curl_hostcache_clean(data, data->dns.hostcache);
2245 data->dns.hostcache = NULL;
2246 data->dns.hostcachetype = HCACHE_NONE;
2249 /* Clear the pointer to the connection cache */
2250 data->state.conn_cache = NULL;
2251 data->multi = NULL; /* clear the association */
2254 if(data->psl == &multi->psl)
2261 /* Close all the connections in the connection cache */
2262 Curl_conncache_close_all_connections(&multi->conn_cache);
2264 Curl_hash_destroy(&multi->sockhash);
2265 Curl_conncache_destroy(&multi->conn_cache);
2266 Curl_llist_destroy(&multi->msglist, NULL);
2267 Curl_llist_destroy(&multi->pending, NULL);
2269 Curl_hash_destroy(&multi->hostcache);
2270 Curl_psl_destroy(&multi->psl);
2272 /* Free the blacklists by setting them to NULL */
2273 Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
2274 Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
2280 return CURLM_BAD_HANDLE;
2284 * curl_multi_info_read()
2286 * This function is the primary way for a multi/multi_socket application to
2287 * figure out if a transfer has ended. We MUST make this function as fast as
2288 * possible as it will be polled frequently and we MUST NOT scan any lists in
2289 * here to figure out things. We must scale fine to thousands of handles and
2290 * beyond. The current design is fully O(1).
2293 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
2295 struct Curl_message *msg;
2297 *msgs_in_queue = 0; /* default to none */
2299 if(GOOD_MULTI_HANDLE(multi) &&
2300 !multi->in_callback &&
2301 Curl_llist_count(&multi->msglist)) {
2302 /* there is one or more messages in the list */
2303 struct curl_llist_element *e;
2305 /* extract the head of the list to return */
2306 e = multi->msglist.head;
2310 /* remove the extracted entry */
2311 Curl_llist_remove(&multi->msglist, e, NULL);
2313 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
2315 return &msg->extmsg;
2321 * singlesocket() checks what sockets we deal with and their "action state"
2322 * and if we have a different state in any of those sockets from last time we
2323 * call the callback accordingly.
2325 static CURLMcode singlesocket(struct Curl_multi *multi,
2326 struct Curl_easy *data)
2328 curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
2330 struct Curl_sh_entry *entry;
2333 unsigned int curraction;
2335 for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
2336 socks[i] = CURL_SOCKET_BAD;
2338 /* Fill in the 'current' struct with the state as it is now: what sockets to
2339 supervise and for what actions */
2340 curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
2342 /* We have 0 .. N sockets already and we get to know about the 0 .. M
2343 sockets we should have from now on. Detect the differences, remove no
2344 longer supervised ones and add new ones */
2346 /* walk over the sockets we got right now */
2347 for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) &&
2348 (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
2350 int action = CURL_POLL_NONE;
2354 /* get it from the hash */
2355 entry = sh_getentry(&multi->sockhash, s);
2357 if(curraction & GETSOCK_READSOCK(i))
2358 action |= CURL_POLL_IN;
2359 if(curraction & GETSOCK_WRITESOCK(i))
2360 action |= CURL_POLL_OUT;
2363 /* yeps, already present so check if it has the same action set */
2364 if(entry->action == action)
2365 /* same, continue */
2369 /* this is a socket we didn't have before, add it! */
2370 entry = sh_addentry(&multi->sockhash, s, data);
2373 return CURLM_OUT_OF_MEMORY;
2376 /* we know (entry != NULL) at this point, see the logic above */
2377 if(multi->socket_cb)
2378 multi->socket_cb(data,
2381 multi->socket_userp,
2384 entry->action = action; /* store the current action state */
2387 num = i; /* number of sockets */
2389 /* when we've walked over all the sockets we should have right now, we must
2390 make sure to detect sockets that are removed */
2391 for(i = 0; i< data->numsocks; i++) {
2393 s = data->sockets[i];
2394 for(j = 0; j<num; j++) {
2396 /* this is still supervised */
2397 s = CURL_SOCKET_BAD;
2402 entry = sh_getentry(&multi->sockhash, s);
2404 /* this socket has been removed. Tell the app to remove it */
2405 bool remove_sock_from_hash = TRUE;
2407 /* check if the socket to be removed serves a connection which has
2408 other easy-s in a pipeline. In this case the socket should not be
2410 struct connectdata *easy_conn = data->easy_conn;
2412 if(easy_conn->recv_pipe.size > 1) {
2413 /* the handle should not be removed from the pipe yet */
2414 remove_sock_from_hash = FALSE;
2416 /* Update the sockhash entry to instead point to the next in line
2417 for the recv_pipe, or the first (in case this particular easy
2419 if(entry->easy == data) {
2420 if(Curl_recvpipe_head(data, easy_conn))
2421 entry->easy = easy_conn->recv_pipe.head->next->ptr;
2423 entry->easy = easy_conn->recv_pipe.head->ptr;
2426 if(easy_conn->send_pipe.size > 1) {
2427 /* the handle should not be removed from the pipe yet */
2428 remove_sock_from_hash = FALSE;
2430 /* Update the sockhash entry to instead point to the next in line
2431 for the send_pipe, or the first (in case this particular easy
2433 if(entry->easy == data) {
2434 if(Curl_sendpipe_head(data, easy_conn))
2435 entry->easy = easy_conn->send_pipe.head->next->ptr;
2437 entry->easy = easy_conn->send_pipe.head->ptr;
2440 /* Don't worry about overwriting recv_pipe head with send_pipe_head,
2441 when action will be asked on the socket (see multi_socket()), the
2442 head of the correct pipe will be taken according to the
2446 if(remove_sock_from_hash) {
2447 /* in this case 'entry' is always non-NULL */
2448 if(multi->socket_cb)
2449 multi->socket_cb(data,
2452 multi->socket_userp,
2454 sh_delentry(&multi->sockhash, s);
2456 } /* if sockhash entry existed */
2457 } /* for loop over numsocks */
2459 memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
2460 data->numsocks = num;
2464 void Curl_updatesocket(struct Curl_easy *data)
2466 singlesocket(data->multi, data);
2471 * Curl_multi_closed()
2473 * Used by the connect code to tell the multi_socket code that one of the
2474 * sockets we were using is about to be closed. This function will then
2475 * remove it from the sockethash for this handle to make the multi_socket API
2476 * behave properly, especially for the case when libcurl will create another
2477 * socket again and it gets the same file descriptor number.
2480 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
2483 /* if there's still an easy handle associated with this connection */
2484 struct Curl_multi *multi = conn->data->multi;
2486 /* this is set if this connection is part of a handle that is added to
2487 a multi handle, and only then this is necessary */
2488 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2491 if(multi->socket_cb)
2492 multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
2493 multi->socket_userp,
2496 /* now remove it from the socket hash */
2497 sh_delentry(&multi->sockhash, s);
2504 * add_next_timeout()
2506 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
2507 * when it has just been removed from the splay tree because the timeout has
2508 * expired. This function is then to advance in the list to pick the next
2509 * timeout to use (skip the already expired ones) and add this node back to
2510 * the splay tree again.
2512 * The splay tree only has each sessionhandle as a single node and the nearest
2513 * timeout is used to sort it on.
2515 static CURLMcode add_next_timeout(struct curltime now,
2516 struct Curl_multi *multi,
2517 struct Curl_easy *d)
2519 struct curltime *tv = &d->state.expiretime;
2520 struct curl_llist *list = &d->state.timeoutlist;
2521 struct curl_llist_element *e;
2522 struct time_node *node = NULL;
2524 /* move over the timeout list for this specific handle and remove all
2525 timeouts that are now passed tense and store the next pending
2527 for(e = list->head; e;) {
2528 struct curl_llist_element *n = e->next;
2530 node = (struct time_node *)e->ptr;
2531 diff = Curl_timediff(node->time, now);
2533 /* remove outdated entry */
2534 Curl_llist_remove(list, e, NULL);
2536 /* the list is sorted so get out on the first mismatch */
2542 /* clear the expire times within the handles that we remove from the
2548 /* copy the first entry to 'tv' */
2549 memcpy(tv, &node->time, sizeof(*tv));
2551 /* Insert this node again into the splay. Keep the timer in the list in
2552 case we need to recompute future timers. */
2553 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2554 &d->state.timenode);
2559 static CURLMcode multi_socket(struct Curl_multi *multi,
2563 int *running_handles)
2565 CURLMcode result = CURLM_OK;
2566 struct Curl_easy *data = NULL;
2567 struct Curl_tree *t;
2568 struct curltime now = Curl_now();
2571 /* *perform() deals with running_handles on its own */
2572 result = curl_multi_perform(multi, running_handles);
2574 /* walk through each easy handle and do the socket state change magic
2576 if(result != CURLM_BAD_HANDLE) {
2577 data = multi->easyp;
2578 while(data && !result) {
2579 result = singlesocket(multi, data);
2584 /* or should we fall-through and do the timer-based stuff? */
2587 if(s != CURL_SOCKET_TIMEOUT) {
2589 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2592 /* Unmatched socket, we can't act on it but we ignore this fact. In
2593 real-world tests it has been proved that libevent can in fact give
2594 the application actions even though the socket was just previously
2595 asked to get removed, so thus we better survive stray socket actions
2596 and just move on. */
2599 SIGPIPE_VARIABLE(pipe_st);
2603 if(data->magic != CURLEASY_MAGIC_NUMBER)
2604 /* bad bad bad bad bad bad bad */
2605 return CURLM_INTERNAL_ERROR;
2607 /* If the pipeline is enabled, take the handle which is in the head of
2608 the pipeline. If we should write into the socket, take the send_pipe
2609 head. If we should read from the socket, take the recv_pipe head. */
2610 if(data->easy_conn) {
2611 if((ev_bitmask & CURL_POLL_OUT) &&
2612 data->easy_conn->send_pipe.head)
2613 data = data->easy_conn->send_pipe.head->ptr;
2614 else if((ev_bitmask & CURL_POLL_IN) &&
2615 data->easy_conn->recv_pipe.head)
2616 data = data->easy_conn->recv_pipe.head->ptr;
2619 if(data->easy_conn &&
2620 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2621 /* set socket event bitmask if they're not locked */
2622 data->easy_conn->cselect_bits = ev_bitmask;
2624 sigpipe_ignore(data, &pipe_st);
2625 result = multi_runsingle(multi, now, data);
2626 sigpipe_restore(&pipe_st);
2628 if(data->easy_conn &&
2629 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2630 /* clear the bitmask only if not locked */
2631 data->easy_conn->cselect_bits = 0;
2633 if(CURLM_OK >= result) {
2634 /* get the socket(s) and check if the state has been changed since
2636 result = singlesocket(multi, data);
2641 /* Now we fall-through and do the timer-based stuff, since we don't want
2642 to force the user to have to deal with timeouts as long as at least
2643 one connection in fact has traffic. */
2645 data = NULL; /* set data to NULL again to avoid calling
2646 multi_runsingle() in case there's no need to */
2647 now = Curl_now(); /* get a newer time since the multi_runsingle() loop
2648 may have taken some time */
2652 /* Asked to run due to time-out. Clear the 'lastcall' variable to force
2653 update_timer() to trigger a callback to the app again even if the same
2654 timeout is still the one to run after this call. That handles the case
2655 when the application asks libcurl to run the timeout prematurely. */
2656 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
2660 * The loop following here will go on as long as there are expire-times left
2661 * to process in the splay and 'data' will be re-assigned for every expired
2662 * handle we deal with.
2665 /* the first loop lap 'data' can be NULL */
2667 SIGPIPE_VARIABLE(pipe_st);
2669 sigpipe_ignore(data, &pipe_st);
2670 result = multi_runsingle(multi, now, data);
2671 sigpipe_restore(&pipe_st);
2673 if(CURLM_OK >= result) {
2674 /* get the socket(s) and check if the state has been changed since
2676 result = singlesocket(multi, data);
2682 /* Check if there's one (more) expired timer to deal with! This function
2683 extracts a matching node if there is one */
2685 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2687 data = t->payload; /* assign this for next loop */
2688 (void)add_next_timeout(now, multi, t->payload);
2693 *running_handles = multi->num_alive;
2697 #undef curl_multi_setopt
2698 CURLMcode curl_multi_setopt(struct Curl_multi *multi,
2699 CURLMoption option, ...)
2701 CURLMcode res = CURLM_OK;
2704 if(!GOOD_MULTI_HANDLE(multi))
2705 return CURLM_BAD_HANDLE;
2707 if(multi->in_callback)
2708 return CURLM_RECURSIVE_API_CALL;
2710 va_start(param, option);
2713 case CURLMOPT_SOCKETFUNCTION:
2714 multi->socket_cb = va_arg(param, curl_socket_callback);
2716 case CURLMOPT_SOCKETDATA:
2717 multi->socket_userp = va_arg(param, void *);
2719 case CURLMOPT_PUSHFUNCTION:
2720 multi->push_cb = va_arg(param, curl_push_callback);
2722 case CURLMOPT_PUSHDATA:
2723 multi->push_userp = va_arg(param, void *);
2725 case CURLMOPT_PIPELINING:
2726 multi->pipelining = va_arg(param, long) & CURLPIPE_MULTIPLEX;
2728 case CURLMOPT_TIMERFUNCTION:
2729 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
2731 case CURLMOPT_TIMERDATA:
2732 multi->timer_userp = va_arg(param, void *);
2734 case CURLMOPT_MAXCONNECTS:
2735 multi->maxconnects = va_arg(param, long);
2737 case CURLMOPT_MAX_HOST_CONNECTIONS:
2738 multi->max_host_connections = va_arg(param, long);
2740 case CURLMOPT_MAX_PIPELINE_LENGTH:
2741 multi->max_pipeline_length = va_arg(param, long);
2743 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
2744 multi->content_length_penalty_size = va_arg(param, long);
2746 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
2747 multi->chunk_length_penalty_size = va_arg(param, long);
2749 case CURLMOPT_PIPELINING_SITE_BL:
2750 res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
2751 &multi->pipelining_site_bl);
2753 case CURLMOPT_PIPELINING_SERVER_BL:
2754 res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
2755 &multi->pipelining_server_bl);
2757 case CURLMOPT_MAX_TOTAL_CONNECTIONS:
2758 multi->max_total_connections = va_arg(param, long);
2761 res = CURLM_UNKNOWN_OPTION;
2768 /* we define curl_multi_socket() in the public multi.h header */
2769 #undef curl_multi_socket
2771 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
2772 int *running_handles)
2775 if(multi->in_callback)
2776 return CURLM_RECURSIVE_API_CALL;
2777 result = multi_socket(multi, FALSE, s, 0, running_handles);
2778 if(CURLM_OK >= result)
2779 update_timer(multi);
2783 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
2784 int ev_bitmask, int *running_handles)
2787 if(multi->in_callback)
2788 return CURLM_RECURSIVE_API_CALL;
2789 result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
2790 if(CURLM_OK >= result)
2791 update_timer(multi);
2795 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
2799 if(multi->in_callback)
2800 return CURLM_RECURSIVE_API_CALL;
2801 result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
2802 if(CURLM_OK >= result)
2803 update_timer(multi);
2807 static CURLMcode multi_timeout(struct Curl_multi *multi,
2810 static struct curltime tv_zero = {0, 0};
2812 if(multi->timetree) {
2813 /* we have a tree of expire times */
2814 struct curltime now = Curl_now();
2816 /* splay the lowest to the bottom */
2817 multi->timetree = Curl_splay(tv_zero, multi->timetree);
2819 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
2820 /* some time left before expiration */
2821 timediff_t diff = Curl_timediff(multi->timetree->key, now);
2824 * Since we only provide millisecond resolution on the returned value
2825 * and the diff might be less than one millisecond here, we don't
2826 * return zero as that may cause short bursts of busyloops on fast
2827 * processors while the diff is still present but less than one
2828 * millisecond! instead we return 1 until the time is ripe.
2832 /* this should be safe even on 64 bit archs, as we don't use that
2833 overly long timeouts */
2834 *timeout_ms = (long)diff;
2837 /* 0 means immediately */
2846 CURLMcode curl_multi_timeout(struct Curl_multi *multi,
2849 /* First, make some basic checks that the CURLM handle is a good handle */
2850 if(!GOOD_MULTI_HANDLE(multi))
2851 return CURLM_BAD_HANDLE;
2853 if(multi->in_callback)
2854 return CURLM_RECURSIVE_API_CALL;
2856 return multi_timeout(multi, timeout_ms);
2860 * Tell the application it should update its timers, if it subscribes to the
2861 * update timer callback.
2863 static int update_timer(struct Curl_multi *multi)
2867 if(!multi->timer_cb)
2869 if(multi_timeout(multi, &timeout_ms)) {
2872 if(timeout_ms < 0) {
2873 static const struct curltime none = {0, 0};
2874 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
2875 multi->timer_lastcall = none;
2876 /* there's no timeout now but there was one previously, tell the app to
2878 return multi->timer_cb(multi, -1, multi->timer_userp);
2883 /* When multi_timeout() is done, multi->timetree points to the node with the
2884 * timeout we got the (relative) time-out time for. We can thus easily check
2885 * if this is the same (fixed) time as we got in a previous call and then
2886 * avoid calling the callback again. */
2887 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
2890 multi->timer_lastcall = multi->timetree->key;
2892 return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
2896 * multi_deltimeout()
2898 * Remove a given timestamp from the list of timeouts.
2901 multi_deltimeout(struct Curl_easy *data, expire_id eid)
2903 struct curl_llist_element *e;
2904 struct curl_llist *timeoutlist = &data->state.timeoutlist;
2905 /* find and remove the specific node from the list */
2906 for(e = timeoutlist->head; e; e = e->next) {
2907 struct time_node *n = (struct time_node *)e->ptr;
2909 Curl_llist_remove(timeoutlist, e, NULL);
2916 * multi_addtimeout()
2918 * Add a timestamp to the list of timeouts. Keep the list sorted so that head
2919 * of list is always the timeout nearest in time.
2923 multi_addtimeout(struct Curl_easy *data,
2924 struct curltime *stamp,
2927 struct curl_llist_element *e;
2928 struct time_node *node;
2929 struct curl_llist_element *prev = NULL;
2931 struct curl_llist *timeoutlist = &data->state.timeoutlist;
2933 node = &data->state.expires[eid];
2935 /* copy the timestamp and id */
2936 memcpy(&node->time, stamp, sizeof(*stamp));
2937 node->eid = eid; /* also marks it as in use */
2939 n = Curl_llist_count(timeoutlist);
2941 /* find the correct spot in the list */
2942 for(e = timeoutlist->head; e; e = e->next) {
2943 struct time_node *check = (struct time_node *)e->ptr;
2944 timediff_t diff = Curl_timediff(check->time, node->time);
2952 this is the first timeout on the list */
2954 Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
2961 * given a number of milliseconds from now to use to set the 'act before
2962 * this'-time for the transfer, to be extracted by curl_multi_timeout()
2964 * The timeout will be added to a queue of timeouts if it defines a moment in
2965 * time that is later than the current head of queue.
2967 * Expire replaces a former timeout using the same id if already set.
2969 void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
2971 struct Curl_multi *multi = data->multi;
2972 struct curltime *nowp = &data->state.expiretime;
2973 struct curltime set;
2975 /* this is only interesting while there is still an associated multi struct
2980 DEBUGASSERT(id < EXPIRE_LAST);
2983 set.tv_sec += milli/1000;
2984 set.tv_usec += (unsigned int)(milli%1000)*1000;
2986 if(set.tv_usec >= 1000000) {
2988 set.tv_usec -= 1000000;
2991 /* Remove any timer with the same id just in case. */
2992 multi_deltimeout(data, id);
2994 /* Add it to the timer list. It must stay in the list until it has expired
2995 in case we need to recompute the minimum timer later. */
2996 multi_addtimeout(data, &set, id);
2998 if(nowp->tv_sec || nowp->tv_usec) {
2999 /* This means that the struct is added as a node in the splay tree.
3000 Compare if the new time is earlier, and only remove-old/add-new if it
3002 timediff_t diff = Curl_timediff(set, *nowp);
3006 /* The current splay tree entry is sooner than this new expiry time.
3007 We don't need to update our splay tree entry. */
3011 /* Since this is an updated time, we must remove the previous entry from
3012 the splay tree first and then re-add the new value */
3013 rc = Curl_splayremovebyaddr(multi->timetree,
3014 &data->state.timenode,
3017 infof(data, "Internal error removing splay node = %d\n", rc);
3020 /* Indicate that we are in the splay tree and insert the new timer expiry
3021 value since it is our local minimum. */
3023 data->state.timenode.payload = data;
3024 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
3025 &data->state.timenode);
3029 * Curl_expire_done()
3031 * Removes the expire timer. Marks it as done.
3034 void Curl_expire_done(struct Curl_easy *data, expire_id id)
3036 /* remove the timer, if there */
3037 multi_deltimeout(data, id);
3041 * Curl_expire_clear()
3043 * Clear ALL timeout values for this handle.
3045 void Curl_expire_clear(struct Curl_easy *data)
3047 struct Curl_multi *multi = data->multi;
3048 struct curltime *nowp = &data->state.expiretime;
3050 /* this is only interesting while there is still an associated multi struct
3055 if(nowp->tv_sec || nowp->tv_usec) {
3056 /* Since this is an cleared time, we must remove the previous entry from
3058 struct curl_llist *list = &data->state.timeoutlist;
3061 rc = Curl_splayremovebyaddr(multi->timetree,
3062 &data->state.timenode,
3065 infof(data, "Internal error clearing splay node = %d\n", rc);
3067 /* flush the timeout list too */
3068 while(list->size > 0) {
3069 Curl_llist_remove(list, list->tail, NULL);
3073 infof(data, "Expire cleared\n");
3083 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
3086 struct Curl_sh_entry *there = NULL;
3088 if(multi->in_callback)
3089 return CURLM_RECURSIVE_API_CALL;
3091 there = sh_getentry(&multi->sockhash, s);
3094 return CURLM_BAD_SOCKET;
3096 there->socketp = hashp;
3101 size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
3103 return multi ? multi->max_host_connections : 0;
3106 size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
3108 return multi ? multi->max_total_connections : 0;
3111 curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
3113 return multi ? multi->content_length_penalty_size : 0;
3116 curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
3118 return multi ? multi->chunk_length_penalty_size : 0;
3121 struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
3123 return &multi->pipelining_site_bl;
3126 struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
3128 return &multi->pipelining_server_bl;
3131 static void process_pending_handles(struct Curl_multi *multi)
3133 struct curl_llist_element *e = multi->pending.head;
3135 struct Curl_easy *data = e->ptr;
3137 DEBUGASSERT(data->mstate == CURLM_STATE_CONNECT_PEND);
3139 multistate(data, CURLM_STATE_CONNECT);
3141 /* Remove this node from the list */
3142 Curl_llist_remove(&multi->pending, e, NULL);
3144 /* Make sure that the handle will be processed soonish. */
3145 Curl_expire(data, 0, EXPIRE_RUN_NOW);
3149 void Curl_set_in_callback(struct Curl_easy *data, bool value)
3151 /* might get called when there is no data pointer! */
3153 if(data->multi_easy)
3154 data->multi_easy->in_callback = value;
3155 else if(data->multi)
3156 data->multi->in_callback = value;
3160 bool Curl_is_in_callback(struct Curl_easy *easy)
3162 return ((easy->multi && easy->multi->in_callback) ||
3163 (easy->multi_easy && easy->multi_easy->in_callback));
3167 void Curl_multi_dump(struct Curl_multi *multi)
3169 struct Curl_easy *data;
3171 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
3172 multi->num_easy, multi->num_alive);
3173 for(data = multi->easyp; data; data = data->next) {
3174 if(data->mstate < CURLM_STATE_COMPLETED) {
3175 /* only display handles that are not completed */
3176 fprintf(stderr, "handle %p, state %s, %d sockets\n",
3178 statename[data->mstate], data->numsocks);
3179 for(i = 0; i < data->numsocks; i++) {
3180 curl_socket_t s = data->sockets[i];
3181 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3183 fprintf(stderr, "%d ", (int)s);
3185 fprintf(stderr, "INTERNAL CONFUSION\n");
3188 fprintf(stderr, "[%s %s] ",
3189 entry->action&CURL_POLL_IN?"RECVING":"",
3190 entry->action&CURL_POLL_OUT?"SENDING":"");
3193 fprintf(stderr, "\n");