1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, 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>
40 #include "speedcheck.h"
41 #include "conncache.h"
42 #include "multihandle.h"
45 #include "vtls/vtls.h"
47 /* The last 3 #include files should be in this order */
48 #include "curl_printf.h"
49 #include "curl_memory.h"
53 CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
54 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
55 CURL handle takes 45-50 K memory, therefore this 3K are not significant.
57 #ifndef CURL_SOCKET_HASH_TABLE_SIZE
58 #define CURL_SOCKET_HASH_TABLE_SIZE 911
61 #define CURL_CONNECTION_HASH_SIZE 97
63 #define CURL_MULTI_HANDLE 0x000bab1e
65 #define GOOD_MULTI_HANDLE(x) \
66 ((x) && (x)->type == CURL_MULTI_HANDLE)
68 static void singlesocket(struct Curl_multi *multi,
69 struct Curl_easy *data);
70 static int update_timer(struct Curl_multi *multi);
72 static CURLMcode add_next_timeout(struct timeval now,
73 struct Curl_multi *multi,
75 static CURLMcode multi_timeout(struct Curl_multi *multi,
79 static const char * const statename[]={
102 static void multi_freetimeout(void *a, void *b);
104 /* function pointer called once when switching TO a state */
105 typedef void (*init_multistate_func)(struct Curl_easy *data);
107 /* always use this function to change state, to make debugging easier */
108 static void mstate(struct Curl_easy *data, CURLMstate state
114 CURLMstate oldstate = data->mstate;
115 static const init_multistate_func finit[CURLM_STATE_LAST] = {
118 Curl_init_CONNECT, /* CONNECT */
119 /* the rest is NULL too */
122 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
126 if(oldstate == state)
127 /* don't bother when the new state is the same as the old state */
130 data->mstate = state;
132 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
133 if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
134 data->mstate < CURLM_STATE_COMPLETED) {
135 long connection_id = -5000;
138 connection_id = data->easy_conn->connection_id;
141 "STATE: %s => %s handle %p; line %d (connection #%ld)\n",
142 statename[oldstate], statename[data->mstate],
143 (void *)data, lineno, connection_id);
147 if(state == CURLM_STATE_COMPLETED)
148 /* changing to COMPLETED means there's one less easy handle 'alive' */
149 data->multi->num_alive--;
151 /* if this state has an init-function, run it */
157 #define multistate(x,y) mstate(x,y)
159 #define multistate(x,y) mstate(x,y, __LINE__)
163 * We add one of these structs to the sockhash for a particular socket
166 struct Curl_sh_entry {
167 struct Curl_easy *easy;
168 int action; /* what action READ/WRITE this socket waits for */
169 curl_socket_t socket; /* mainly to ease debugging */
170 void *socketp; /* settable by users with curl_multi_assign() */
172 /* bits for 'action' having no bits means this socket is not expecting any
177 /* look up a given socket in the socket hash, skip invalid sockets */
178 static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
181 if(s != CURL_SOCKET_BAD)
182 /* only look for proper sockets */
183 return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
187 /* make sure this socket is present in the hash for this handle */
188 static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
190 struct Curl_easy *data)
192 struct Curl_sh_entry *there = sh_getentry(sh, s);
193 struct Curl_sh_entry *check;
196 /* it is present, return fine */
199 /* not present, add it */
200 check = calloc(1, sizeof(struct Curl_sh_entry));
202 return NULL; /* major failure */
207 /* make/add new hash entry */
208 if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
210 return NULL; /* major failure */
213 return check; /* things are good in sockhash land */
217 /* delete the given socket + handle from the hash */
218 static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
220 /* We remove the hash entry. This will end up in a call to
222 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
226 * free a sockhash entry
228 static void sh_freeentry(void *freethis)
230 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
235 static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
237 (void) k1_len; (void) k2_len;
239 return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2));
242 static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
244 curl_socket_t fd = *((curl_socket_t *) key);
247 return (fd % slots_num);
251 * sh_init() creates a new socket hash and returns the handle for it.
253 * Quote from README.multi_socket:
255 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
256 * is somewhat of a bottle neck. Its current implementation may be a bit too
257 * limiting. It simply has a fixed-size array, and on each entry in the array
258 * it has a linked list with entries. So the hash only checks which list to
259 * scan through. The code I had used so for used a list with merely 7 slots
260 * (as that is what the DNS hash uses) but with 7000 connections that would
261 * make an average of 1000 nodes in each list to run through. I upped that to
262 * 97 slots (I believe a prime is suitable) and noticed a significant speed
263 * increase. I need to reconsider the hash implementation or use a rather
264 * large default value like this. At 9000 connections I was still below 10us
268 static int sh_init(struct curl_hash *hash, int hashsize)
270 return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
277 * Called when a transfer is completed. Adds the given msg pointer to
278 * the list kept in the multi handle.
280 static CURLMcode multi_addmsg(struct Curl_multi *multi,
281 struct Curl_message *msg)
283 if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
284 return CURLM_OUT_OF_MEMORY;
292 * Callback used by the llist system when a single list entry is destroyed.
294 static void multi_freeamsg(void *a, void *b)
300 struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
301 int chashsize) /* connection hash */
303 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
308 multi->type = CURL_MULTI_HANDLE;
310 if(Curl_mk_dnscache(&multi->hostcache))
313 if(sh_init(&multi->sockhash, hashsize))
316 if(Curl_conncache_init(&multi->conn_cache, chashsize))
319 multi->msglist = Curl_llist_alloc(multi_freeamsg);
323 multi->pending = Curl_llist_alloc(multi_freeamsg);
327 /* allocate a new easy handle to use when closing cached connections */
328 multi->closure_handle = curl_easy_init();
329 if(!multi->closure_handle)
332 multi->closure_handle->multi = multi;
333 multi->closure_handle->state.conn_cache = &multi->conn_cache;
335 multi->max_pipeline_length = 5;
337 /* -1 means it not set by user, use the default value */
338 multi->maxconnects = -1;
343 Curl_hash_destroy(&multi->sockhash);
344 Curl_hash_destroy(&multi->hostcache);
345 Curl_conncache_destroy(&multi->conn_cache);
346 Curl_close(multi->closure_handle);
347 multi->closure_handle = NULL;
348 Curl_llist_destroy(multi->msglist, NULL);
349 Curl_llist_destroy(multi->pending, NULL);
355 struct Curl_multi *curl_multi_init(void)
357 return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
358 CURL_CONNECTION_HASH_SIZE);
361 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
362 struct Curl_easy *data)
364 struct curl_llist *timeoutlist;
366 /* First, make some basic checks that the CURLM handle is a good handle */
367 if(!GOOD_MULTI_HANDLE(multi))
368 return CURLM_BAD_HANDLE;
370 /* Verify that we got a somewhat good easy handle too */
371 if(!GOOD_EASY_HANDLE(data))
372 return CURLM_BAD_EASY_HANDLE;
374 /* Prevent users from adding same easy handle more than once and prevent
375 adding to more than one multi stack */
377 return CURLM_ADDED_ALREADY;
379 /* Allocate and initialize timeout list for easy handle */
380 timeoutlist = Curl_llist_alloc(multi_freetimeout);
382 return CURLM_OUT_OF_MEMORY;
385 * No failure allowed in this function beyond this point. And no
386 * modification of easy nor multi handle allowed before this except for
387 * potential multi's connection cache growing which won't be undone in this
388 * function no matter what.
391 /* Make easy handle use timeout list initialized above */
392 data->state.timeoutlist = timeoutlist;
395 /* set the easy handle */
396 multistate(data, CURLM_STATE_INIT);
398 if((data->set.global_dns_cache) &&
399 (data->dns.hostcachetype != HCACHE_GLOBAL)) {
400 /* global dns cache was requested but still isn't */
401 struct curl_hash *global = Curl_global_host_cache_init();
403 /* only do this if the global cache init works */
404 data->dns.hostcache = global;
405 data->dns.hostcachetype = HCACHE_GLOBAL;
408 /* for multi interface connections, we share DNS cache automatically if the
409 easy handle's one is currently not set. */
410 else if(!data->dns.hostcache ||
411 (data->dns.hostcachetype == HCACHE_NONE)) {
412 data->dns.hostcache = &multi->hostcache;
413 data->dns.hostcachetype = HCACHE_MULTI;
416 /* Point to the multi's connection cache */
417 data->state.conn_cache = &multi->conn_cache;
419 /* This adds the new entry at the 'end' of the doubly-linked circular
420 list of Curl_easy structs to try and maintain a FIFO queue so
421 the pipelined requests are in order. */
423 /* We add this new entry last in the list. */
425 data->next = NULL; /* end of the line */
427 struct Curl_easy *last = multi->easylp;
430 multi->easylp = data; /* the new last node */
433 /* first node, make prev NULL! */
435 multi->easylp = multi->easyp = data; /* both first and last */
438 /* make the Curl_easy refer back to this multi handle */
441 /* Set the timeout for this handle to expire really soon so that it will
442 be taken care of even when this handle is added in the midst of operation
443 when only the curl_multi_socket() API is used. During that flow, only
444 sockets that time-out or have actions will be dealt with. Since this
445 handle has no action yet, we make sure it times out to get things to
447 Curl_expire(data, 0);
449 /* increase the node-counter */
452 /* increase the alive-counter */
455 /* A somewhat crude work-around for a little glitch in update_timer() that
456 happens if the lastcall time is set to the same time when the handle is
457 removed as when the next handle is added, as then the check in
458 update_timer() that prevents calling the application multiple times with
459 the same timer infor will not trigger and then the new handle's timeout
460 will not be notified to the app.
462 The work-around is thus simply to clear the 'lastcall' variable to force
463 update_timer() to always trigger a callback to the app when a new easy
465 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
467 /* The closure handle only ever has default timeouts set. To improve the
468 state somewhat we clone the timeouts from each added handle so that the
469 closure handle always has the same timeouts as the most recently added
471 multi->closure_handle->set.timeout = data->set.timeout;
472 multi->closure_handle->set.server_response_timeout =
473 data->set.server_response_timeout;
480 /* Debug-function, used like this:
482 * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
484 * Enable the hash print function first by editing hash.c
486 static void debug_print_sock_hash(void *p)
488 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
490 fprintf(stderr, " [easy %p/magic %x/socket %d]",
491 (void *)sh->data, sh->data->magic, (int)sh->socket);
495 /* Mark the connection as 'idle', or close it if the cache is full.
496 Returns TRUE if the connection is kept, or FALSE if it was closed. */
498 ConnectionDone(struct Curl_easy *data, struct connectdata *conn)
500 /* data->multi->maxconnects can be negative, deal with it. */
502 (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
503 data->multi->maxconnects;
504 struct connectdata *conn_candidate = NULL;
506 /* Mark the current connection as 'unused' */
509 if(maxconnects > 0 &&
510 data->state.conn_cache->num_connections > maxconnects) {
511 infof(data, "Connection cache is full, closing the oldest one.\n");
513 conn_candidate = Curl_oldest_idle_connection(data);
516 /* Set the connection's owner correctly */
517 conn_candidate->data = data;
519 /* the winner gets the honour of being disconnected */
520 (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
524 return (conn_candidate == conn) ? FALSE : TRUE;
527 static CURLcode multi_done(struct connectdata **connp,
528 CURLcode status, /* an error if this is called
529 after an error was detected */
533 struct connectdata *conn;
534 struct Curl_easy *data;
541 DEBUGF(infof(data, "multi_done\n"));
544 /* Stop if multi_done() has already been called */
547 Curl_getoff_all_pipelines(data, conn);
549 /* Cleanup possible redirect junk */
550 free(data->req.newurl);
551 data->req.newurl = NULL;
552 free(data->req.location);
553 data->req.location = NULL;
556 case CURLE_ABORTED_BY_CALLBACK:
557 case CURLE_READ_ERROR:
558 case CURLE_WRITE_ERROR:
559 /* When we're aborted due to a callback return code it basically have to
560 be counted as premature as there is trouble ahead if we don't. We have
561 many callbacks and protocols work differently, we could potentially do
562 this more fine-grained in the future. */
568 /* this calls the protocol-specific function pointer previously set */
569 if(conn->handler->done)
570 result = conn->handler->done(conn, status, premature);
574 if(CURLE_ABORTED_BY_CALLBACK != result) {
575 /* avoid this if we already aborted by callback to avoid this calling
577 CURLcode rc = Curl_pgrsDone(conn);
579 result = CURLE_ABORTED_BY_CALLBACK;
582 if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
583 !data->set.reuse_forbid &&
585 /* Stop if pipeline is not empty and we do not have to close
587 data->easy_conn = NULL;
588 DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
592 data->state.done = TRUE; /* called just now! */
593 Curl_resolver_cancel(conn);
595 if(conn->dns_entry) {
596 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
597 conn->dns_entry = NULL;
600 /* if the transfer was completed in a paused state there can be buffered
601 data left to write and then kill */
602 free(data->state.tempwrite);
603 data->state.tempwrite = NULL;
605 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
606 forced us to close this connection. This is ignored for requests taking
607 place in a NTLM authentication handshake
609 if conn->bits.close is TRUE, it means that the connection should be
610 closed in spite of all our efforts to be nice, due to protocol
611 restrictions in our or the server's end
613 if premature is TRUE, it means this connection was said to be DONE before
614 the entire request operation is complete and thus we can't know in what
615 state it is for re-using, so we're forced to close it. In a perfect world
616 we can add code that keep track of if we really must close it here or not,
617 but currently we have no such detail knowledge.
620 if((data->set.reuse_forbid
621 #if defined(USE_NTLM)
622 && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
623 conn->proxyntlm.state == NTLMSTATE_TYPE2)
625 ) || conn->bits.close || premature) {
626 CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
628 /* If we had an error already, make sure we return that one. But
629 if we got a new error, return that. */
634 /* the connection is no longer in use */
635 if(ConnectionDone(data, conn)) {
636 /* remember the most recently used connection */
637 data->state.lastconnect = conn;
639 infof(data, "Connection #%ld to host %s left intact\n",
641 conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
642 conn->bits.httpproxy ? conn->http_proxy.host.dispname :
643 conn->bits.conn_to_host ? conn->conn_to_host.dispname :
644 conn->host.dispname);
647 data->state.lastconnect = NULL;
650 *connp = NULL; /* to make the caller of this function better detect that
651 this was either closed or handed over to the connection
652 cache here, and therefore cannot be used from this point on
654 Curl_free_request_state(data);
659 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
660 struct Curl_easy *data)
662 struct Curl_easy *easy = data;
665 struct curl_llist_element *e;
667 /* First, make some basic checks that the CURLM handle is a good handle */
668 if(!GOOD_MULTI_HANDLE(multi))
669 return CURLM_BAD_HANDLE;
671 /* Verify that we got a somewhat good easy handle too */
672 if(!GOOD_EASY_HANDLE(data))
673 return CURLM_BAD_EASY_HANDLE;
675 /* Prevent users from trying to remove same easy handle more than once */
677 return CURLM_OK; /* it is already removed so let's say it is fine! */
679 premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
680 easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
683 /* If the 'state' is not INIT or COMPLETED, we might need to do something
684 nice to put the easy_handle in a good known state when this returns. */
686 /* this handle is "alive" so we need to count down the total number of
687 alive connections when this is removed */
690 /* When this handle gets removed, other handles may be able to get the
692 Curl_multi_process_pending_handles(multi);
695 if(data->easy_conn &&
696 data->mstate > CURLM_STATE_DO &&
697 data->mstate < CURLM_STATE_COMPLETED) {
698 /* If the handle is in a pipeline and has started sending off its
699 request but not received its response yet, we need to close
701 streamclose(data->easy_conn, "Removed with partial response");
702 /* Set connection owner so that the DONE function closes it. We can
703 safely do this here since connection is killed. */
704 data->easy_conn->data = easy;
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->dns.hostcachetype == HCACHE_MULTI) {
714 /* stop using the multi handle's DNS cache */
715 data->dns.hostcache = NULL;
716 data->dns.hostcachetype = HCACHE_NONE;
719 if(data->easy_conn) {
721 /* we must call multi_done() here (if we still own the connection) so that
722 we don't leave a half-baked one around */
725 /* multi_done() clears the conn->data field to lose the association
726 between the easy handle and the connection
728 Note that this ignores the return code simply because there's
729 nothing really useful to do with it anyway! */
730 (void)multi_done(&data->easy_conn, data->result, premature);
733 /* Clear connection pipelines, if multi_done above was not called */
734 Curl_getoff_all_pipelines(data, data->easy_conn);
737 Curl_wildcard_dtor(&data->wildcard);
739 /* destroy the timeout list that is held in the easy handle, do this *after*
740 multi_done() as that may actually call Curl_expire that uses this */
741 if(data->state.timeoutlist) {
742 Curl_llist_destroy(data->state.timeoutlist, NULL);
743 data->state.timeoutlist = NULL;
746 /* as this was using a shared connection cache we clear the pointer to that
747 since we're not part of that multi handle anymore */
748 data->state.conn_cache = NULL;
750 /* change state without using multistate(), only to make singlesocket() do
752 data->mstate = CURLM_STATE_COMPLETED;
753 singlesocket(multi, easy); /* to let the application know what sockets that
754 vanish with this handle */
756 /* Remove the association between the connection and the handle */
757 if(data->easy_conn) {
758 data->easy_conn->data = NULL;
759 data->easy_conn = NULL;
762 data->multi = NULL; /* clear the association to this multi handle */
764 /* make sure there's no pending message in the queue sent from this easy
767 for(e = multi->msglist->head; e; e = e->next) {
768 struct Curl_message *msg = e->ptr;
770 if(msg->extmsg.easy_handle == easy) {
771 Curl_llist_remove(multi->msglist, e, NULL);
772 /* there can only be one from this specific handle */
777 /* make the previous node point to our next */
779 data->prev->next = data->next;
781 multi->easyp = data->next; /* point to first node */
783 /* make our next point to our previous node */
785 data->next->prev = data->prev;
787 multi->easylp = data->prev; /* point to last node */
790 We do not touch the easy handle here! */
791 multi->num_easy--; /* one less to care about now */
797 /* Return TRUE if the application asked for a certain set of pipelining */
798 bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
800 return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
803 void Curl_multi_handlePipeBreak(struct Curl_easy *data)
805 data->easy_conn = NULL;
808 static int waitconnect_getsock(struct connectdata *conn,
817 return GETSOCK_BLANK;
820 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
821 return Curl_ssl_getsock(conn, sock, numsocks);
825 if(conn->tempsock[i] != CURL_SOCKET_BAD) {
826 sock[s] = conn->tempsock[i];
827 rc |= GETSOCK_WRITESOCK(s++);
834 static int waitproxyconnect_getsock(struct connectdata *conn,
839 return GETSOCK_BLANK;
841 sock[0] = conn->sock[FIRSTSOCKET];
843 /* when we've sent a CONNECT to a proxy, we should rather wait for the
844 socket to become readable to be able to get the response headers */
845 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
846 return GETSOCK_READSOCK(0);
848 return GETSOCK_WRITESOCK(0);
851 static int domore_getsock(struct connectdata *conn,
852 curl_socket_t *socks,
855 if(conn && conn->handler->domore_getsock)
856 return conn->handler->domore_getsock(conn, socks, numsocks);
857 return GETSOCK_BLANK;
860 /* returns bitmapped flags for this handle and its sockets */
861 static int multi_getsock(struct Curl_easy *data,
862 curl_socket_t *socks, /* points to numsocks number
866 /* If the pipe broke, or if there's no connection left for this easy handle,
867 then we MUST bail out now with no bitmask set. The no connection case can
868 happen when this is called from curl_multi_remove_handle() =>
869 singlesocket() => multi_getsock().
871 if(data->state.pipe_broke || !data->easy_conn)
874 if(data->mstate > CURLM_STATE_CONNECT &&
875 data->mstate < CURLM_STATE_COMPLETED) {
876 /* Set up ownership correctly */
877 data->easy_conn->data = data;
880 switch(data->mstate) {
882 #if 0 /* switch back on these cases to get the compiler to check for all enums
884 case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
885 case CURLM_STATE_COMPLETED:
886 case CURLM_STATE_MSGSENT:
887 case CURLM_STATE_INIT:
888 case CURLM_STATE_CONNECT:
889 case CURLM_STATE_WAITDO:
890 case CURLM_STATE_DONE:
891 case CURLM_STATE_LAST:
892 /* this will get called with CURLM_STATE_COMPLETED when a handle is
897 case CURLM_STATE_WAITRESOLVE:
898 return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
900 case CURLM_STATE_PROTOCONNECT:
901 case CURLM_STATE_SENDPROTOCONNECT:
902 return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
905 case CURLM_STATE_DOING:
906 return Curl_doing_getsock(data->easy_conn, socks, numsocks);
908 case CURLM_STATE_WAITPROXYCONNECT:
909 return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
911 case CURLM_STATE_WAITCONNECT:
912 return waitconnect_getsock(data->easy_conn, socks, numsocks);
914 case CURLM_STATE_DO_MORE:
915 return domore_getsock(data->easy_conn, socks, numsocks);
917 case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
918 to waiting for the same as the *PERFORM
920 case CURLM_STATE_PERFORM:
921 case CURLM_STATE_WAITPERFORM:
922 return Curl_single_getsock(data->easy_conn, socks, numsocks);
927 CURLMcode curl_multi_fdset(struct Curl_multi *multi,
928 fd_set *read_fd_set, fd_set *write_fd_set,
929 fd_set *exc_fd_set, int *max_fd)
931 /* Scan through all the easy handles to get the file descriptors set.
932 Some easy handles may not have connected to the remote host yet,
933 and then we must make sure that is done. */
934 struct Curl_easy *data;
936 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
939 (void)exc_fd_set; /* not used */
941 if(!GOOD_MULTI_HANDLE(multi))
942 return CURLM_BAD_HANDLE;
946 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
948 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
949 curl_socket_t s = CURL_SOCKET_BAD;
951 if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
952 FD_SET(sockbunch[i], read_fd_set);
955 if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
956 FD_SET(sockbunch[i], write_fd_set);
959 if(s == CURL_SOCKET_BAD)
960 /* this socket is unused, break out of loop */
963 if((int)s > this_max_fd)
964 this_max_fd = (int)s;
968 data = data->next; /* check next handle */
971 *max_fd = this_max_fd;
976 CURLMcode curl_multi_wait(struct Curl_multi *multi,
977 struct curl_waitfd extra_fds[],
978 unsigned int extra_nfds,
982 struct Curl_easy *data;
983 curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
986 unsigned int nfds = 0;
987 unsigned int curlfds;
988 struct pollfd *ufds = NULL;
989 long timeout_internal;
992 if(!GOOD_MULTI_HANDLE(multi))
993 return CURLM_BAD_HANDLE;
995 /* If the internally desired timeout is actually shorter than requested from
996 the outside, then use the shorter time! But only if the internal timer
997 is actually larger than -1! */
998 (void)multi_timeout(multi, &timeout_internal);
999 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
1000 timeout_ms = (int)timeout_internal;
1002 /* Count up how many fds we have from the multi handle */
1005 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1007 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1008 curl_socket_t s = CURL_SOCKET_BAD;
1010 if(bitmap & GETSOCK_READSOCK(i)) {
1014 if(bitmap & GETSOCK_WRITESOCK(i)) {
1018 if(s == CURL_SOCKET_BAD) {
1023 data = data->next; /* check next handle */
1026 curlfds = nfds; /* number of internal file descriptors */
1027 nfds += extra_nfds; /* add the externally provided ones */
1029 if(nfds || extra_nfds) {
1030 ufds = malloc(nfds * sizeof(struct pollfd));
1032 return CURLM_OUT_OF_MEMORY;
1036 /* only do the second loop if we found descriptors in the first stage run
1040 /* Add the curl handles to our pollfds first */
1043 bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
1045 for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1046 curl_socket_t s = CURL_SOCKET_BAD;
1048 if(bitmap & GETSOCK_READSOCK(i)) {
1049 ufds[nfds].fd = sockbunch[i];
1050 ufds[nfds].events = POLLIN;
1054 if(bitmap & GETSOCK_WRITESOCK(i)) {
1055 ufds[nfds].fd = sockbunch[i];
1056 ufds[nfds].events = POLLOUT;
1060 if(s == CURL_SOCKET_BAD) {
1065 data = data->next; /* check next handle */
1069 /* Add external file descriptions from poll-like struct curl_waitfd */
1070 for(i = 0; i < extra_nfds; i++) {
1071 ufds[nfds].fd = extra_fds[i].fd;
1072 ufds[nfds].events = 0;
1073 if(extra_fds[i].events & CURL_WAIT_POLLIN)
1074 ufds[nfds].events |= POLLIN;
1075 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1076 ufds[nfds].events |= POLLPRI;
1077 if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1078 ufds[nfds].events |= POLLOUT;
1085 pollrc = Curl_poll(ufds, nfds, timeout_ms);
1086 DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
1087 nfds, timeout_ms, pollrc));
1091 /* copy revents results from the poll to the curl_multi_wait poll
1092 struct, the bit values of the actual underlying poll() implementation
1093 may not be the same as the ones in the public libcurl API! */
1094 for(i = 0; i < extra_nfds; i++) {
1095 unsigned short mask = 0;
1096 unsigned r = ufds[curlfds + i].revents;
1099 mask |= CURL_WAIT_POLLIN;
1101 mask |= CURL_WAIT_POLLOUT;
1103 mask |= CURL_WAIT_POLLPRI;
1105 extra_fds[i].revents = mask;
1117 * Curl_multi_connchanged() is called to tell that there is a connection in
1118 * this multi handle that has changed state (pipelining become possible, the
1119 * number of allowed streams changed or similar), and a subsequent use of this
1120 * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1123 void Curl_multi_connchanged(struct Curl_multi *multi)
1125 multi->recheckstate = TRUE;
1129 * multi_ischanged() is called
1131 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1132 * => CONNECT action.
1134 * Set 'clear' to TRUE to have it also clear the state variable.
1136 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1138 bool retval = multi->recheckstate;
1140 multi->recheckstate = FALSE;
1144 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1145 struct Curl_easy *data,
1146 struct connectdata *conn)
1150 rc = curl_multi_add_handle(multi, data);
1152 struct SingleRequest *k = &data->req;
1154 /* pass in NULL for 'conn' here since we don't want to init the
1155 connection, only this transfer */
1156 Curl_init_do(data, NULL);
1158 /* take this handle to the perform state right away */
1159 multistate(data, CURLM_STATE_PERFORM);
1160 data->easy_conn = conn;
1161 k->keepon |= KEEP_RECV; /* setup to receive! */
1166 static CURLcode multi_reconnect_request(struct connectdata **connp)
1168 CURLcode result = CURLE_OK;
1169 struct connectdata *conn = *connp;
1170 struct Curl_easy *data = conn->data;
1172 /* This was a re-use of a connection and we got a write error in the
1173 * DO-phase. Then we DISCONNECT this connection and have another attempt to
1174 * CONNECT and then DO again! The retry cannot possibly find another
1175 * connection to re-use, since we only keep one possible connection for
1178 infof(data, "Re-used connection seems dead, get a new one\n");
1180 connclose(conn, "Reconnect dead connection"); /* enforce close */
1181 result = multi_done(&conn, result, FALSE); /* we are so done with this */
1183 /* conn may no longer be a good pointer, clear it to avoid mistakes by
1188 * We need to check for CURLE_SEND_ERROR here as well. This could happen
1189 * when the request failed on a FTP connection and thus multi_done() itself
1190 * tried to use the connection (again).
1192 if(!result || (CURLE_SEND_ERROR == result)) {
1194 bool protocol_done = TRUE;
1196 /* Now, redo the connect and get a new connection */
1197 result = Curl_connect(data, connp, &async, &protocol_done);
1199 /* We have connected or sent away a name resolve query fine */
1201 conn = *connp; /* setup conn to again point to something nice */
1203 /* Now, if async is TRUE here, we need to wait for the name
1205 result = Curl_resolver_wait_resolv(conn, NULL);
1209 /* Resolved, continue with the connection */
1210 result = Curl_async_resolved(conn, &protocol_done);
1221 * do_complete is called when the DO actions are complete.
1223 * We init chunking and trailer bits to their default values here immediately
1224 * before receiving any header data for the current request in the pipeline.
1226 static void do_complete(struct connectdata *conn)
1228 conn->data->req.chunk=FALSE;
1229 conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
1230 conn->sockfd:conn->writesockfd)+1;
1231 Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
1234 static CURLcode multi_do(struct connectdata **connp, bool *done)
1236 CURLcode result=CURLE_OK;
1237 struct connectdata *conn = *connp;
1238 struct Curl_easy *data = conn->data;
1240 if(conn->handler->do_it) {
1241 /* generic protocol-specific function pointer set in curl_connect() */
1242 result = conn->handler->do_it(conn, done);
1244 /* This was formerly done in transfer.c, but we better do it here */
1245 if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
1247 * If the connection is using an easy handle, call reconnect
1248 * to re-establish the connection. Otherwise, let the multi logic
1249 * figure out how to re-establish the connection.
1252 result = multi_reconnect_request(connp);
1255 /* ... finally back to actually retry the DO phase */
1256 conn = *connp; /* re-assign conn since multi_reconnect_request
1257 creates a new connection */
1258 result = conn->handler->do_it(conn, done);
1265 if(!result && *done)
1266 /* do_complete must be called after the protocol-specific DO function */
1273 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1274 * second stage DO state which (wrongly) was introduced to support FTP's
1275 * second connection.
1277 * TODO: A future libcurl should be able to work away this state.
1279 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1280 * DOING state there's more work to do!
1283 static CURLcode multi_do_more(struct connectdata *conn, int *complete)
1285 CURLcode result=CURLE_OK;
1289 if(conn->handler->do_more)
1290 result = conn->handler->do_more(conn, complete);
1292 if(!result && (*complete == 1))
1293 /* do_complete must be called after the protocol-specific DO function */
1299 static CURLMcode multi_runsingle(struct Curl_multi *multi,
1301 struct Curl_easy *data)
1303 struct Curl_message *msg = NULL;
1306 bool protocol_connect = FALSE;
1307 bool dophase_done = FALSE;
1310 CURLcode result = CURLE_OK;
1311 struct SingleRequest *k;
1313 time_t recv_timeout_ms;
1314 time_t send_timeout_ms;
1317 if(!GOOD_EASY_HANDLE(data))
1318 return CURLM_BAD_EASY_HANDLE;
1321 /* A "stream" here is a logical stream if the protocol can handle that
1322 (HTTP/2), or the full connection for older protocols */
1323 bool stream_error = FALSE;
1326 /* Handle the case when the pipe breaks, i.e., the connection
1327 we're using gets cleaned up and we're left with nothing. */
1328 if(data->state.pipe_broke) {
1329 infof(data, "Pipe broke: handle %p, url = %s\n",
1330 (void *)data, data->state.path);
1332 if(data->mstate < CURLM_STATE_COMPLETED) {
1333 /* Head back to the CONNECT state */
1334 multistate(data, CURLM_STATE_CONNECT);
1335 rc = CURLM_CALL_MULTI_PERFORM;
1339 data->state.pipe_broke = FALSE;
1340 data->easy_conn = NULL;
1344 if(!data->easy_conn &&
1345 data->mstate > CURLM_STATE_CONNECT &&
1346 data->mstate < CURLM_STATE_DONE) {
1347 /* In all these states, the code will blindly access 'data->easy_conn'
1348 so this is precaution that it isn't NULL. And it silences static
1350 failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
1351 return CURLM_INTERNAL_ERROR;
1354 if(multi_ischanged(multi, TRUE)) {
1355 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
1356 Curl_multi_process_pending_handles(multi);
1359 if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
1360 data->mstate < CURLM_STATE_COMPLETED)
1361 /* Make sure we set the connection's current owner */
1362 data->easy_conn->data = data;
1364 if(data->easy_conn &&
1365 (data->mstate >= CURLM_STATE_CONNECT) &&
1366 (data->mstate < CURLM_STATE_COMPLETED)) {
1367 /* we need to wait for the connect state as only then is the start time
1368 stored, but we must not check already completed handles */
1370 timeout_ms = Curl_timeleft(data, &now,
1371 (data->mstate <= CURLM_STATE_WAITDO)?
1374 if(timeout_ms < 0) {
1375 /* Handle timed out */
1376 if(data->mstate == CURLM_STATE_WAITRESOLVE)
1377 failf(data, "Resolving timed out after %ld milliseconds",
1378 Curl_tvdiff(now, data->progress.t_startsingle));
1379 else if(data->mstate == CURLM_STATE_WAITCONNECT)
1380 failf(data, "Connection timed out after %ld milliseconds",
1381 Curl_tvdiff(now, data->progress.t_startsingle));
1385 failf(data, "Operation timed out after %ld milliseconds with %"
1386 CURL_FORMAT_CURL_OFF_T " out of %"
1387 CURL_FORMAT_CURL_OFF_T " bytes received",
1388 Curl_tvdiff(now, data->progress.t_startsingle),
1389 k->bytecount, k->size);
1392 failf(data, "Operation timed out after %ld milliseconds with %"
1393 CURL_FORMAT_CURL_OFF_T " bytes received",
1394 Curl_tvdiff(now, data->progress.t_startsingle),
1399 /* Force connection closed if the connection has indeed been used */
1400 if(data->mstate > CURLM_STATE_DO) {
1401 streamclose(data->easy_conn, "Disconnected with pending data");
1402 stream_error = TRUE;
1404 result = CURLE_OPERATION_TIMEDOUT;
1405 (void)multi_done(&data->easy_conn, result, TRUE);
1406 /* Skip the statemachine and go directly to error handling section. */
1407 goto statemachine_end;
1411 switch(data->mstate) {
1412 case CURLM_STATE_INIT:
1413 /* init this transfer. */
1414 result=Curl_pretransfer(data);
1417 /* after init, go CONNECT */
1418 multistate(data, CURLM_STATE_CONNECT);
1419 Curl_pgrsTime(data, TIMER_STARTOP);
1420 rc = CURLM_CALL_MULTI_PERFORM;
1424 case CURLM_STATE_CONNECT_PEND:
1425 /* We will stay here until there is a connection available. Then
1426 we try again in the CURLM_STATE_CONNECT state. */
1429 case CURLM_STATE_CONNECT:
1430 /* Connect. We want to get a connection identifier filled in. */
1431 Curl_pgrsTime(data, TIMER_STARTSINGLE);
1432 result = Curl_connect(data, &data->easy_conn,
1433 &async, &protocol_connect);
1434 if(CURLE_NO_CONNECTION_AVAILABLE == result) {
1435 /* There was no connection available. We will go to the pending
1436 state and wait for an available connection. */
1437 multistate(data, CURLM_STATE_CONNECT_PEND);
1439 /* add this handle to the list of connect-pending handles */
1440 if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
1441 result = CURLE_OUT_OF_MEMORY;
1448 /* Add this handle to the send or pend pipeline */
1449 result = Curl_add_handle_to_pipeline(data, data->easy_conn);
1451 stream_error = TRUE;
1454 /* We're now waiting for an asynchronous name lookup */
1455 multistate(data, CURLM_STATE_WAITRESOLVE);
1457 /* after the connect has been sent off, go WAITCONNECT unless the
1458 protocol connect is already done and we can go directly to
1460 rc = CURLM_CALL_MULTI_PERFORM;
1462 if(protocol_connect)
1463 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1464 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1466 #ifndef CURL_DISABLE_HTTP
1467 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1468 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1471 multistate(data, CURLM_STATE_WAITCONNECT);
1478 case CURLM_STATE_WAITRESOLVE:
1479 /* awaiting an asynch name resolve to complete */
1481 struct Curl_dns_entry *dns = NULL;
1482 struct connectdata *conn = data->easy_conn;
1483 const char *hostname;
1485 if(conn->bits.httpproxy)
1486 hostname = conn->http_proxy.host.name;
1487 else if(conn->bits.conn_to_host)
1488 hostname = conn->conn_to_host.name;
1490 hostname = conn->host.name;
1492 /* check if we have the name resolved by now */
1493 dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
1496 #ifdef CURLRES_ASYNCH
1497 conn->async.dns = dns;
1498 conn->async.done = TRUE;
1501 infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
1505 result = Curl_resolver_is_resolved(data->easy_conn, &dns);
1507 /* Update sockets here, because the socket(s) may have been
1508 closed and the application thus needs to be told, even if it
1509 is likely that the same socket(s) will again be used further
1510 down. If the name has not yet been resolved, it is likely
1511 that new sockets have been opened in an attempt to contact
1512 another resolver. */
1513 singlesocket(multi, data);
1516 /* Perform the next step in the connection phase, and then move on
1517 to the WAITCONNECT state */
1518 result = Curl_async_resolved(data->easy_conn, &protocol_connect);
1521 /* if Curl_async_resolved() returns failure, the connection struct
1522 is already freed and gone */
1523 data->easy_conn = NULL; /* no more connection */
1525 /* call again please so that we get the next socket setup */
1526 rc = CURLM_CALL_MULTI_PERFORM;
1527 if(protocol_connect)
1528 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1529 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1531 #ifndef CURL_DISABLE_HTTP
1532 if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1533 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1536 multistate(data, CURLM_STATE_WAITCONNECT);
1542 /* failure detected */
1543 stream_error = TRUE;
1549 #ifndef CURL_DISABLE_HTTP
1550 case CURLM_STATE_WAITPROXYCONNECT:
1551 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
1552 result = Curl_http_connect(data->easy_conn, &protocol_connect);
1554 if(data->easy_conn->bits.proxy_connect_closed) {
1555 rc = CURLM_CALL_MULTI_PERFORM;
1556 /* connect back to proxy again */
1558 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1559 multistate(data, CURLM_STATE_CONNECT);
1562 if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
1563 data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
1564 (data->easy_conn->tunnel_state[FIRSTSOCKET] != TUNNEL_CONNECT)) {
1565 rc = CURLM_CALL_MULTI_PERFORM;
1566 /* initiate protocol connect phase */
1567 multistate(data, CURLM_STATE_SENDPROTOCONNECT);
1573 case CURLM_STATE_WAITCONNECT:
1574 /* awaiting a completion of an asynch TCP connect */
1575 result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
1576 if(connected && !result) {
1577 #ifndef CURL_DISABLE_HTTP
1578 if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
1579 !data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
1580 (data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)) {
1581 multistate(data, CURLM_STATE_WAITPROXYCONNECT);
1585 rc = CURLM_CALL_MULTI_PERFORM;
1586 multistate(data, data->easy_conn->bits.tunnel_proxy?
1587 CURLM_STATE_WAITPROXYCONNECT:
1588 CURLM_STATE_SENDPROTOCONNECT);
1591 /* failure detected */
1592 /* Just break, the cleaning up is handled all in one place */
1593 stream_error = TRUE;
1598 case CURLM_STATE_SENDPROTOCONNECT:
1599 result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
1600 if(!protocol_connect)
1601 /* switch to waiting state */
1602 multistate(data, CURLM_STATE_PROTOCONNECT);
1604 /* protocol connect has completed, go WAITDO or DO */
1605 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1606 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1607 rc = CURLM_CALL_MULTI_PERFORM;
1610 /* failure detected */
1611 Curl_posttransfer(data);
1612 multi_done(&data->easy_conn, result, TRUE);
1613 stream_error = TRUE;
1617 case CURLM_STATE_PROTOCONNECT:
1618 /* protocol-specific connect phase */
1619 result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
1620 if(!result && protocol_connect) {
1621 /* after the connect has completed, go WAITDO or DO */
1622 multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
1623 CURLM_STATE_WAITDO:CURLM_STATE_DO);
1624 rc = CURLM_CALL_MULTI_PERFORM;
1627 /* failure detected */
1628 Curl_posttransfer(data);
1629 multi_done(&data->easy_conn, result, TRUE);
1630 stream_error = TRUE;
1634 case CURLM_STATE_WAITDO:
1635 /* Wait for our turn to DO when we're pipelining requests */
1636 if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
1637 /* Grabbed the channel */
1638 multistate(data, CURLM_STATE_DO);
1639 rc = CURLM_CALL_MULTI_PERFORM;
1643 case CURLM_STATE_DO:
1644 if(data->set.connect_only) {
1645 /* keep connection open for application to use the socket */
1646 connkeep(data->easy_conn, "CONNECT_ONLY");
1647 multistate(data, CURLM_STATE_DONE);
1649 rc = CURLM_CALL_MULTI_PERFORM;
1652 /* Perform the protocol's DO action */
1653 result = multi_do(&data->easy_conn, &dophase_done);
1655 /* When multi_do() returns failure, data->easy_conn might be NULL! */
1659 /* some steps needed for wildcard matching */
1660 if(data->set.wildcardmatch) {
1661 struct WildcardData *wc = &data->wildcard;
1662 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
1663 /* skip some states if it is important */
1664 multi_done(&data->easy_conn, CURLE_OK, FALSE);
1665 multistate(data, CURLM_STATE_DONE);
1666 rc = CURLM_CALL_MULTI_PERFORM;
1670 /* DO was not completed in one function call, we must continue
1672 multistate(data, CURLM_STATE_DOING);
1676 /* after DO, go DO_DONE... or DO_MORE */
1677 else if(data->easy_conn->bits.do_more) {
1678 /* we're supposed to do more, but we need to sit down, relax
1679 and wait a little while first */
1680 multistate(data, CURLM_STATE_DO_MORE);
1684 /* we're done with the DO, now DO_DONE */
1685 multistate(data, CURLM_STATE_DO_DONE);
1686 rc = CURLM_CALL_MULTI_PERFORM;
1689 else if((CURLE_SEND_ERROR == result) &&
1690 data->easy_conn->bits.reuse) {
1692 * In this situation, a connection that we were trying to use
1693 * may have unexpectedly died. If possible, send the connection
1694 * back to the CONNECT phase so we can try again.
1696 char *newurl = NULL;
1697 followtype follow=FOLLOW_NONE;
1701 drc = Curl_retry_request(data->easy_conn, &newurl);
1703 /* a failure here pretty much implies an out of memory */
1705 stream_error = TRUE;
1708 retry = (newurl)?TRUE:FALSE;
1710 Curl_posttransfer(data);
1711 drc = multi_done(&data->easy_conn, result, FALSE);
1713 /* When set to retry the connection, we must to go back to
1714 * the CONNECT state */
1716 if(!drc || (drc == CURLE_SEND_ERROR)) {
1717 follow = FOLLOW_RETRY;
1718 drc = Curl_follow(data, newurl, follow);
1720 multistate(data, CURLM_STATE_CONNECT);
1721 rc = CURLM_CALL_MULTI_PERFORM;
1731 /* done didn't return OK or SEND_ERROR */
1737 /* Have error handler disconnect conn if we can't retry */
1738 stream_error = TRUE;
1743 /* failure detected */
1744 Curl_posttransfer(data);
1746 multi_done(&data->easy_conn, result, FALSE);
1747 stream_error = TRUE;
1752 case CURLM_STATE_DOING:
1753 /* we continue DOING until the DO phase is complete */
1754 result = Curl_protocol_doing(data->easy_conn,
1758 /* after DO, go DO_DONE or DO_MORE */
1759 multistate(data, data->easy_conn->bits.do_more?
1760 CURLM_STATE_DO_MORE:
1761 CURLM_STATE_DO_DONE);
1762 rc = CURLM_CALL_MULTI_PERFORM;
1763 } /* dophase_done */
1766 /* failure detected */
1767 Curl_posttransfer(data);
1768 multi_done(&data->easy_conn, result, FALSE);
1769 stream_error = TRUE;
1773 case CURLM_STATE_DO_MORE:
1775 * When we are connected, DO MORE and then go DO_DONE
1777 result = multi_do_more(data->easy_conn, &control);
1779 /* No need to remove this handle from the send pipeline here since that
1780 is done in multi_done() */
1783 /* if positive, advance to DO_DONE
1784 if negative, go back to DOING */
1785 multistate(data, control==1?
1786 CURLM_STATE_DO_DONE:
1788 rc = CURLM_CALL_MULTI_PERFORM;
1791 /* stay in DO_MORE */
1795 /* failure detected */
1796 Curl_posttransfer(data);
1797 multi_done(&data->easy_conn, result, FALSE);
1798 stream_error = TRUE;
1802 case CURLM_STATE_DO_DONE:
1803 /* Move ourselves from the send to recv pipeline */
1804 Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
1805 /* Check if we can move pending requests to send pipe */
1806 Curl_multi_process_pending_handles(multi);
1808 /* Only perform the transfer if there's a good socket to work with.
1809 Having both BAD is a signal to skip immediately to DONE */
1810 if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
1811 (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
1812 multistate(data, CURLM_STATE_WAITPERFORM);
1814 multistate(data, CURLM_STATE_DONE);
1815 rc = CURLM_CALL_MULTI_PERFORM;
1818 case CURLM_STATE_WAITPERFORM:
1819 /* Wait for our turn to PERFORM */
1820 if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
1821 /* Grabbed the channel */
1822 multistate(data, CURLM_STATE_PERFORM);
1823 rc = CURLM_CALL_MULTI_PERFORM;
1827 case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
1828 /* if both rates are within spec, resume transfer */
1829 if(Curl_pgrsUpdate(data->easy_conn))
1830 result = CURLE_ABORTED_BY_CALLBACK;
1832 result = Curl_speedcheck(data, now);
1835 send_timeout_ms = 0;
1836 if(data->set.max_send_speed > 0)
1837 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
1838 data->progress.ul_limit_size,
1839 data->set.max_send_speed,
1840 data->progress.ul_limit_start,
1843 recv_timeout_ms = 0;
1844 if(data->set.max_recv_speed > 0)
1845 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
1846 data->progress.dl_limit_size,
1847 data->set.max_recv_speed,
1848 data->progress.dl_limit_start,
1851 if(send_timeout_ms <= 0 && recv_timeout_ms <= 0)
1852 multistate(data, CURLM_STATE_PERFORM);
1853 else if(send_timeout_ms >= recv_timeout_ms)
1854 Curl_expire_latest(data, send_timeout_ms);
1856 Curl_expire_latest(data, recv_timeout_ms);
1860 case CURLM_STATE_PERFORM:
1862 char *newurl = NULL;
1864 bool comeback = FALSE;
1866 /* check if over send speed */
1867 send_timeout_ms = 0;
1868 if(data->set.max_send_speed > 0)
1869 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
1870 data->progress.ul_limit_size,
1871 data->set.max_send_speed,
1872 data->progress.ul_limit_start,
1875 /* check if over recv speed */
1876 recv_timeout_ms = 0;
1877 if(data->set.max_recv_speed > 0)
1878 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
1879 data->progress.dl_limit_size,
1880 data->set.max_recv_speed,
1881 data->progress.dl_limit_start,
1884 if(send_timeout_ms > 0 || recv_timeout_ms > 0) {
1885 multistate(data, CURLM_STATE_TOOFAST);
1886 if(send_timeout_ms >= recv_timeout_ms)
1887 Curl_expire_latest(data, send_timeout_ms);
1889 Curl_expire_latest(data, recv_timeout_ms);
1893 /* read/write data if it is ready to do so */
1894 result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
1898 if(!(k->keepon & KEEP_RECV))
1899 /* We're done receiving */
1900 Curl_pipeline_leave_read(data->easy_conn);
1902 if(!(k->keepon & KEEP_SEND))
1903 /* We're done sending */
1904 Curl_pipeline_leave_write(data->easy_conn);
1906 if(done || (result == CURLE_RECV_ERROR)) {
1907 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
1908 * condition and the server closed the re-used connection exactly when
1909 * we wanted to use it, so figure out if that is indeed the case.
1911 CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
1913 retry = (newurl)?TRUE:FALSE;
1916 /* if we are to retry, set the result to OK and consider the
1925 * The transfer phase returned error, we mark the connection to get
1926 * closed to prevent being re-used. This is because we can't possibly
1927 * know if the connection is in a good shape or not now. Unless it is
1928 * a protocol which uses two "channels" like FTP, as then the error
1929 * happened in the data connection.
1932 if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
1933 result != CURLE_HTTP2_STREAM)
1934 streamclose(data->easy_conn, "Transfer returned error");
1936 Curl_posttransfer(data);
1937 multi_done(&data->easy_conn, result, TRUE);
1940 followtype follow=FOLLOW_NONE;
1942 /* call this even if the readwrite function returned error */
1943 Curl_posttransfer(data);
1945 /* we're no longer receiving */
1946 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
1948 /* expire the new receiving pipeline head */
1949 if(data->easy_conn->recv_pipe->head)
1950 Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
1952 /* Check if we can move pending requests to send pipe */
1953 Curl_multi_process_pending_handles(multi);
1955 /* When we follow redirects or is set to retry the connection, we must
1956 to go back to the CONNECT state */
1957 if(data->req.newurl || retry) {
1959 /* if the URL is a follow-location and not just a retried request
1960 then figure out the URL here */
1962 newurl = data->req.newurl;
1963 data->req.newurl = NULL;
1964 follow = FOLLOW_REDIR;
1967 follow = FOLLOW_RETRY;
1968 result = multi_done(&data->easy_conn, CURLE_OK, FALSE);
1970 result = Curl_follow(data, newurl, follow);
1972 multistate(data, CURLM_STATE_CONNECT);
1973 rc = CURLM_CALL_MULTI_PERFORM;
1974 newurl = NULL; /* handed over the memory ownership to
1975 Curl_follow(), make sure we don't free() it
1981 /* after the transfer is done, go DONE */
1983 /* but first check to see if we got a location info even though we're
1984 not following redirects */
1985 if(data->req.location) {
1987 newurl = data->req.location;
1988 data->req.location = NULL;
1989 result = Curl_follow(data, newurl, FOLLOW_FAKE);
1991 newurl = NULL; /* allocation was handed over Curl_follow() */
1993 stream_error = TRUE;
1996 multistate(data, CURLM_STATE_DONE);
1997 rc = CURLM_CALL_MULTI_PERFORM;
2001 rc = CURLM_CALL_MULTI_PERFORM;
2007 case CURLM_STATE_DONE:
2008 /* this state is highly transient, so run another loop after this */
2009 rc = CURLM_CALL_MULTI_PERFORM;
2011 if(data->easy_conn) {
2014 /* Remove ourselves from the receive pipeline, if we are there. */
2015 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
2016 /* Check if we can move pending requests to send pipe */
2017 Curl_multi_process_pending_handles(multi);
2019 /* post-transfer command */
2020 res = multi_done(&data->easy_conn, result, FALSE);
2022 /* allow a previously set error code take precedence */
2027 * If there are other handles on the pipeline, multi_done won't set
2028 * easy_conn to NULL. In such a case, curl_multi_remove_handle() can
2029 * access free'd data, if the connection is free'd and the handle
2030 * removed before we perform the processing in CURLM_STATE_COMPLETED
2033 data->easy_conn = NULL;
2036 if(data->set.wildcardmatch) {
2037 if(data->wildcard.state != CURLWC_DONE) {
2038 /* if a wildcard is set and we are not ending -> lets start again
2039 with CURLM_STATE_INIT */
2040 multistate(data, CURLM_STATE_INIT);
2045 /* after we have DONE what we're supposed to do, go COMPLETED, and
2046 it doesn't matter what the multi_done() returned! */
2047 multistate(data, CURLM_STATE_COMPLETED);
2050 case CURLM_STATE_COMPLETED:
2051 /* this is a completed transfer, it is likely to still be connected */
2053 /* This node should be delinked from the list now and we should post
2054 an information message that we are complete. */
2056 /* Important: reset the conn pointer so that we don't point to memory
2057 that could be freed anytime */
2058 data->easy_conn = NULL;
2060 Curl_expire_clear(data); /* stop all timers */
2063 case CURLM_STATE_MSGSENT:
2064 data->result = result;
2065 return CURLM_OK; /* do nothing */
2068 return CURLM_INTERNAL_ERROR;
2072 if(data->mstate < CURLM_STATE_COMPLETED) {
2075 * If an error was returned, and we aren't in completed state now,
2076 * then we go to completed and consider this transfer aborted.
2079 /* NOTE: no attempt to disconnect connections must be made
2080 in the case blocks above - cleanup happens only here */
2082 data->state.pipe_broke = FALSE;
2084 /* Check if we can move pending requests to send pipe */
2085 Curl_multi_process_pending_handles(multi);
2087 if(data->easy_conn) {
2088 /* if this has a connection, unsubscribe from the pipelines */
2089 Curl_pipeline_leave_write(data->easy_conn);
2090 Curl_pipeline_leave_read(data->easy_conn);
2091 Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
2092 Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
2095 /* Don't attempt to send data over a connection that timed out */
2096 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2097 /* disconnect properly */
2098 Curl_disconnect(data->easy_conn, dead_connection);
2100 /* This is where we make sure that the easy_conn pointer is reset.
2101 We don't have to do this in every case block above where a
2102 failure is detected */
2103 data->easy_conn = NULL;
2106 else if(data->mstate == CURLM_STATE_CONNECT) {
2107 /* Curl_connect() failed */
2108 (void)Curl_posttransfer(data);
2111 multistate(data, CURLM_STATE_COMPLETED);
2113 /* if there's still a connection to use, call the progress function */
2114 else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
2115 /* aborted due to progress callback return code must close the
2117 result = CURLE_ABORTED_BY_CALLBACK;
2118 streamclose(data->easy_conn, "Aborted by callback");
2120 /* if not yet in DONE state, go there, otherwise COMPLETED */
2121 multistate(data, (data->mstate < CURLM_STATE_DONE)?
2122 CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
2123 rc = CURLM_CALL_MULTI_PERFORM;
2127 if(CURLM_STATE_COMPLETED == data->mstate) {
2128 /* now fill in the Curl_message with this info */
2131 msg->extmsg.msg = CURLMSG_DONE;
2132 msg->extmsg.easy_handle = data;
2133 msg->extmsg.data.result = result;
2135 rc = multi_addmsg(multi, msg);
2137 multistate(data, CURLM_STATE_MSGSENT);
2139 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2141 data->result = result;
2148 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
2150 struct Curl_easy *data;
2151 CURLMcode returncode=CURLM_OK;
2152 struct Curl_tree *t;
2153 struct timeval now = Curl_tvnow();
2155 if(!GOOD_MULTI_HANDLE(multi))
2156 return CURLM_BAD_HANDLE;
2161 SIGPIPE_VARIABLE(pipe_st);
2163 sigpipe_ignore(data, &pipe_st);
2164 result = multi_runsingle(multi, now, data);
2165 sigpipe_restore(&pipe_st);
2168 returncode = result;
2170 data = data->next; /* operate on next handle */
2174 * Simply remove all expired timers from the splay since handles are dealt
2175 * with unconditionally by this function and curl_multi_timeout() requires
2176 * that already passed/handled expire times are removed from the splay.
2178 * It is important that the 'now' value is set at the entry of this function
2179 * and not for the current time as it may have ticked a little while since
2180 * then and then we risk this loop to remove timers that actually have not
2184 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2186 /* the removed may have another timeout in queue */
2187 (void)add_next_timeout(now, multi, t->payload);
2191 *running_handles = multi->num_alive;
2193 if(CURLM_OK >= returncode)
2194 update_timer(multi);
2199 static void close_all_connections(struct Curl_multi *multi)
2201 struct connectdata *conn;
2203 conn = Curl_conncache_find_first_connection(&multi->conn_cache);
2205 SIGPIPE_VARIABLE(pipe_st);
2206 conn->data = multi->closure_handle;
2208 sigpipe_ignore(conn->data, &pipe_st);
2209 conn->data->easy_conn = NULL; /* clear the easy handle's connection
2211 /* This will remove the connection from the cache */
2212 connclose(conn, "kill all");
2213 (void)Curl_disconnect(conn, FALSE);
2214 sigpipe_restore(&pipe_st);
2216 conn = Curl_conncache_find_first_connection(&multi->conn_cache);
2220 CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
2222 struct Curl_easy *data;
2223 struct Curl_easy *nextdata;
2225 if(GOOD_MULTI_HANDLE(multi)) {
2226 bool restore_pipe = FALSE;
2227 SIGPIPE_VARIABLE(pipe_st);
2229 multi->type = 0; /* not good anymore */
2231 /* Close all the connections in the connection cache */
2232 close_all_connections(multi);
2234 if(multi->closure_handle) {
2235 sigpipe_ignore(multi->closure_handle, &pipe_st);
2236 restore_pipe = TRUE;
2238 multi->closure_handle->dns.hostcache = &multi->hostcache;
2239 Curl_hostcache_clean(multi->closure_handle,
2240 multi->closure_handle->dns.hostcache);
2242 Curl_close(multi->closure_handle);
2245 Curl_hash_destroy(&multi->sockhash);
2246 Curl_conncache_destroy(&multi->conn_cache);
2247 Curl_llist_destroy(multi->msglist, NULL);
2248 Curl_llist_destroy(multi->pending, NULL);
2250 /* remove all easy handles */
2251 data = multi->easyp;
2253 nextdata=data->next;
2254 if(data->dns.hostcachetype == HCACHE_MULTI) {
2255 /* clear out the usage of the shared DNS cache */
2256 Curl_hostcache_clean(data, data->dns.hostcache);
2257 data->dns.hostcache = NULL;
2258 data->dns.hostcachetype = HCACHE_NONE;
2261 /* Clear the pointer to the connection cache */
2262 data->state.conn_cache = NULL;
2263 data->multi = NULL; /* clear the association */
2268 Curl_hash_destroy(&multi->hostcache);
2270 /* Free the blacklists by setting them to NULL */
2271 Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
2272 Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
2276 sigpipe_restore(&pipe_st);
2281 return CURLM_BAD_HANDLE;
2285 * curl_multi_info_read()
2287 * This function is the primary way for a multi/multi_socket application to
2288 * figure out if a transfer has ended. We MUST make this function as fast as
2289 * possible as it will be polled frequently and we MUST NOT scan any lists in
2290 * here to figure out things. We must scale fine to thousands of handles and
2291 * beyond. The current design is fully O(1).
2294 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
2296 struct Curl_message *msg;
2298 *msgs_in_queue = 0; /* default to none */
2300 if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
2301 /* there is one or more messages in the list */
2302 struct curl_llist_element *e;
2304 /* extract the head of the list to return */
2305 e = multi->msglist->head;
2309 /* remove the extracted entry */
2310 Curl_llist_remove(multi->msglist, e, NULL);
2312 *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
2314 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 void 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);
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 && 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 && 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 * Curl_multi_closed()
2466 * Used by the connect code to tell the multi_socket code that one of the
2467 * sockets we were using is about to be closed. This function will then
2468 * remove it from the sockethash for this handle to make the multi_socket API
2469 * behave properly, especially for the case when libcurl will create another
2470 * socket again and it gets the same file descriptor number.
2473 void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
2475 struct Curl_multi *multi = conn->data->multi;
2477 /* this is set if this connection is part of a handle that is added to
2478 a multi handle, and only then this is necessary */
2479 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2482 if(multi->socket_cb)
2483 multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
2484 multi->socket_userp,
2487 /* now remove it from the socket hash */
2488 sh_delentry(&multi->sockhash, s);
2496 * add_next_timeout()
2498 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
2499 * when it has just been removed from the splay tree because the timeout has
2500 * expired. This function is then to advance in the list to pick the next
2501 * timeout to use (skip the already expired ones) and add this node back to
2502 * the splay tree again.
2504 * The splay tree only has each sessionhandle as a single node and the nearest
2505 * timeout is used to sort it on.
2507 static CURLMcode add_next_timeout(struct timeval now,
2508 struct Curl_multi *multi,
2509 struct Curl_easy *d)
2511 struct timeval *tv = &d->state.expiretime;
2512 struct curl_llist *list = d->state.timeoutlist;
2513 struct curl_llist_element *e;
2515 /* move over the timeout list for this specific handle and remove all
2516 timeouts that are now passed tense and store the next pending
2518 for(e = list->head; e;) {
2519 struct curl_llist_element *n = e->next;
2520 time_t diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
2522 /* remove outdated entry */
2523 Curl_llist_remove(list, e, NULL);
2525 /* the list is sorted so get out on the first mismatch */
2531 /* clear the expire times within the handles that we remove from the
2537 /* copy the first entry to 'tv' */
2538 memcpy(tv, e->ptr, sizeof(*tv));
2540 /* remove first entry from list */
2541 Curl_llist_remove(list, e, NULL);
2543 /* insert this node again into the splay */
2544 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
2545 &d->state.timenode);
2550 static CURLMcode multi_socket(struct Curl_multi *multi,
2554 int *running_handles)
2556 CURLMcode result = CURLM_OK;
2557 struct Curl_easy *data = NULL;
2558 struct Curl_tree *t;
2559 struct timeval now = Curl_tvnow();
2562 /* *perform() deals with running_handles on its own */
2563 result = curl_multi_perform(multi, running_handles);
2565 /* walk through each easy handle and do the socket state change magic
2567 if(result != CURLM_BAD_HANDLE) {
2570 singlesocket(multi, data);
2575 /* or should we fall-through and do the timer-based stuff? */
2578 else if(s != CURL_SOCKET_TIMEOUT) {
2580 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
2583 /* Unmatched socket, we can't act on it but we ignore this fact. In
2584 real-world tests it has been proved that libevent can in fact give
2585 the application actions even though the socket was just previously
2586 asked to get removed, so thus we better survive stray socket actions
2587 and just move on. */
2590 SIGPIPE_VARIABLE(pipe_st);
2594 if(data->magic != CURLEASY_MAGIC_NUMBER)
2595 /* bad bad bad bad bad bad bad */
2596 return CURLM_INTERNAL_ERROR;
2598 /* If the pipeline is enabled, take the handle which is in the head of
2599 the pipeline. If we should write into the socket, take the send_pipe
2600 head. If we should read from the socket, take the recv_pipe head. */
2601 if(data->easy_conn) {
2602 if((ev_bitmask & CURL_POLL_OUT) &&
2603 data->easy_conn->send_pipe &&
2604 data->easy_conn->send_pipe->head)
2605 data = data->easy_conn->send_pipe->head->ptr;
2606 else if((ev_bitmask & CURL_POLL_IN) &&
2607 data->easy_conn->recv_pipe &&
2608 data->easy_conn->recv_pipe->head)
2609 data = data->easy_conn->recv_pipe->head->ptr;
2612 if(data->easy_conn &&
2613 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2614 /* set socket event bitmask if they're not locked */
2615 data->easy_conn->cselect_bits = ev_bitmask;
2617 sigpipe_ignore(data, &pipe_st);
2618 result = multi_runsingle(multi, now, data);
2619 sigpipe_restore(&pipe_st);
2621 if(data->easy_conn &&
2622 !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
2623 /* clear the bitmask only if not locked */
2624 data->easy_conn->cselect_bits = 0;
2626 if(CURLM_OK >= result)
2627 /* get the socket(s) and check if the state has been changed since
2629 singlesocket(multi, data);
2631 /* Now we fall-through and do the timer-based stuff, since we don't want
2632 to force the user to have to deal with timeouts as long as at least
2633 one connection in fact has traffic. */
2635 data = NULL; /* set data to NULL again to avoid calling
2636 multi_runsingle() in case there's no need to */
2637 now = Curl_tvnow(); /* get a newer time since the multi_runsingle() loop
2638 may have taken some time */
2642 /* Asked to run due to time-out. Clear the 'lastcall' variable to force
2643 update_timer() to trigger a callback to the app again even if the same
2644 timeout is still the one to run after this call. That handles the case
2645 when the application asks libcurl to run the timeout prematurely. */
2646 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
2650 * The loop following here will go on as long as there are expire-times left
2651 * to process in the splay and 'data' will be re-assigned for every expired
2652 * handle we deal with.
2655 /* the first loop lap 'data' can be NULL */
2657 SIGPIPE_VARIABLE(pipe_st);
2659 sigpipe_ignore(data, &pipe_st);
2660 result = multi_runsingle(multi, now, data);
2661 sigpipe_restore(&pipe_st);
2663 if(CURLM_OK >= result)
2664 /* get the socket(s) and check if the state has been changed since
2666 singlesocket(multi, data);
2669 /* Check if there's one (more) expired timer to deal with! This function
2670 extracts a matching node if there is one */
2672 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2674 data = t->payload; /* assign this for next loop */
2675 (void)add_next_timeout(now, multi, t->payload);
2680 *running_handles = multi->num_alive;
2684 #undef curl_multi_setopt
2685 CURLMcode curl_multi_setopt(struct Curl_multi *multi,
2686 CURLMoption option, ...)
2688 CURLMcode res = CURLM_OK;
2691 if(!GOOD_MULTI_HANDLE(multi))
2692 return CURLM_BAD_HANDLE;
2694 va_start(param, option);
2697 case CURLMOPT_SOCKETFUNCTION:
2698 multi->socket_cb = va_arg(param, curl_socket_callback);
2700 case CURLMOPT_SOCKETDATA:
2701 multi->socket_userp = va_arg(param, void *);
2703 case CURLMOPT_PUSHFUNCTION:
2704 multi->push_cb = va_arg(param, curl_push_callback);
2706 case CURLMOPT_PUSHDATA:
2707 multi->push_userp = va_arg(param, void *);
2709 case CURLMOPT_PIPELINING:
2710 multi->pipelining = va_arg(param, long);
2712 case CURLMOPT_TIMERFUNCTION:
2713 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
2715 case CURLMOPT_TIMERDATA:
2716 multi->timer_userp = va_arg(param, void *);
2718 case CURLMOPT_MAXCONNECTS:
2719 multi->maxconnects = va_arg(param, long);
2721 case CURLMOPT_MAX_HOST_CONNECTIONS:
2722 multi->max_host_connections = va_arg(param, long);
2724 case CURLMOPT_MAX_PIPELINE_LENGTH:
2725 multi->max_pipeline_length = va_arg(param, long);
2727 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
2728 multi->content_length_penalty_size = va_arg(param, long);
2730 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
2731 multi->chunk_length_penalty_size = va_arg(param, long);
2733 case CURLMOPT_PIPELINING_SITE_BL:
2734 res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
2735 &multi->pipelining_site_bl);
2737 case CURLMOPT_PIPELINING_SERVER_BL:
2738 res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
2739 &multi->pipelining_server_bl);
2741 case CURLMOPT_MAX_TOTAL_CONNECTIONS:
2742 multi->max_total_connections = va_arg(param, long);
2745 res = CURLM_UNKNOWN_OPTION;
2752 /* we define curl_multi_socket() in the public multi.h header */
2753 #undef curl_multi_socket
2755 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
2756 int *running_handles)
2758 CURLMcode result = multi_socket(multi, FALSE, s, 0, running_handles);
2759 if(CURLM_OK >= result)
2760 update_timer(multi);
2764 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
2765 int ev_bitmask, int *running_handles)
2767 CURLMcode result = multi_socket(multi, FALSE, s,
2768 ev_bitmask, running_handles);
2769 if(CURLM_OK >= result)
2770 update_timer(multi);
2774 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
2777 CURLMcode result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0,
2779 if(CURLM_OK >= result)
2780 update_timer(multi);
2784 static CURLMcode multi_timeout(struct Curl_multi *multi,
2787 static struct timeval tv_zero = {0, 0};
2789 if(multi->timetree) {
2790 /* we have a tree of expire times */
2791 struct timeval now = Curl_tvnow();
2793 /* splay the lowest to the bottom */
2794 multi->timetree = Curl_splay(tv_zero, multi->timetree);
2796 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
2797 /* some time left before expiration */
2798 *timeout_ms = (long)curlx_tvdiff(multi->timetree->key, now);
2801 * Since we only provide millisecond resolution on the returned value
2802 * and the diff might be less than one millisecond here, we don't
2803 * return zero as that may cause short bursts of busyloops on fast
2804 * processors while the diff is still present but less than one
2805 * millisecond! instead we return 1 until the time is ripe.
2810 /* 0 means immediately */
2819 CURLMcode curl_multi_timeout(struct Curl_multi *multi,
2822 /* First, make some basic checks that the CURLM handle is a good handle */
2823 if(!GOOD_MULTI_HANDLE(multi))
2824 return CURLM_BAD_HANDLE;
2826 return multi_timeout(multi, timeout_ms);
2830 * Tell the application it should update its timers, if it subscribes to the
2831 * update timer callback.
2833 static int update_timer(struct Curl_multi *multi)
2837 if(!multi->timer_cb)
2839 if(multi_timeout(multi, &timeout_ms)) {
2842 if(timeout_ms < 0) {
2843 static const struct timeval none={0, 0};
2844 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
2845 multi->timer_lastcall = none;
2846 /* there's no timeout now but there was one previously, tell the app to
2848 return multi->timer_cb(multi, -1, multi->timer_userp);
2853 /* When multi_timeout() is done, multi->timetree points to the node with the
2854 * timeout we got the (relative) time-out time for. We can thus easily check
2855 * if this is the same (fixed) time as we got in a previous call and then
2856 * avoid calling the callback again. */
2857 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
2860 multi->timer_lastcall = multi->timetree->key;
2862 return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
2866 * multi_freetimeout()
2868 * Callback used by the llist system when a single timeout list entry is
2871 static void multi_freetimeout(void *user, void *entryptr)
2875 /* the entry was plain malloc()'ed */
2880 * multi_addtimeout()
2882 * Add a timestamp to the list of timeouts. Keep the list sorted so that head
2883 * of list is always the timeout nearest in time.
2887 multi_addtimeout(struct curl_llist *timeoutlist,
2888 struct timeval *stamp)
2890 struct curl_llist_element *e;
2891 struct timeval *timedup;
2892 struct curl_llist_element *prev = NULL;
2894 timedup = malloc(sizeof(*timedup));
2896 return CURLM_OUT_OF_MEMORY;
2898 /* copy the timestamp */
2899 memcpy(timedup, stamp, sizeof(*timedup));
2901 if(Curl_llist_count(timeoutlist)) {
2902 /* find the correct spot in the list */
2903 for(e = timeoutlist->head; e; e = e->next) {
2904 struct timeval *checktime = e->ptr;
2905 time_t diff = curlx_tvdiff(*checktime, *timedup);
2913 this is the first timeout on the list */
2915 if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
2917 return CURLM_OUT_OF_MEMORY;
2926 * given a number of milliseconds from now to use to set the 'act before
2927 * this'-time for the transfer, to be extracted by curl_multi_timeout()
2929 * The timeout will be added to a queue of timeouts if it defines a moment in
2930 * time that is later than the current head of queue.
2932 void Curl_expire(struct Curl_easy *data, time_t milli)
2934 struct Curl_multi *multi = data->multi;
2935 struct timeval *nowp = &data->state.expiretime;
2939 /* this is only interesting while there is still an associated multi struct
2945 set.tv_sec += (long)(milli/1000);
2946 set.tv_usec += (milli%1000)*1000;
2948 if(set.tv_usec >= 1000000) {
2950 set.tv_usec -= 1000000;
2953 if(nowp->tv_sec || nowp->tv_usec) {
2954 /* This means that the struct is added as a node in the splay tree.
2955 Compare if the new time is earlier, and only remove-old/add-new if it
2957 time_t diff = curlx_tvdiff(set, *nowp);
2959 /* the new expire time was later so just add it to the queue
2961 multi_addtimeout(data->state.timeoutlist, &set);
2965 /* the new time is newer than the presently set one, so add the current
2966 to the queue and update the head */
2967 multi_addtimeout(data->state.timeoutlist, nowp);
2969 /* Since this is an updated time, we must remove the previous entry from
2970 the splay tree first and then re-add the new value */
2971 rc = Curl_splayremovebyaddr(multi->timetree,
2972 &data->state.timenode,
2975 infof(data, "Internal error removing splay node = %d\n", rc);
2979 data->state.timenode.payload = data;
2980 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
2981 &data->state.timenode);
2985 * Curl_expire_latest()
2987 * This is like Curl_expire() but will only add a timeout node to the list of
2988 * timers if there is no timeout that will expire before the given time.
2990 * Use this function if the code logic risks calling this function many times
2991 * or if there's no particular conditional wait in the code for this specific
2992 * time-out period to expire.
2995 void Curl_expire_latest(struct Curl_easy *data, time_t milli)
2997 struct timeval *expire = &data->state.expiretime;
3002 set.tv_sec += (long)(milli / 1000);
3003 set.tv_usec += (milli % 1000) * 1000;
3005 if(set.tv_usec >= 1000000) {
3007 set.tv_usec -= 1000000;
3010 if(expire->tv_sec || expire->tv_usec) {
3011 /* This means that the struct is added as a node in the splay tree.
3012 Compare if the new time is earlier, and only remove-old/add-new if it
3014 time_t diff = curlx_tvdiff(set, *expire);
3016 /* the new expire time was later than the top time, so just skip this */
3020 /* Just add the timeout like normal */
3021 Curl_expire(data, milli);
3026 * Curl_expire_clear()
3028 * Clear ALL timeout values for this handle.
3030 void Curl_expire_clear(struct Curl_easy *data)
3032 struct Curl_multi *multi = data->multi;
3033 struct timeval *nowp = &data->state.expiretime;
3036 /* this is only interesting while there is still an associated multi struct
3041 if(nowp->tv_sec || nowp->tv_usec) {
3042 /* Since this is an cleared time, we must remove the previous entry from
3044 struct curl_llist *list = data->state.timeoutlist;
3046 rc = Curl_splayremovebyaddr(multi->timetree,
3047 &data->state.timenode,
3050 infof(data, "Internal error clearing splay node = %d\n", rc);
3052 /* flush the timeout list too */
3053 while(list->size > 0)
3054 Curl_llist_remove(list, list->tail, NULL);
3057 infof(data, "Expire cleared\n");
3067 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
3070 struct Curl_sh_entry *there = NULL;
3072 there = sh_getentry(&multi->sockhash, s);
3075 return CURLM_BAD_SOCKET;
3077 there->socketp = hashp;
3082 size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
3084 return multi ? multi->max_host_connections : 0;
3087 size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
3089 return multi ? multi->max_total_connections : 0;
3092 curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
3094 return multi ? multi->content_length_penalty_size : 0;
3097 curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
3099 return multi ? multi->chunk_length_penalty_size : 0;
3102 struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
3104 return multi->pipelining_site_bl;
3107 struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
3109 return multi->pipelining_server_bl;
3112 void Curl_multi_process_pending_handles(struct Curl_multi *multi)
3114 struct curl_llist_element *e = multi->pending->head;
3117 struct Curl_easy *data = e->ptr;
3118 struct curl_llist_element *next = e->next;
3120 if(data->mstate == CURLM_STATE_CONNECT_PEND) {
3121 multistate(data, CURLM_STATE_CONNECT);
3123 /* Remove this node from the list */
3124 Curl_llist_remove(multi->pending, e, NULL);
3126 /* Make sure that the handle will be processed soonish. */
3127 Curl_expire_latest(data, 0);
3130 e = next; /* operate on next handle */
3135 void Curl_multi_dump(struct Curl_multi *multi)
3137 struct Curl_easy *data;
3139 fprintf(stderr, "* Multi status: %d handles, %d alive\n",
3140 multi->num_easy, multi->num_alive);
3141 for(data=multi->easyp; data; data = data->next) {
3142 if(data->mstate < CURLM_STATE_COMPLETED) {
3143 /* only display handles that are not completed */
3144 fprintf(stderr, "handle %p, state %s, %d sockets\n",
3146 statename[data->mstate], data->numsocks);
3147 for(i=0; i < data->numsocks; i++) {
3148 curl_socket_t s = data->sockets[i];
3149 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3151 fprintf(stderr, "%d ", (int)s);
3153 fprintf(stderr, "INTERNAL CONFUSION\n");
3156 fprintf(stderr, "[%s %s] ",
3157 entry->action&CURL_POLL_IN?"RECVING":"",
3158 entry->action&CURL_POLL_OUT?"SENDING":"");
3161 fprintf(stderr, "\n");