• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 
25 #include "curl_setup.h"
26 
27 #include <curl/curl.h>
28 
29 #include "urldata.h"
30 #include "transfer.h"
31 #include "url.h"
32 #include "cfilters.h"
33 #include "connect.h"
34 #include "progress.h"
35 #include "easyif.h"
36 #include "share.h"
37 #include "psl.h"
38 #include "multiif.h"
39 #include "sendf.h"
40 #include "timeval.h"
41 #include "http.h"
42 #include "select.h"
43 #include "warnless.h"
44 #include "speedcheck.h"
45 #include "conncache.h"
46 #include "multihandle.h"
47 #include "sigpipe.h"
48 #include "vtls/vtls.h"
49 #include "http_proxy.h"
50 #include "http2.h"
51 #include "socketpair.h"
52 #include "socks.h"
53 /* The last 3 #include files should be in this order */
54 #include "curl_printf.h"
55 #include "curl_memory.h"
56 #include "memdebug.h"
57 
58 #ifdef __APPLE__
59 
60 #define wakeup_write  write
61 #define wakeup_read   read
62 #define wakeup_close  close
63 #define wakeup_create pipe
64 
65 #else /* __APPLE__ */
66 
67 #define wakeup_write     swrite
68 #define wakeup_read      sread
69 #define wakeup_close     sclose
70 #define wakeup_create(p) Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, p)
71 
72 #endif /* __APPLE__ */
73 
74 /*
75   CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
76   to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes.  Still, every
77   CURL handle takes 45-50 K memory, therefore this 3K are not significant.
78 */
79 #ifndef CURL_SOCKET_HASH_TABLE_SIZE
80 #define CURL_SOCKET_HASH_TABLE_SIZE 911
81 #endif
82 
83 #ifndef CURL_CONNECTION_HASH_SIZE
84 #define CURL_CONNECTION_HASH_SIZE 97
85 #endif
86 
87 #ifndef CURL_DNS_HASH_SIZE
88 #define CURL_DNS_HASH_SIZE 71
89 #endif
90 
91 #define CURL_MULTI_HANDLE 0x000bab1e
92 
93 #ifdef DEBUGBUILD
94 /* On a debug build, we want to fail hard on multi handles that
95  * are not NULL, but no longer have the MAGIC touch. This gives
96  * us early warning on things only discovered by valgrind otherwise. */
97 #define GOOD_MULTI_HANDLE(x) \
98   (((x) && (x)->magic == CURL_MULTI_HANDLE)? TRUE: \
99   (DEBUGASSERT(!(x)), FALSE))
100 #else
101 #define GOOD_MULTI_HANDLE(x) \
102   ((x) && (x)->magic == CURL_MULTI_HANDLE)
103 #endif
104 
105 static CURLMcode singlesocket(struct Curl_multi *multi,
106                               struct Curl_easy *data);
107 static CURLMcode add_next_timeout(struct curltime now,
108                                   struct Curl_multi *multi,
109                                   struct Curl_easy *d);
110 static CURLMcode multi_timeout(struct Curl_multi *multi,
111                                long *timeout_ms);
112 static void process_pending_handles(struct Curl_multi *multi);
113 
114 #ifdef DEBUGBUILD
115 static const char * const multi_statename[]={
116   "INIT",
117   "PENDING",
118   "CONNECT",
119   "RESOLVING",
120   "CONNECTING",
121   "TUNNELING",
122   "PROTOCONNECT",
123   "PROTOCONNECTING",
124   "DO",
125   "DOING",
126   "DOING_MORE",
127   "DID",
128   "PERFORMING",
129   "RATELIMITING",
130   "DONE",
131   "COMPLETED",
132   "MSGSENT",
133 };
134 #endif
135 
136 /* function pointer called once when switching TO a state */
137 typedef void (*init_multistate_func)(struct Curl_easy *data);
138 
139 /* called in DID state, before PERFORMING state */
before_perform(struct Curl_easy * data)140 static void before_perform(struct Curl_easy *data)
141 {
142   data->req.chunk = FALSE;
143   Curl_pgrsTime(data, TIMER_PRETRANSFER);
144 }
145 
init_completed(struct Curl_easy * data)146 static void init_completed(struct Curl_easy *data)
147 {
148   /* this is a completed transfer */
149 
150   /* Important: reset the conn pointer so that we don't point to memory
151      that could be freed anytime */
152   Curl_detach_connection(data);
153   Curl_expire_clear(data); /* stop all timers */
154 }
155 
156 /* always use this function to change state, to make debugging easier */
mstate(struct Curl_easy * data,CURLMstate state,int lineno)157 static void mstate(struct Curl_easy *data, CURLMstate state
158 #ifdef DEBUGBUILD
159                    , int lineno
160 #endif
161 )
162 {
163   CURLMstate oldstate = data->mstate;
164   static const init_multistate_func finit[MSTATE_LAST] = {
165     NULL,              /* INIT */
166     NULL,              /* PENDING */
167     Curl_init_CONNECT, /* CONNECT */
168     NULL,              /* RESOLVING */
169     NULL,              /* CONNECTING */
170     NULL,              /* TUNNELING */
171     NULL,              /* PROTOCONNECT */
172     NULL,              /* PROTOCONNECTING */
173     NULL,              /* DO */
174     NULL,              /* DOING */
175     NULL,              /* DOING_MORE */
176     before_perform,    /* DID */
177     NULL,              /* PERFORMING */
178     NULL,              /* RATELIMITING */
179     NULL,              /* DONE */
180     init_completed,    /* COMPLETED */
181     NULL               /* MSGSENT */
182   };
183 
184 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
185   (void) lineno;
186 #endif
187 
188   if(oldstate == state)
189     /* don't bother when the new state is the same as the old state */
190     return;
191 
192   data->mstate = state;
193 
194 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
195   if(data->mstate >= MSTATE_PENDING &&
196      data->mstate < MSTATE_COMPLETED) {
197     infof(data,
198           "STATE: %s => %s handle %p; line %d",
199           multi_statename[oldstate], multi_statename[data->mstate],
200           (void *)data, lineno);
201   }
202 #endif
203 
204   if(state == MSTATE_COMPLETED) {
205     /* changing to COMPLETED means there's one less easy handle 'alive' */
206     DEBUGASSERT(data->multi->num_alive > 0);
207     data->multi->num_alive--;
208   }
209 
210   /* if this state has an init-function, run it */
211   if(finit[state])
212     finit[state](data);
213 }
214 
215 #ifndef DEBUGBUILD
216 #define multistate(x,y) mstate(x,y)
217 #else
218 #define multistate(x,y) mstate(x,y, __LINE__)
219 #endif
220 
221 /*
222  * We add one of these structs to the sockhash for each socket
223  */
224 
225 struct Curl_sh_entry {
226   struct Curl_hash transfers; /* hash of transfers using this socket */
227   unsigned int action;  /* what combined action READ/WRITE this socket waits
228                            for */
229   unsigned int users; /* number of transfers using this */
230   void *socketp; /* settable by users with curl_multi_assign() */
231   unsigned int readers; /* this many transfers want to read */
232   unsigned int writers; /* this many transfers want to write */
233 };
234 /* bits for 'action' having no bits means this socket is not expecting any
235    action */
236 #define SH_READ  1
237 #define SH_WRITE 2
238 
239 /* look up a given socket in the socket hash, skip invalid sockets */
sh_getentry(struct Curl_hash * sh,curl_socket_t s)240 static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh,
241                                          curl_socket_t s)
242 {
243   if(s != CURL_SOCKET_BAD) {
244     /* only look for proper sockets */
245     return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
246   }
247   return NULL;
248 }
249 
250 #define TRHASH_SIZE 13
trhash(void * key,size_t key_length,size_t slots_num)251 static size_t trhash(void *key, size_t key_length, size_t slots_num)
252 {
253   size_t keyval = (size_t)*(struct Curl_easy **)key;
254   (void) key_length;
255 
256   return (keyval % slots_num);
257 }
258 
trhash_compare(void * k1,size_t k1_len,void * k2,size_t k2_len)259 static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
260 {
261   (void)k1_len;
262   (void)k2_len;
263 
264   return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2;
265 }
266 
trhash_dtor(void * nada)267 static void trhash_dtor(void *nada)
268 {
269   (void)nada;
270 }
271 
272 /*
273  * The sockhash has its own separate subhash in each entry that need to be
274  * safely destroyed first.
275  */
sockhash_destroy(struct Curl_hash * h)276 static void sockhash_destroy(struct Curl_hash *h)
277 {
278   struct Curl_hash_iterator iter;
279   struct Curl_hash_element *he;
280 
281   DEBUGASSERT(h);
282   Curl_hash_start_iterate(h, &iter);
283   he = Curl_hash_next_element(&iter);
284   while(he) {
285     struct Curl_sh_entry *sh = (struct Curl_sh_entry *)he->ptr;
286     Curl_hash_destroy(&sh->transfers);
287     he = Curl_hash_next_element(&iter);
288   }
289   Curl_hash_destroy(h);
290 }
291 
292 
293 /* make sure this socket is present in the hash for this handle */
sh_addentry(struct Curl_hash * sh,curl_socket_t s)294 static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
295                                          curl_socket_t s)
296 {
297   struct Curl_sh_entry *there = sh_getentry(sh, s);
298   struct Curl_sh_entry *check;
299 
300   if(there) {
301     /* it is present, return fine */
302     return there;
303   }
304 
305   /* not present, add it */
306   check = calloc(1, sizeof(struct Curl_sh_entry));
307   if(!check)
308     return NULL; /* major failure */
309 
310   Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, trhash_compare,
311                  trhash_dtor);
312 
313   /* make/add new hash entry */
314   if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
315     Curl_hash_destroy(&check->transfers);
316     free(check);
317     return NULL; /* major failure */
318   }
319 
320   return check; /* things are good in sockhash land */
321 }
322 
323 
324 /* delete the given socket + handle from the hash */
sh_delentry(struct Curl_sh_entry * entry,struct Curl_hash * sh,curl_socket_t s)325 static void sh_delentry(struct Curl_sh_entry *entry,
326                         struct Curl_hash *sh, curl_socket_t s)
327 {
328   Curl_hash_destroy(&entry->transfers);
329 
330   /* We remove the hash entry. This will end up in a call to
331      sh_freeentry(). */
332   Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
333 }
334 
335 /*
336  * free a sockhash entry
337  */
sh_freeentry(void * freethis)338 static void sh_freeentry(void *freethis)
339 {
340   struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
341 
342   free(p);
343 }
344 
fd_key_compare(void * k1,size_t k1_len,void * k2,size_t k2_len)345 static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
346 {
347   (void) k1_len; (void) k2_len;
348 
349   return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2));
350 }
351 
hash_fd(void * key,size_t key_length,size_t slots_num)352 static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
353 {
354   curl_socket_t fd = *((curl_socket_t *) key);
355   (void) key_length;
356 
357   return (fd % slots_num);
358 }
359 
360 /*
361  * sh_init() creates a new socket hash and returns the handle for it.
362  *
363  * Quote from README.multi_socket:
364  *
365  * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
366  * is somewhat of a bottle neck. Its current implementation may be a bit too
367  * limiting. It simply has a fixed-size array, and on each entry in the array
368  * it has a linked list with entries. So the hash only checks which list to
369  * scan through. The code I had used so for used a list with merely 7 slots
370  * (as that is what the DNS hash uses) but with 7000 connections that would
371  * make an average of 1000 nodes in each list to run through. I upped that to
372  * 97 slots (I believe a prime is suitable) and noticed a significant speed
373  * increase.  I need to reconsider the hash implementation or use a rather
374  * large default value like this. At 9000 connections I was still below 10us
375  * per call."
376  *
377  */
sh_init(struct Curl_hash * hash,int hashsize)378 static void sh_init(struct Curl_hash *hash, int hashsize)
379 {
380   Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
381                  sh_freeentry);
382 }
383 
384 /*
385  * multi_addmsg()
386  *
387  * Called when a transfer is completed. Adds the given msg pointer to
388  * the list kept in the multi handle.
389  */
multi_addmsg(struct Curl_multi * multi,struct Curl_message * msg)390 static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg)
391 {
392   Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg,
393                          &msg->list);
394 }
395 
Curl_multi_handle(int hashsize,int chashsize,int dnssize)396 struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
397                                      int chashsize, /* connection hash */
398                                      int dnssize) /* dns hash */
399 {
400   struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
401 
402   if(!multi)
403     return NULL;
404 
405   multi->magic = CURL_MULTI_HANDLE;
406 
407   Curl_init_dnscache(&multi->hostcache, dnssize);
408 
409   sh_init(&multi->sockhash, hashsize);
410 
411   if(Curl_conncache_init(&multi->conn_cache, chashsize))
412     goto error;
413 
414   Curl_llist_init(&multi->msglist, NULL);
415   Curl_llist_init(&multi->pending, NULL);
416   Curl_llist_init(&multi->msgsent, NULL);
417 
418   multi->multiplexing = TRUE;
419 
420   /* -1 means it not set by user, use the default value */
421   multi->maxconnects = -1;
422   multi->max_concurrent_streams = 100;
423 
424 #ifdef USE_WINSOCK
425   multi->wsa_event = WSACreateEvent();
426   if(multi->wsa_event == WSA_INVALID_EVENT)
427     goto error;
428 #else
429 #ifdef ENABLE_WAKEUP
430   if(wakeup_create(multi->wakeup_pair) < 0) {
431     multi->wakeup_pair[0] = CURL_SOCKET_BAD;
432     multi->wakeup_pair[1] = CURL_SOCKET_BAD;
433   }
434   else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 ||
435           curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) {
436     wakeup_close(multi->wakeup_pair[0]);
437     wakeup_close(multi->wakeup_pair[1]);
438     multi->wakeup_pair[0] = CURL_SOCKET_BAD;
439     multi->wakeup_pair[1] = CURL_SOCKET_BAD;
440   }
441 #endif
442 #endif
443 
444   return multi;
445 
446 error:
447 
448   sockhash_destroy(&multi->sockhash);
449   Curl_hash_destroy(&multi->hostcache);
450   Curl_conncache_destroy(&multi->conn_cache);
451   free(multi);
452   return NULL;
453 }
454 
curl_multi_init(void)455 struct Curl_multi *curl_multi_init(void)
456 {
457   return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
458                            CURL_CONNECTION_HASH_SIZE,
459                            CURL_DNS_HASH_SIZE);
460 }
461 
462 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
multi_warn_debug(struct Curl_multi * multi,struct Curl_easy * data)463 static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
464 {
465   if(!multi->warned) {
466     infof(data, "!!! WARNING !!!");
467     infof(data, "This is a debug build of libcurl, "
468           "do not use in production.");
469     multi->warned = true;
470   }
471 }
472 #else
473 #define multi_warn_debug(x,y) Curl_nop_stmt
474 #endif
475 
476 /* returns TRUE if the easy handle is supposed to be present in the main link
477    list */
in_main_list(struct Curl_easy * data)478 static bool in_main_list(struct Curl_easy *data)
479 {
480   return ((data->mstate != MSTATE_PENDING) &&
481           (data->mstate != MSTATE_MSGSENT));
482 }
483 
link_easy(struct Curl_multi * multi,struct Curl_easy * data)484 static void link_easy(struct Curl_multi *multi,
485                       struct Curl_easy *data)
486 {
487   /* We add the new easy entry last in the list. */
488   data->next = NULL; /* end of the line */
489   if(multi->easyp) {
490     struct Curl_easy *last = multi->easylp;
491     last->next = data;
492     data->prev = last;
493     multi->easylp = data; /* the new last node */
494   }
495   else {
496     /* first node, make prev NULL! */
497     data->prev = NULL;
498     multi->easylp = multi->easyp = data; /* both first and last */
499   }
500 }
501 
502 /* unlink the given easy handle from the linked list of easy handles */
unlink_easy(struct Curl_multi * multi,struct Curl_easy * data)503 static void unlink_easy(struct Curl_multi *multi,
504                         struct Curl_easy *data)
505 {
506   /* make the previous node point to our next */
507   if(data->prev)
508     data->prev->next = data->next;
509   else
510     multi->easyp = data->next; /* point to first node */
511 
512   /* make our next point to our previous node */
513   if(data->next)
514     data->next->prev = data->prev;
515   else
516     multi->easylp = data->prev; /* point to last node */
517 
518   data->prev = data->next = NULL;
519 }
520 
521 
curl_multi_add_handle(struct Curl_multi * multi,struct Curl_easy * data)522 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
523                                 struct Curl_easy *data)
524 {
525   CURLMcode rc;
526   /* First, make some basic checks that the CURLM handle is a good handle */
527   if(!GOOD_MULTI_HANDLE(multi))
528     return CURLM_BAD_HANDLE;
529 
530   /* Verify that we got a somewhat good easy handle too */
531   if(!GOOD_EASY_HANDLE(data))
532     return CURLM_BAD_EASY_HANDLE;
533 
534   /* Prevent users from adding same easy handle more than once and prevent
535      adding to more than one multi stack */
536   if(data->multi)
537     return CURLM_ADDED_ALREADY;
538 
539   if(multi->in_callback)
540     return CURLM_RECURSIVE_API_CALL;
541 
542   if(multi->dead) {
543     /* a "dead" handle cannot get added transfers while any existing easy
544        handles are still alive - but if there are none alive anymore, it is
545        fine to start over and unmark the "deadness" of this handle */
546     if(multi->num_alive)
547       return CURLM_ABORTED_BY_CALLBACK;
548     multi->dead = FALSE;
549   }
550 
551   /* Initialize timeout list for this handle */
552   Curl_llist_init(&data->state.timeoutlist, NULL);
553 
554   /*
555    * No failure allowed in this function beyond this point. And no
556    * modification of easy nor multi handle allowed before this except for
557    * potential multi's connection cache growing which won't be undone in this
558    * function no matter what.
559    */
560   if(data->set.errorbuffer)
561     data->set.errorbuffer[0] = 0;
562 
563   /* make the Curl_easy refer back to this multi handle - before Curl_expire()
564      is called. */
565   data->multi = multi;
566 
567   /* Set the timeout for this handle to expire really soon so that it will
568      be taken care of even when this handle is added in the midst of operation
569      when only the curl_multi_socket() API is used. During that flow, only
570      sockets that time-out or have actions will be dealt with. Since this
571      handle has no action yet, we make sure it times out to get things to
572      happen. */
573   Curl_expire(data, 0, EXPIRE_RUN_NOW);
574 
575   /* A somewhat crude work-around for a little glitch in Curl_update_timer()
576      that happens if the lastcall time is set to the same time when the handle
577      is removed as when the next handle is added, as then the check in
578      Curl_update_timer() that prevents calling the application multiple times
579      with the same timer info will not trigger and then the new handle's
580      timeout will not be notified to the app.
581 
582      The work-around is thus simply to clear the 'lastcall' variable to force
583      Curl_update_timer() to always trigger a callback to the app when a new
584      easy handle is added */
585   memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
586 
587   rc = Curl_update_timer(multi);
588   if(rc)
589     return rc;
590 
591   /* set the easy handle */
592   multistate(data, MSTATE_INIT);
593 
594   /* for multi interface connections, we share DNS cache automatically if the
595      easy handle's one is currently not set. */
596   if(!data->dns.hostcache ||
597      (data->dns.hostcachetype == HCACHE_NONE)) {
598     data->dns.hostcache = &multi->hostcache;
599     data->dns.hostcachetype = HCACHE_MULTI;
600   }
601 
602   /* Point to the shared or multi handle connection cache */
603   if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT)))
604     data->state.conn_cache = &data->share->conn_cache;
605   else
606     data->state.conn_cache = &multi->conn_cache;
607   data->state.lastconnect_id = -1;
608 
609 #ifdef USE_LIBPSL
610   /* Do the same for PSL. */
611   if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
612     data->psl = &data->share->psl;
613   else
614     data->psl = &multi->psl;
615 #endif
616 
617   link_easy(multi, data);
618 
619   /* increase the node-counter */
620   multi->num_easy++;
621 
622   /* increase the alive-counter */
623   multi->num_alive++;
624 
625   CONNCACHE_LOCK(data);
626   /* The closure handle only ever has default timeouts set. To improve the
627      state somewhat we clone the timeouts from each added handle so that the
628      closure handle always has the same timeouts as the most recently added
629      easy handle. */
630   data->state.conn_cache->closure_handle->set.timeout = data->set.timeout;
631   data->state.conn_cache->closure_handle->set.server_response_timeout =
632     data->set.server_response_timeout;
633   data->state.conn_cache->closure_handle->set.no_signal =
634     data->set.no_signal;
635   data->id = data->state.conn_cache->next_easy_id++;
636   if(data->state.conn_cache->next_easy_id <= 0)
637     data->state.conn_cache->next_easy_id = 0;
638   CONNCACHE_UNLOCK(data);
639 
640   multi_warn_debug(multi, data);
641 
642   return CURLM_OK;
643 }
644 
645 #if 0
646 /* Debug-function, used like this:
647  *
648  * Curl_hash_print(&multi->sockhash, debug_print_sock_hash);
649  *
650  * Enable the hash print function first by editing hash.c
651  */
652 static void debug_print_sock_hash(void *p)
653 {
654   struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
655 
656   fprintf(stderr, " [readers %u][writers %u]",
657           sh->readers, sh->writers);
658 }
659 #endif
660 
multi_done(struct Curl_easy * data,CURLcode status,bool premature)661 static CURLcode multi_done(struct Curl_easy *data,
662                            CURLcode status,  /* an error if this is called
663                                                 after an error was detected */
664                            bool premature)
665 {
666   CURLcode result;
667   struct connectdata *conn = data->conn;
668 
669 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
670   DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d",
671                multi_statename[data->mstate],
672                (int)status, (int)premature, data->state.done));
673 #else
674   DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d",
675                (int)status, (int)premature, data->state.done));
676 #endif
677 
678   if(data->state.done)
679     /* Stop if multi_done() has already been called */
680     return CURLE_OK;
681 
682   /* Stop the resolver and free its own resources (but not dns_entry yet). */
683   Curl_resolver_kill(data);
684 
685   /* Cleanup possible redirect junk */
686   Curl_safefree(data->req.newurl);
687   Curl_safefree(data->req.location);
688 
689   switch(status) {
690   case CURLE_ABORTED_BY_CALLBACK:
691   case CURLE_READ_ERROR:
692   case CURLE_WRITE_ERROR:
693     /* When we're aborted due to a callback return code it basically have to
694        be counted as premature as there is trouble ahead if we don't. We have
695        many callbacks and protocols work differently, we could potentially do
696        this more fine-grained in the future. */
697     premature = TRUE;
698   default:
699     break;
700   }
701 
702   /* this calls the protocol-specific function pointer previously set */
703   if(conn->handler->done)
704     result = conn->handler->done(data, status, premature);
705   else
706     result = status;
707 
708   if(CURLE_ABORTED_BY_CALLBACK != result) {
709     /* avoid this if we already aborted by callback to avoid this calling
710        another callback */
711     int rc = Curl_pgrsDone(data);
712     if(!result && rc)
713       result = CURLE_ABORTED_BY_CALLBACK;
714   }
715 
716   /* Inform connection filters that this transfer is done */
717   Curl_conn_ev_data_done(data, premature);
718 
719   process_pending_handles(data->multi); /* connection / multiplex */
720 
721   Curl_safefree(data->state.ulbuf);
722 
723   Curl_client_cleanup(data);
724 
725   CONNCACHE_LOCK(data);
726   Curl_detach_connection(data);
727   if(CONN_INUSE(conn)) {
728     /* Stop if still used. */
729     CONNCACHE_UNLOCK(data);
730     DEBUGF(infof(data, "Connection still in use %zu, "
731                  "no more multi_done now!",
732                  conn->easyq.size));
733     return CURLE_OK;
734   }
735 
736   data->state.done = TRUE; /* called just now! */
737 
738   if(conn->dns_entry) {
739     Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
740     conn->dns_entry = NULL;
741   }
742   Curl_hostcache_prune(data);
743 
744   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
745      forced us to close this connection. This is ignored for requests taking
746      place in a NTLM/NEGOTIATE authentication handshake
747 
748      if conn->bits.close is TRUE, it means that the connection should be
749      closed in spite of all our efforts to be nice, due to protocol
750      restrictions in our or the server's end
751 
752      if premature is TRUE, it means this connection was said to be DONE before
753      the entire request operation is complete and thus we can't know in what
754      state it is for reusing, so we're forced to close it. In a perfect world
755      we can add code that keep track of if we really must close it here or not,
756      but currently we have no such detail knowledge.
757   */
758 
759   data->state.recent_conn_id = conn->connection_id;
760   if((data->set.reuse_forbid
761 #if defined(USE_NTLM)
762       && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
763            conn->proxy_ntlm_state == NTLMSTATE_TYPE2)
764 #endif
765 #if defined(USE_SPNEGO)
766       && !(conn->http_negotiate_state == GSS_AUTHRECV ||
767            conn->proxy_negotiate_state == GSS_AUTHRECV)
768 #endif
769      ) || conn->bits.close
770        || (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) {
771     DEBUGF(infof(data, "multi_done, not reusing connection=%"
772                        CURL_FORMAT_CURL_OFF_T ", forbid=%d"
773                        ", close=%d, premature=%d, conn_multiplex=%d",
774                  conn->connection_id,
775                  data->set.reuse_forbid, conn->bits.close, premature,
776                  Curl_conn_is_multiplex(conn, FIRSTSOCKET)));
777     connclose(conn, "disconnecting");
778     Curl_conncache_remove_conn(data, conn, FALSE);
779     CONNCACHE_UNLOCK(data);
780     Curl_disconnect(data, conn, premature);
781   }
782   else {
783     char buffer[256];
784     const char *host =
785 #ifndef CURL_DISABLE_PROXY
786       conn->bits.socksproxy ?
787       conn->socks_proxy.host.dispname :
788       conn->bits.httpproxy ? conn->http_proxy.host.dispname :
789 #endif
790       conn->bits.conn_to_host ? conn->conn_to_host.dispname :
791       conn->host.dispname;
792     /* create string before returning the connection */
793     curl_off_t connection_id = conn->connection_id;
794     msnprintf(buffer, sizeof(buffer),
795               "Connection #%" CURL_FORMAT_CURL_OFF_T " to host %s left intact",
796               connection_id, host);
797     /* the connection is no longer in use by this transfer */
798     CONNCACHE_UNLOCK(data);
799     if(Curl_conncache_return_conn(data, conn)) {
800       /* remember the most recently used connection */
801       data->state.lastconnect_id = connection_id;
802       data->state.recent_conn_id = connection_id;
803       infof(data, "%s", buffer);
804     }
805     else
806       data->state.lastconnect_id = -1;
807   }
808 
809   Curl_safefree(data->state.buffer);
810   return result;
811 }
812 
close_connect_only(struct Curl_easy * data,struct connectdata * conn,void * param)813 static int close_connect_only(struct Curl_easy *data,
814                               struct connectdata *conn, void *param)
815 {
816   (void)param;
817   if(data->state.lastconnect_id != conn->connection_id)
818     return 0;
819 
820   if(!conn->connect_only)
821     return 1;
822 
823   connclose(conn, "Removing connect-only easy handle");
824 
825   return 1;
826 }
827 
curl_multi_remove_handle(struct Curl_multi * multi,struct Curl_easy * data)828 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
829                                    struct Curl_easy *data)
830 {
831   struct Curl_easy *easy = data;
832   bool premature;
833   struct Curl_llist_element *e;
834   CURLMcode rc;
835 
836   /* First, make some basic checks that the CURLM handle is a good handle */
837   if(!GOOD_MULTI_HANDLE(multi))
838     return CURLM_BAD_HANDLE;
839 
840   /* Verify that we got a somewhat good easy handle too */
841   if(!GOOD_EASY_HANDLE(data))
842     return CURLM_BAD_EASY_HANDLE;
843 
844   /* Prevent users from trying to remove same easy handle more than once */
845   if(!data->multi)
846     return CURLM_OK; /* it is already removed so let's say it is fine! */
847 
848   /* Prevent users from trying to remove an easy handle from the wrong multi */
849   if(data->multi != multi)
850     return CURLM_BAD_EASY_HANDLE;
851 
852   if(multi->in_callback)
853     return CURLM_RECURSIVE_API_CALL;
854 
855   premature = (data->mstate < MSTATE_COMPLETED) ? TRUE : FALSE;
856 
857   /* If the 'state' is not INIT or COMPLETED, we might need to do something
858      nice to put the easy_handle in a good known state when this returns. */
859   if(premature) {
860     /* this handle is "alive" so we need to count down the total number of
861        alive connections when this is removed */
862     multi->num_alive--;
863   }
864 
865   if(data->conn &&
866      data->mstate > MSTATE_DO &&
867      data->mstate < MSTATE_COMPLETED) {
868     /* Set connection owner so that the DONE function closes it.  We can
869        safely do this here since connection is killed. */
870     streamclose(data->conn, "Removed with partial response");
871   }
872 
873   if(data->conn) {
874     /* multi_done() clears the association between the easy handle and the
875        connection.
876 
877        Note that this ignores the return code simply because there's
878        nothing really useful to do with it anyway! */
879     (void)multi_done(data, data->result, premature);
880   }
881 
882   /* The timer must be shut down before data->multi is set to NULL, else the
883      timenode will remain in the splay tree after curl_easy_cleanup is
884      called. Do it after multi_done() in case that sets another time! */
885   Curl_expire_clear(data);
886 
887   if(data->connect_queue.ptr) {
888     /* the handle is in the pending or msgsent lists, so go ahead and remove
889        it */
890     if(data->mstate == MSTATE_PENDING)
891       Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
892     else
893       Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL);
894   }
895   if(in_main_list(data))
896     unlink_easy(multi, data);
897 
898   if(data->dns.hostcachetype == HCACHE_MULTI) {
899     /* stop using the multi handle's DNS cache, *after* the possible
900        multi_done() call above */
901     data->dns.hostcache = NULL;
902     data->dns.hostcachetype = HCACHE_NONE;
903   }
904 
905   Curl_wildcard_dtor(&data->wildcard);
906 
907   /* change state without using multistate(), only to make singlesocket() do
908      what we want */
909   data->mstate = MSTATE_COMPLETED;
910 
911   /* This ignores the return code even in case of problems because there's
912      nothing more to do about that, here */
913   (void)singlesocket(multi, easy); /* to let the application know what sockets
914                                       that vanish with this handle */
915 
916   /* Remove the association between the connection and the handle */
917   Curl_detach_connection(data);
918 
919   if(data->set.connect_only && !data->multi_easy) {
920     /* This removes a handle that was part the multi interface that used
921        CONNECT_ONLY, that connection is now left alive but since this handle
922        has bits.close set nothing can use that transfer anymore and it is
923        forbidden from reuse. And this easy handle cannot find the connection
924        anymore once removed from the multi handle
925 
926        Better close the connection here, at once.
927     */
928     struct connectdata *c;
929     curl_socket_t s;
930     s = Curl_getconnectinfo(data, &c);
931     if((s != CURL_SOCKET_BAD) && c) {
932       Curl_conncache_remove_conn(data, c, TRUE);
933       Curl_disconnect(data, c, TRUE);
934     }
935   }
936 
937   if(data->state.lastconnect_id != -1) {
938     /* Mark any connect-only connection for closure */
939     Curl_conncache_foreach(data, data->state.conn_cache,
940                            NULL, close_connect_only);
941   }
942 
943 #ifdef USE_LIBPSL
944   /* Remove the PSL association. */
945   if(data->psl == &multi->psl)
946     data->psl = NULL;
947 #endif
948 
949   /* as this was using a shared connection cache we clear the pointer to that
950      since we're not part of that multi handle anymore */
951   data->state.conn_cache = NULL;
952 
953   data->multi = NULL; /* clear the association to this multi handle */
954 
955   /* make sure there's no pending message in the queue sent from this easy
956      handle */
957   for(e = multi->msglist.head; e; e = e->next) {
958     struct Curl_message *msg = e->ptr;
959 
960     if(msg->extmsg.easy_handle == easy) {
961       Curl_llist_remove(&multi->msglist, e, NULL);
962       /* there can only be one from this specific handle */
963       break;
964     }
965   }
966 
967   /* NOTE NOTE NOTE
968      We do not touch the easy handle here! */
969   multi->num_easy--; /* one less to care about now */
970 
971   process_pending_handles(multi);
972 
973   rc = Curl_update_timer(multi);
974   if(rc)
975     return rc;
976   return CURLM_OK;
977 }
978 
979 /* Return TRUE if the application asked for multiplexing */
Curl_multiplex_wanted(const struct Curl_multi * multi)980 bool Curl_multiplex_wanted(const struct Curl_multi *multi)
981 {
982   return (multi && (multi->multiplexing));
983 }
984 
985 /*
986  * Curl_detach_connection() removes the given transfer from the connection.
987  *
988  * This is the only function that should clear data->conn. This will
989  * occasionally be called with the data->conn pointer already cleared.
990  */
Curl_detach_connection(struct Curl_easy * data)991 void Curl_detach_connection(struct Curl_easy *data)
992 {
993   struct connectdata *conn = data->conn;
994   if(conn) {
995     Curl_conn_ev_data_detach(conn, data);
996     Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
997   }
998   data->conn = NULL;
999 }
1000 
1001 /*
1002  * Curl_attach_connection() attaches this transfer to this connection.
1003  *
1004  * This is the only function that should assign data->conn
1005  */
Curl_attach_connection(struct Curl_easy * data,struct connectdata * conn)1006 void Curl_attach_connection(struct Curl_easy *data,
1007                              struct connectdata *conn)
1008 {
1009   DEBUGASSERT(!data->conn);
1010   DEBUGASSERT(conn);
1011   data->conn = conn;
1012   Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data,
1013                          &data->conn_queue);
1014   if(conn->handler && conn->handler->attach)
1015     conn->handler->attach(data, conn);
1016   Curl_conn_ev_data_attach(conn, data);
1017 }
1018 
domore_getsock(struct Curl_easy * data,struct connectdata * conn,curl_socket_t * socks)1019 static int domore_getsock(struct Curl_easy *data,
1020                           struct connectdata *conn,
1021                           curl_socket_t *socks)
1022 {
1023   if(conn && conn->handler->domore_getsock)
1024     return conn->handler->domore_getsock(data, conn, socks);
1025   return GETSOCK_BLANK;
1026 }
1027 
doing_getsock(struct Curl_easy * data,struct connectdata * conn,curl_socket_t * socks)1028 static int doing_getsock(struct Curl_easy *data,
1029                          struct connectdata *conn,
1030                          curl_socket_t *socks)
1031 {
1032   if(conn && conn->handler->doing_getsock)
1033     return conn->handler->doing_getsock(data, conn, socks);
1034   return GETSOCK_BLANK;
1035 }
1036 
protocol_getsock(struct Curl_easy * data,struct connectdata * conn,curl_socket_t * socks)1037 static int protocol_getsock(struct Curl_easy *data,
1038                             struct connectdata *conn,
1039                             curl_socket_t *socks)
1040 {
1041   if(conn->handler->proto_getsock)
1042     return conn->handler->proto_getsock(data, conn, socks);
1043   return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks);
1044 }
1045 
1046 /* returns bitmapped flags for this handle and its sockets. The 'socks[]'
1047    array contains MAX_SOCKSPEREASYHANDLE entries. */
multi_getsock(struct Curl_easy * data,curl_socket_t * socks)1048 static int multi_getsock(struct Curl_easy *data,
1049                          curl_socket_t *socks)
1050 {
1051   struct connectdata *conn = data->conn;
1052   /* The no connection case can happen when this is called from
1053      curl_multi_remove_handle() => singlesocket() => multi_getsock().
1054   */
1055   if(!conn)
1056     return 0;
1057 
1058   switch(data->mstate) {
1059   default:
1060     return 0;
1061 
1062   case MSTATE_RESOLVING:
1063     return Curl_resolv_getsock(data, socks);
1064 
1065   case MSTATE_PROTOCONNECTING:
1066   case MSTATE_PROTOCONNECT:
1067     return protocol_getsock(data, conn, socks);
1068 
1069   case MSTATE_DO:
1070   case MSTATE_DOING:
1071     return doing_getsock(data, conn, socks);
1072 
1073   case MSTATE_TUNNELING:
1074   case MSTATE_CONNECTING:
1075     return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks);
1076 
1077   case MSTATE_DOING_MORE:
1078     return domore_getsock(data, conn, socks);
1079 
1080   case MSTATE_DID: /* since is set after DO is completed, we switch to
1081                         waiting for the same as the PERFORMING state */
1082   case MSTATE_PERFORMING:
1083     return Curl_single_getsock(data, conn, socks);
1084   }
1085 
1086 }
1087 
curl_multi_fdset(struct Curl_multi * multi,fd_set * read_fd_set,fd_set * write_fd_set,fd_set * exc_fd_set,int * max_fd)1088 CURLMcode curl_multi_fdset(struct Curl_multi *multi,
1089                            fd_set *read_fd_set, fd_set *write_fd_set,
1090                            fd_set *exc_fd_set, int *max_fd)
1091 {
1092   /* Scan through all the easy handles to get the file descriptors set.
1093      Some easy handles may not have connected to the remote host yet,
1094      and then we must make sure that is done. */
1095   struct Curl_easy *data;
1096   int this_max_fd = -1;
1097   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
1098   int i;
1099   (void)exc_fd_set; /* not used */
1100 
1101   if(!GOOD_MULTI_HANDLE(multi))
1102     return CURLM_BAD_HANDLE;
1103 
1104   if(multi->in_callback)
1105     return CURLM_RECURSIVE_API_CALL;
1106 
1107   for(data = multi->easyp; data; data = data->next) {
1108     int bitmap;
1109 #ifdef __clang_analyzer_
1110     /* to prevent "The left operand of '>=' is a garbage value" warnings */
1111     memset(sockbunch, 0, sizeof(sockbunch));
1112 #endif
1113     bitmap = multi_getsock(data, sockbunch);
1114 
1115     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
1116       if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
1117         if(!FDSET_SOCK(sockbunch[i]))
1118           /* pretend it doesn't exist */
1119           continue;
1120         if(bitmap & GETSOCK_READSOCK(i))
1121           FD_SET(sockbunch[i], read_fd_set);
1122         if(bitmap & GETSOCK_WRITESOCK(i))
1123           FD_SET(sockbunch[i], write_fd_set);
1124         if((int)sockbunch[i] > this_max_fd)
1125           this_max_fd = (int)sockbunch[i];
1126       }
1127       else {
1128         break;
1129       }
1130     }
1131   }
1132 
1133   *max_fd = this_max_fd;
1134 
1135   return CURLM_OK;
1136 }
1137 
1138 #ifdef USE_WINSOCK
1139 /* Reset FD_WRITE for TCP sockets. Nothing is actually sent. UDP sockets can't
1140  * be reset this way because an empty datagram would be sent. #9203
1141  *
1142  * "On Windows the internal state of FD_WRITE as returned from
1143  * WSAEnumNetworkEvents is only reset after successful send()."
1144  */
reset_socket_fdwrite(curl_socket_t s)1145 static void reset_socket_fdwrite(curl_socket_t s)
1146 {
1147   int t;
1148   int l = (int)sizeof(t);
1149   if(!getsockopt(s, SOL_SOCKET, SO_TYPE, (char *)&t, &l) && t == SOCK_STREAM)
1150     send(s, NULL, 0, 0);
1151 }
1152 #endif
1153 
1154 #define NUM_POLLS_ON_STACK 10
1155 
multi_wait(struct Curl_multi * multi,struct curl_waitfd extra_fds[],unsigned int extra_nfds,int timeout_ms,int * ret,bool extrawait,bool use_wakeup)1156 static CURLMcode multi_wait(struct Curl_multi *multi,
1157                             struct curl_waitfd extra_fds[],
1158                             unsigned int extra_nfds,
1159                             int timeout_ms,
1160                             int *ret,
1161                             bool extrawait, /* when no socket, wait */
1162                             bool use_wakeup)
1163 {
1164   struct Curl_easy *data;
1165   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
1166   int bitmap;
1167   unsigned int i;
1168   unsigned int nfds = 0;
1169   unsigned int curlfds;
1170   long timeout_internal;
1171   int retcode = 0;
1172   struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
1173   struct pollfd *ufds = &a_few_on_stack[0];
1174   bool ufds_malloc = FALSE;
1175 #ifdef USE_WINSOCK
1176   WSANETWORKEVENTS wsa_events;
1177   DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
1178 #endif
1179 #ifndef ENABLE_WAKEUP
1180   (void)use_wakeup;
1181 #endif
1182 
1183   if(!GOOD_MULTI_HANDLE(multi))
1184     return CURLM_BAD_HANDLE;
1185 
1186   if(multi->in_callback)
1187     return CURLM_RECURSIVE_API_CALL;
1188 
1189   if(timeout_ms < 0)
1190     return CURLM_BAD_FUNCTION_ARGUMENT;
1191 
1192   /* Count up how many fds we have from the multi handle */
1193   for(data = multi->easyp; data; data = data->next) {
1194     bitmap = multi_getsock(data, sockbunch);
1195 
1196     for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
1197       if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
1198         ++nfds;
1199       }
1200       else {
1201         break;
1202       }
1203     }
1204   }
1205 
1206   /* If the internally desired timeout is actually shorter than requested from
1207      the outside, then use the shorter time! But only if the internal timer
1208      is actually larger than -1! */
1209   (void)multi_timeout(multi, &timeout_internal);
1210   if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
1211     timeout_ms = (int)timeout_internal;
1212 
1213   curlfds = nfds; /* number of internal file descriptors */
1214   nfds += extra_nfds; /* add the externally provided ones */
1215 
1216 #ifdef ENABLE_WAKEUP
1217 #ifdef USE_WINSOCK
1218   if(use_wakeup) {
1219 #else
1220   if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1221 #endif
1222     ++nfds;
1223   }
1224 #endif
1225 
1226   if(nfds > NUM_POLLS_ON_STACK) {
1227     /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
1228        big, so at 2^29 sockets this value might wrap. When a process gets
1229        the capability to actually handle over 500 million sockets this
1230        calculation needs a integer overflow check. */
1231     ufds = malloc(nfds * sizeof(struct pollfd));
1232     if(!ufds)
1233       return CURLM_OUT_OF_MEMORY;
1234     ufds_malloc = TRUE;
1235   }
1236   nfds = 0;
1237 
1238   /* only do the second loop if we found descriptors in the first stage run
1239      above */
1240 
1241   if(curlfds) {
1242     /* Add the curl handles to our pollfds first */
1243     for(data = multi->easyp; data; data = data->next) {
1244       bitmap = multi_getsock(data, sockbunch);
1245 
1246       for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
1247         if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
1248           struct pollfd *ufd = &ufds[nfds++];
1249 #ifdef USE_WINSOCK
1250           long mask = 0;
1251 #endif
1252           ufd->fd = sockbunch[i];
1253           ufd->events = 0;
1254           if(bitmap & GETSOCK_READSOCK(i)) {
1255 #ifdef USE_WINSOCK
1256             mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
1257 #endif
1258             ufd->events |= POLLIN;
1259           }
1260           if(bitmap & GETSOCK_WRITESOCK(i)) {
1261 #ifdef USE_WINSOCK
1262             mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
1263             reset_socket_fdwrite(sockbunch[i]);
1264 #endif
1265             ufd->events |= POLLOUT;
1266           }
1267 #ifdef USE_WINSOCK
1268           if(WSAEventSelect(sockbunch[i], multi->wsa_event, mask) != 0) {
1269             if(ufds_malloc)
1270               free(ufds);
1271             return CURLM_INTERNAL_ERROR;
1272           }
1273 #endif
1274         }
1275         else {
1276           break;
1277         }
1278       }
1279     }
1280   }
1281 
1282   /* Add external file descriptions from poll-like struct curl_waitfd */
1283   for(i = 0; i < extra_nfds; i++) {
1284 #ifdef USE_WINSOCK
1285     long mask = 0;
1286     if(extra_fds[i].events & CURL_WAIT_POLLIN)
1287       mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
1288     if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1289       mask |= FD_OOB;
1290     if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
1291       mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
1292       reset_socket_fdwrite(extra_fds[i].fd);
1293     }
1294     if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) {
1295       if(ufds_malloc)
1296         free(ufds);
1297       return CURLM_INTERNAL_ERROR;
1298     }
1299 #endif
1300     ufds[nfds].fd = extra_fds[i].fd;
1301     ufds[nfds].events = 0;
1302     if(extra_fds[i].events & CURL_WAIT_POLLIN)
1303       ufds[nfds].events |= POLLIN;
1304     if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1305       ufds[nfds].events |= POLLPRI;
1306     if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1307       ufds[nfds].events |= POLLOUT;
1308     ++nfds;
1309   }
1310 
1311 #ifdef ENABLE_WAKEUP
1312 #ifndef USE_WINSOCK
1313   if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1314     ufds[nfds].fd = multi->wakeup_pair[0];
1315     ufds[nfds].events = POLLIN;
1316     ++nfds;
1317   }
1318 #endif
1319 #endif
1320 
1321 #if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK)
1322   if(nfds || use_wakeup) {
1323 #else
1324   if(nfds) {
1325 #endif
1326     int pollrc;
1327 #ifdef USE_WINSOCK
1328     if(nfds)
1329       pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */
1330     else
1331       pollrc = 0;
1332 #else
1333     pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
1334 #endif
1335     if(pollrc < 0)
1336       return CURLM_UNRECOVERABLE_POLL;
1337 
1338     if(pollrc > 0) {
1339       retcode = pollrc;
1340 #ifdef USE_WINSOCK
1341     }
1342     else { /* now wait... if not ready during the pre-check (pollrc == 0) */
1343       WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
1344     }
1345     /* With WinSock, we have to run the following section unconditionally
1346        to call WSAEventSelect(fd, event, 0) on all the sockets */
1347     {
1348 #endif
1349       /* copy revents results from the poll to the curl_multi_wait poll
1350          struct, the bit values of the actual underlying poll() implementation
1351          may not be the same as the ones in the public libcurl API! */
1352       for(i = 0; i < extra_nfds; i++) {
1353         unsigned r = ufds[curlfds + i].revents;
1354         unsigned short mask = 0;
1355 #ifdef USE_WINSOCK
1356         curl_socket_t s = extra_fds[i].fd;
1357         wsa_events.lNetworkEvents = 0;
1358         if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) {
1359           if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE))
1360             mask |= CURL_WAIT_POLLIN;
1361           if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE))
1362             mask |= CURL_WAIT_POLLOUT;
1363           if(wsa_events.lNetworkEvents & FD_OOB)
1364             mask |= CURL_WAIT_POLLPRI;
1365           if(ret && !pollrc && wsa_events.lNetworkEvents)
1366             retcode++;
1367         }
1368         WSAEventSelect(s, multi->wsa_event, 0);
1369         if(!pollrc) {
1370           extra_fds[i].revents = mask;
1371           continue;
1372         }
1373 #endif
1374         if(r & POLLIN)
1375           mask |= CURL_WAIT_POLLIN;
1376         if(r & POLLOUT)
1377           mask |= CURL_WAIT_POLLOUT;
1378         if(r & POLLPRI)
1379           mask |= CURL_WAIT_POLLPRI;
1380         extra_fds[i].revents = mask;
1381       }
1382 
1383 #ifdef USE_WINSOCK
1384       /* Count up all our own sockets that had activity,
1385          and remove them from the event. */
1386       if(curlfds) {
1387 
1388         for(data = multi->easyp; data; data = data->next) {
1389           bitmap = multi_getsock(data, sockbunch);
1390 
1391           for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
1392             if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
1393               wsa_events.lNetworkEvents = 0;
1394               if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) {
1395                 if(ret && !pollrc && wsa_events.lNetworkEvents)
1396                   retcode++;
1397               }
1398               WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
1399             }
1400             else {
1401               /* break on entry not checked for being readable or writable */
1402               break;
1403             }
1404           }
1405         }
1406       }
1407 
1408       WSAResetEvent(multi->wsa_event);
1409 #else
1410 #ifdef ENABLE_WAKEUP
1411       if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1412         if(ufds[curlfds + extra_nfds].revents & POLLIN) {
1413           char buf[64];
1414           ssize_t nread;
1415           while(1) {
1416             /* the reading socket is non-blocking, try to read
1417                data from it until it receives an error (except EINTR).
1418                In normal cases it will get EAGAIN or EWOULDBLOCK
1419                when there is no more data, breaking the loop. */
1420             nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf));
1421             if(nread <= 0) {
1422               if(nread < 0 && EINTR == SOCKERRNO)
1423                 continue;
1424               break;
1425             }
1426           }
1427           /* do not count the wakeup socket into the returned value */
1428           retcode--;
1429         }
1430       }
1431 #endif
1432 #endif
1433     }
1434   }
1435 
1436   if(ufds_malloc)
1437     free(ufds);
1438   if(ret)
1439     *ret = retcode;
1440 #if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK)
1441   if(extrawait && !nfds && !use_wakeup) {
1442 #else
1443   if(extrawait && !nfds) {
1444 #endif
1445     long sleep_ms = 0;
1446 
1447     /* Avoid busy-looping when there's nothing particular to wait for */
1448     if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
1449       if(sleep_ms > timeout_ms)
1450         sleep_ms = timeout_ms;
1451       /* when there are no easy handles in the multi, this holds a -1
1452          timeout */
1453       else if(sleep_ms < 0)
1454         sleep_ms = timeout_ms;
1455       Curl_wait_ms(sleep_ms);
1456     }
1457   }
1458 
1459   return CURLM_OK;
1460 }
1461 
1462 CURLMcode curl_multi_wait(struct Curl_multi *multi,
1463                           struct curl_waitfd extra_fds[],
1464                           unsigned int extra_nfds,
1465                           int timeout_ms,
1466                           int *ret)
1467 {
1468   return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
1469                     FALSE);
1470 }
1471 
1472 CURLMcode curl_multi_poll(struct Curl_multi *multi,
1473                           struct curl_waitfd extra_fds[],
1474                           unsigned int extra_nfds,
1475                           int timeout_ms,
1476                           int *ret)
1477 {
1478   return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
1479                     TRUE);
1480 }
1481 
1482 CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
1483 {
1484   /* this function is usually called from another thread,
1485      it has to be careful only to access parts of the
1486      Curl_multi struct that are constant */
1487 
1488   /* GOOD_MULTI_HANDLE can be safely called */
1489   if(!GOOD_MULTI_HANDLE(multi))
1490     return CURLM_BAD_HANDLE;
1491 
1492 #ifdef ENABLE_WAKEUP
1493 #ifdef USE_WINSOCK
1494   if(WSASetEvent(multi->wsa_event))
1495     return CURLM_OK;
1496 #else
1497   /* the wakeup_pair variable is only written during init and cleanup,
1498      making it safe to access from another thread after the init part
1499      and before cleanup */
1500   if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
1501     char buf[1];
1502     buf[0] = 1;
1503     while(1) {
1504       /* swrite() is not thread-safe in general, because concurrent calls
1505          can have their messages interleaved, but in this case the content
1506          of the messages does not matter, which makes it ok to call.
1507 
1508          The write socket is set to non-blocking, this way this function
1509          cannot block, making it safe to call even from the same thread
1510          that will call curl_multi_wait(). If swrite() returns that it
1511          would block, it's considered successful because it means that
1512          previous calls to this function will wake up the poll(). */
1513       if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1514         int err = SOCKERRNO;
1515         int return_success;
1516 #ifdef USE_WINSOCK
1517         return_success = WSAEWOULDBLOCK == err;
1518 #else
1519         if(EINTR == err)
1520           continue;
1521         return_success = EWOULDBLOCK == err || EAGAIN == err;
1522 #endif
1523         if(!return_success)
1524           return CURLM_WAKEUP_FAILURE;
1525       }
1526       return CURLM_OK;
1527     }
1528   }
1529 #endif
1530 #endif
1531   return CURLM_WAKEUP_FAILURE;
1532 }
1533 
1534 /*
1535  * multi_ischanged() is called
1536  *
1537  * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1538  * => CONNECT action.
1539  *
1540  * Set 'clear' to TRUE to have it also clear the state variable.
1541  */
1542 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1543 {
1544   bool retval = multi->recheckstate;
1545   if(clear)
1546     multi->recheckstate = FALSE;
1547   return retval;
1548 }
1549 
1550 /*
1551  * Curl_multi_connchanged() is called to tell that there is a connection in
1552  * this multi handle that has changed state (multiplexing become possible, the
1553  * number of allowed streams changed or similar), and a subsequent use of this
1554  * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1555  * retry.
1556  */
1557 void Curl_multi_connchanged(struct Curl_multi *multi)
1558 {
1559   multi->recheckstate = TRUE;
1560 }
1561 
1562 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1563                                  struct Curl_easy *data,
1564                                  struct connectdata *conn)
1565 {
1566   CURLMcode rc;
1567 
1568   if(multi->in_callback)
1569     return CURLM_RECURSIVE_API_CALL;
1570 
1571   rc = curl_multi_add_handle(multi, data);
1572   if(!rc) {
1573     struct SingleRequest *k = &data->req;
1574 
1575     /* pass in NULL for 'conn' here since we don't want to init the
1576        connection, only this transfer */
1577     Curl_init_do(data, NULL);
1578 
1579     /* take this handle to the perform state right away */
1580     multistate(data, MSTATE_PERFORMING);
1581     Curl_attach_connection(data, conn);
1582     k->keepon |= KEEP_RECV; /* setup to receive! */
1583   }
1584   return rc;
1585 }
1586 
1587 static CURLcode multi_do(struct Curl_easy *data, bool *done)
1588 {
1589   CURLcode result = CURLE_OK;
1590   struct connectdata *conn = data->conn;
1591 
1592   DEBUGASSERT(conn);
1593   DEBUGASSERT(conn->handler);
1594 
1595   if(conn->handler->do_it)
1596     result = conn->handler->do_it(data, done);
1597 
1598   return result;
1599 }
1600 
1601 /*
1602  * multi_do_more() is called during the DO_MORE multi state. It is basically a
1603  * second stage DO state which (wrongly) was introduced to support FTP's
1604  * second connection.
1605  *
1606  * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1607  * DOING state there's more work to do!
1608  */
1609 
1610 static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
1611 {
1612   CURLcode result = CURLE_OK;
1613   struct connectdata *conn = data->conn;
1614 
1615   *complete = 0;
1616 
1617   if(conn->handler->do_more)
1618     result = conn->handler->do_more(data, complete);
1619 
1620   return result;
1621 }
1622 
1623 /*
1624  * Check whether a timeout occurred, and handle it if it did
1625  */
1626 static bool multi_handle_timeout(struct Curl_easy *data,
1627                                  struct curltime *now,
1628                                  bool *stream_error,
1629                                  CURLcode *result,
1630                                  bool connect_timeout)
1631 {
1632   timediff_t timeout_ms;
1633   timeout_ms = Curl_timeleft(data, now, connect_timeout);
1634 
1635   if(timeout_ms < 0) {
1636     /* Handle timed out */
1637     if(data->mstate == MSTATE_RESOLVING)
1638       failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
1639             " milliseconds",
1640             Curl_timediff(*now, data->progress.t_startsingle));
1641     else if(data->mstate == MSTATE_CONNECTING)
1642       failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
1643             " milliseconds",
1644             Curl_timediff(*now, data->progress.t_startsingle));
1645     else {
1646       struct SingleRequest *k = &data->req;
1647       if(k->size != -1) {
1648         failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
1649               " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
1650               CURL_FORMAT_CURL_OFF_T " bytes received",
1651               Curl_timediff(*now, data->progress.t_startsingle),
1652               k->bytecount, k->size);
1653       }
1654       else {
1655         failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
1656               " milliseconds with %" CURL_FORMAT_CURL_OFF_T
1657               " bytes received",
1658               Curl_timediff(*now, data->progress.t_startsingle),
1659               k->bytecount);
1660       }
1661     }
1662 
1663     /* Force connection closed if the connection has indeed been used */
1664     if(data->mstate > MSTATE_DO) {
1665       streamclose(data->conn, "Disconnected with pending data");
1666       *stream_error = TRUE;
1667     }
1668     *result = CURLE_OPERATION_TIMEDOUT;
1669     (void)multi_done(data, *result, TRUE);
1670   }
1671 
1672   return (timeout_ms < 0);
1673 }
1674 
1675 /*
1676  * We are doing protocol-specific connecting and this is being called over and
1677  * over from the multi interface until the connection phase is done on
1678  * protocol layer.
1679  */
1680 
1681 static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
1682 {
1683   CURLcode result = CURLE_OK;
1684   struct connectdata *conn = data->conn;
1685 
1686   if(conn && conn->handler->connecting) {
1687     *done = FALSE;
1688     result = conn->handler->connecting(data, done);
1689   }
1690   else
1691     *done = TRUE;
1692 
1693   return result;
1694 }
1695 
1696 /*
1697  * We are DOING this is being called over and over from the multi interface
1698  * until the DOING phase is done on protocol layer.
1699  */
1700 
1701 static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
1702 {
1703   CURLcode result = CURLE_OK;
1704   struct connectdata *conn = data->conn;
1705 
1706   if(conn && conn->handler->doing) {
1707     *done = FALSE;
1708     result = conn->handler->doing(data, done);
1709   }
1710   else
1711     *done = TRUE;
1712 
1713   return result;
1714 }
1715 
1716 /*
1717  * We have discovered that the TCP connection has been successful, we can now
1718  * proceed with some action.
1719  *
1720  */
1721 static CURLcode protocol_connect(struct Curl_easy *data,
1722                                  bool *protocol_done)
1723 {
1724   CURLcode result = CURLE_OK;
1725   struct connectdata *conn = data->conn;
1726   DEBUGASSERT(conn);
1727   DEBUGASSERT(protocol_done);
1728 
1729   *protocol_done = FALSE;
1730 
1731   if(Curl_conn_is_connected(conn, FIRSTSOCKET)
1732      && conn->bits.protoconnstart) {
1733     /* We already are connected, get back. This may happen when the connect
1734        worked fine in the first call, like when we connect to a local server
1735        or proxy. Note that we don't know if the protocol is actually done.
1736 
1737        Unless this protocol doesn't have any protocol-connect callback, as
1738        then we know we're done. */
1739     if(!conn->handler->connecting)
1740       *protocol_done = TRUE;
1741 
1742     return CURLE_OK;
1743   }
1744 
1745   if(!conn->bits.protoconnstart) {
1746     if(conn->handler->connect_it) {
1747       /* is there a protocol-specific connect() procedure? */
1748 
1749       /* Call the protocol-specific connect function */
1750       result = conn->handler->connect_it(data, protocol_done);
1751     }
1752     else
1753       *protocol_done = TRUE;
1754 
1755     /* it has started, possibly even completed but that knowledge isn't stored
1756        in this bit! */
1757     if(!result)
1758       conn->bits.protoconnstart = TRUE;
1759   }
1760 
1761   return result; /* pass back status */
1762 }
1763 
1764 /*
1765  * readrewind() rewinds the read stream. This is typically used for HTTP
1766  * POST/PUT with multi-pass authentication when a sending was denied and a
1767  * resend is necessary.
1768  */
1769 static CURLcode readrewind(struct Curl_easy *data)
1770 {
1771   curl_mimepart *mimepart = &data->set.mimepost;
1772   DEBUGASSERT(data->conn);
1773 
1774   data->state.rewindbeforesend = FALSE; /* we rewind now */
1775 
1776   /* explicitly switch off sending data on this connection now since we are
1777      about to restart a new transfer and thus we want to avoid inadvertently
1778      sending more data on the existing connection until the next transfer
1779      starts */
1780   data->req.keepon &= ~KEEP_SEND;
1781 
1782   /* We have sent away data. If not using CURLOPT_POSTFIELDS or
1783      CURLOPT_HTTPPOST, call app to rewind
1784   */
1785 #ifndef CURL_DISABLE_HTTP
1786   if(data->conn->handler->protocol & PROTO_FAMILY_HTTP) {
1787     if(data->state.mimepost)
1788       mimepart = data->state.mimepost;
1789   }
1790 #endif
1791   if(data->set.postfields ||
1792      (data->state.httpreq == HTTPREQ_GET) ||
1793      (data->state.httpreq == HTTPREQ_HEAD))
1794     ; /* no need to rewind */
1795   else if(data->state.httpreq == HTTPREQ_POST_MIME ||
1796           data->state.httpreq == HTTPREQ_POST_FORM) {
1797     CURLcode result = Curl_mime_rewind(mimepart);
1798     if(result) {
1799       failf(data, "Cannot rewind mime/post data");
1800       return result;
1801     }
1802   }
1803   else {
1804     if(data->set.seek_func) {
1805       int err;
1806 
1807       Curl_set_in_callback(data, true);
1808       err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
1809       Curl_set_in_callback(data, false);
1810       if(err) {
1811         failf(data, "seek callback returned error %d", (int)err);
1812         return CURLE_SEND_FAIL_REWIND;
1813       }
1814     }
1815     else if(data->set.ioctl_func) {
1816       curlioerr err;
1817 
1818       Curl_set_in_callback(data, true);
1819       err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
1820                                    data->set.ioctl_client);
1821       Curl_set_in_callback(data, false);
1822       infof(data, "the ioctl callback returned %d", (int)err);
1823 
1824       if(err) {
1825         failf(data, "ioctl callback returned error %d", (int)err);
1826         return CURLE_SEND_FAIL_REWIND;
1827       }
1828     }
1829     else {
1830       /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
1831          given FILE * stream and we can actually attempt to rewind that
1832          ourselves with fseek() */
1833       if(data->state.fread_func == (curl_read_callback)fread) {
1834         if(-1 != fseek(data->state.in, 0, SEEK_SET))
1835           /* successful rewind */
1836           return CURLE_OK;
1837       }
1838 
1839       /* no callback set or failure above, makes us fail at once */
1840       failf(data, "necessary data rewind wasn't possible");
1841       return CURLE_SEND_FAIL_REWIND;
1842     }
1843   }
1844   return CURLE_OK;
1845 }
1846 
1847 /*
1848  * Curl_preconnect() is called immediately before a connect starts. When a
1849  * redirect is followed, this is then called multiple times during a single
1850  * transfer.
1851  */
1852 CURLcode Curl_preconnect(struct Curl_easy *data)
1853 {
1854   if(!data->state.buffer) {
1855     data->state.buffer = malloc(data->set.buffer_size + 1);
1856     if(!data->state.buffer)
1857       return CURLE_OUT_OF_MEMORY;
1858   }
1859 
1860   return CURLE_OK;
1861 }
1862 
1863 static void set_in_callback(struct Curl_multi *multi, bool value)
1864 {
1865   multi->in_callback = value;
1866 }
1867 
1868 static CURLMcode multi_runsingle(struct Curl_multi *multi,
1869                                  struct curltime *nowp,
1870                                  struct Curl_easy *data)
1871 {
1872   struct Curl_message *msg = NULL;
1873   bool connected;
1874   bool async;
1875   bool protocol_connected = FALSE;
1876   bool dophase_done = FALSE;
1877   bool done = FALSE;
1878   CURLMcode rc;
1879   CURLcode result = CURLE_OK;
1880   timediff_t recv_timeout_ms;
1881   timediff_t send_timeout_ms;
1882   int control;
1883 
1884   if(!GOOD_EASY_HANDLE(data))
1885     return CURLM_BAD_EASY_HANDLE;
1886 
1887   if(multi->dead) {
1888     /* a multi-level callback returned error before, meaning every individual
1889      transfer now has failed */
1890     result = CURLE_ABORTED_BY_CALLBACK;
1891     Curl_posttransfer(data);
1892     multi_done(data, result, FALSE);
1893     multistate(data, MSTATE_COMPLETED);
1894   }
1895 
1896   multi_warn_debug(multi, data);
1897 
1898   do {
1899     /* A "stream" here is a logical stream if the protocol can handle that
1900        (HTTP/2), or the full connection for older protocols */
1901     bool stream_error = FALSE;
1902     rc = CURLM_OK;
1903 
1904     if(multi_ischanged(multi, TRUE)) {
1905       DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
1906       process_pending_handles(multi); /* multiplexed */
1907     }
1908 
1909     if(data->mstate > MSTATE_CONNECT &&
1910        data->mstate < MSTATE_COMPLETED) {
1911       /* Make sure we set the connection's current owner */
1912       DEBUGASSERT(data->conn);
1913       if(!data->conn)
1914         return CURLM_INTERNAL_ERROR;
1915     }
1916 
1917     if(data->conn &&
1918        (data->mstate >= MSTATE_CONNECT) &&
1919        (data->mstate < MSTATE_COMPLETED)) {
1920       /* Check for overall operation timeout here but defer handling the
1921        * connection timeout to later, to allow for a connection to be set up
1922        * in the window since we last checked timeout. This prevents us
1923        * tearing down a completed connection in the case where we were slow
1924        * to check the timeout (e.g. process descheduled during this loop).
1925        * We set connect_timeout=FALSE to do this. */
1926 
1927       /* we need to wait for the connect state as only then is the start time
1928          stored, but we must not check already completed handles */
1929       if(multi_handle_timeout(data, nowp, &stream_error, &result, FALSE)) {
1930         /* Skip the statemachine and go directly to error handling section. */
1931         goto statemachine_end;
1932       }
1933     }
1934 
1935     switch(data->mstate) {
1936     case MSTATE_INIT:
1937       /* init this transfer. */
1938       result = Curl_pretransfer(data);
1939 
1940       if(!result) {
1941         /* after init, go CONNECT */
1942         multistate(data, MSTATE_CONNECT);
1943         *nowp = Curl_pgrsTime(data, TIMER_STARTOP);
1944         rc = CURLM_CALL_MULTI_PERFORM;
1945       }
1946       break;
1947 
1948     case MSTATE_CONNECT:
1949       /* Connect. We want to get a connection identifier filled in. */
1950       /* init this transfer. */
1951       result = Curl_preconnect(data);
1952       if(result)
1953         break;
1954 
1955       *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
1956       if(data->set.timeout)
1957         Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
1958 
1959       if(data->set.connecttimeout)
1960         Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
1961 
1962       result = Curl_connect(data, &async, &connected);
1963       if(CURLE_NO_CONNECTION_AVAILABLE == result) {
1964         /* There was no connection available. We will go to the pending
1965            state and wait for an available connection. */
1966         multistate(data, MSTATE_PENDING);
1967 
1968         /* add this handle to the list of connect-pending handles */
1969         Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
1970                                &data->connect_queue);
1971         /* unlink from the main list */
1972         unlink_easy(multi, data);
1973         result = CURLE_OK;
1974         break;
1975       }
1976       else if(data->state.previouslypending) {
1977         /* this transfer comes from the pending queue so try move another */
1978         infof(data, "Transfer was pending, now try another");
1979         process_pending_handles(data->multi);
1980       }
1981 
1982       if(!result) {
1983         if(async)
1984           /* We're now waiting for an asynchronous name lookup */
1985           multistate(data, MSTATE_RESOLVING);
1986         else {
1987           /* after the connect has been sent off, go WAITCONNECT unless the
1988              protocol connect is already done and we can go directly to
1989              WAITDO or DO! */
1990           rc = CURLM_CALL_MULTI_PERFORM;
1991 
1992           if(connected)
1993             multistate(data, MSTATE_PROTOCONNECT);
1994           else {
1995             multistate(data, MSTATE_CONNECTING);
1996           }
1997         }
1998       }
1999       break;
2000 
2001     case MSTATE_RESOLVING:
2002       /* awaiting an asynch name resolve to complete */
2003     {
2004       struct Curl_dns_entry *dns = NULL;
2005       struct connectdata *conn = data->conn;
2006       const char *hostname;
2007 
2008       DEBUGASSERT(conn);
2009 #ifndef CURL_DISABLE_PROXY
2010       if(conn->bits.httpproxy)
2011         hostname = conn->http_proxy.host.name;
2012       else
2013 #endif
2014         if(conn->bits.conn_to_host)
2015           hostname = conn->conn_to_host.name;
2016       else
2017         hostname = conn->host.name;
2018 
2019       /* check if we have the name resolved by now */
2020       dns = Curl_fetch_addr(data, hostname, (int)conn->port);
2021 
2022       if(dns) {
2023 #ifdef CURLRES_ASYNCH
2024         data->state.async.dns = dns;
2025         data->state.async.done = TRUE;
2026 #endif
2027         result = CURLE_OK;
2028         infof(data, "Hostname '%s' was found in DNS cache", hostname);
2029       }
2030 
2031       if(!dns)
2032         result = Curl_resolv_check(data, &dns);
2033 
2034       /* Update sockets here, because the socket(s) may have been
2035          closed and the application thus needs to be told, even if it
2036          is likely that the same socket(s) will again be used further
2037          down.  If the name has not yet been resolved, it is likely
2038          that new sockets have been opened in an attempt to contact
2039          another resolver. */
2040       rc = singlesocket(multi, data);
2041       if(rc)
2042         return rc;
2043 
2044       if(dns) {
2045         /* Perform the next step in the connection phase, and then move on
2046            to the WAITCONNECT state */
2047         result = Curl_once_resolved(data, &connected);
2048 
2049         if(result)
2050           /* if Curl_once_resolved() returns failure, the connection struct
2051              is already freed and gone */
2052           data->conn = NULL; /* no more connection */
2053         else {
2054           /* call again please so that we get the next socket setup */
2055           rc = CURLM_CALL_MULTI_PERFORM;
2056           if(connected)
2057             multistate(data, MSTATE_PROTOCONNECT);
2058           else {
2059             multistate(data, MSTATE_CONNECTING);
2060           }
2061         }
2062       }
2063 
2064       if(result) {
2065         /* failure detected */
2066         stream_error = TRUE;
2067         break;
2068       }
2069     }
2070     break;
2071 
2072 #ifndef CURL_DISABLE_HTTP
2073     case MSTATE_TUNNELING:
2074       /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
2075       DEBUGASSERT(data->conn);
2076       result = Curl_http_connect(data, &protocol_connected);
2077 #ifndef CURL_DISABLE_PROXY
2078       if(data->conn->bits.proxy_connect_closed) {
2079         rc = CURLM_CALL_MULTI_PERFORM;
2080         /* connect back to proxy again */
2081         result = CURLE_OK;
2082         multi_done(data, CURLE_OK, FALSE);
2083         multistate(data, MSTATE_CONNECT);
2084       }
2085       else
2086 #endif
2087         if(!result) {
2088           rc = CURLM_CALL_MULTI_PERFORM;
2089           /* initiate protocol connect phase */
2090           multistate(data, MSTATE_PROTOCONNECT);
2091         }
2092       else
2093         stream_error = TRUE;
2094       break;
2095 #endif
2096 
2097     case MSTATE_CONNECTING:
2098       /* awaiting a completion of an asynch TCP connect */
2099       DEBUGASSERT(data->conn);
2100       result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
2101       if(connected && !result) {
2102         rc = CURLM_CALL_MULTI_PERFORM;
2103         multistate(data, MSTATE_PROTOCONNECT);
2104       }
2105       else if(result) {
2106         /* failure detected */
2107         Curl_posttransfer(data);
2108         multi_done(data, result, TRUE);
2109         stream_error = TRUE;
2110         break;
2111       }
2112       break;
2113 
2114     case MSTATE_PROTOCONNECT:
2115       if(data->state.rewindbeforesend)
2116         result = readrewind(data);
2117 
2118       if(!result && data->conn->bits.reuse) {
2119         /* ftp seems to hang when protoconnect on reused connection
2120          * since we handle PROTOCONNECT in general inside the filers, it
2121          * seems wrong to restart this on a reused connection. */
2122         multistate(data, MSTATE_DO);
2123         rc = CURLM_CALL_MULTI_PERFORM;
2124         break;
2125       }
2126       if(!result)
2127         result = protocol_connect(data, &protocol_connected);
2128       if(!result && !protocol_connected) {
2129         /* switch to waiting state */
2130         multistate(data, MSTATE_PROTOCONNECTING);
2131         rc = CURLM_CALL_MULTI_PERFORM;
2132       }
2133       else if(!result) {
2134         /* protocol connect has completed, go WAITDO or DO */
2135         multistate(data, MSTATE_DO);
2136         rc = CURLM_CALL_MULTI_PERFORM;
2137       }
2138       else {
2139         /* failure detected */
2140         Curl_posttransfer(data);
2141         multi_done(data, result, TRUE);
2142         stream_error = TRUE;
2143       }
2144       break;
2145 
2146     case MSTATE_PROTOCONNECTING:
2147       /* protocol-specific connect phase */
2148       result = protocol_connecting(data, &protocol_connected);
2149       if(!result && protocol_connected) {
2150         /* after the connect has completed, go WAITDO or DO */
2151         multistate(data, MSTATE_DO);
2152         rc = CURLM_CALL_MULTI_PERFORM;
2153       }
2154       else if(result) {
2155         /* failure detected */
2156         Curl_posttransfer(data);
2157         multi_done(data, result, TRUE);
2158         stream_error = TRUE;
2159       }
2160       break;
2161 
2162     case MSTATE_DO:
2163       if(data->set.fprereq) {
2164         int prereq_rc;
2165 
2166         /* call the prerequest callback function */
2167         Curl_set_in_callback(data, true);
2168         prereq_rc = data->set.fprereq(data->set.prereq_userp,
2169                                       data->info.conn_primary_ip,
2170                                       data->info.conn_local_ip,
2171                                       data->info.conn_primary_port,
2172                                       data->info.conn_local_port);
2173         Curl_set_in_callback(data, false);
2174         if(prereq_rc != CURL_PREREQFUNC_OK) {
2175           failf(data, "operation aborted by pre-request callback");
2176           /* failure in pre-request callback - don't do any other processing */
2177           result = CURLE_ABORTED_BY_CALLBACK;
2178           Curl_posttransfer(data);
2179           multi_done(data, result, FALSE);
2180           stream_error = TRUE;
2181           break;
2182         }
2183       }
2184 
2185       if(data->set.connect_only == 1) {
2186         /* keep connection open for application to use the socket */
2187         connkeep(data->conn, "CONNECT_ONLY");
2188         multistate(data, MSTATE_DONE);
2189         result = CURLE_OK;
2190         rc = CURLM_CALL_MULTI_PERFORM;
2191       }
2192       else {
2193         /* Perform the protocol's DO action */
2194         result = multi_do(data, &dophase_done);
2195 
2196         /* When multi_do() returns failure, data->conn might be NULL! */
2197 
2198         if(!result) {
2199           if(!dophase_done) {
2200 #ifndef CURL_DISABLE_FTP
2201             /* some steps needed for wildcard matching */
2202             if(data->state.wildcardmatch) {
2203               struct WildcardData *wc = data->wildcard;
2204               if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
2205                 /* skip some states if it is important */
2206                 multi_done(data, CURLE_OK, FALSE);
2207 
2208                 /* if there's no connection left, skip the DONE state */
2209                 multistate(data, data->conn ?
2210                            MSTATE_DONE : MSTATE_COMPLETED);
2211                 rc = CURLM_CALL_MULTI_PERFORM;
2212                 break;
2213               }
2214             }
2215 #endif
2216             /* DO was not completed in one function call, we must continue
2217                DOING... */
2218             multistate(data, MSTATE_DOING);
2219             rc = CURLM_CALL_MULTI_PERFORM;
2220           }
2221 
2222           /* after DO, go DO_DONE... or DO_MORE */
2223           else if(data->conn->bits.do_more) {
2224             /* we're supposed to do more, but we need to sit down, relax
2225                and wait a little while first */
2226             multistate(data, MSTATE_DOING_MORE);
2227             rc = CURLM_CALL_MULTI_PERFORM;
2228           }
2229           else {
2230             /* we're done with the DO, now DID */
2231             multistate(data, MSTATE_DID);
2232             rc = CURLM_CALL_MULTI_PERFORM;
2233           }
2234         }
2235         else if((CURLE_SEND_ERROR == result) &&
2236                 data->conn->bits.reuse) {
2237           /*
2238            * In this situation, a connection that we were trying to use
2239            * may have unexpectedly died.  If possible, send the connection
2240            * back to the CONNECT phase so we can try again.
2241            */
2242           char *newurl = NULL;
2243           followtype follow = FOLLOW_NONE;
2244           CURLcode drc;
2245 
2246           drc = Curl_retry_request(data, &newurl);
2247           if(drc) {
2248             /* a failure here pretty much implies an out of memory */
2249             result = drc;
2250             stream_error = TRUE;
2251           }
2252 
2253           Curl_posttransfer(data);
2254           drc = multi_done(data, result, FALSE);
2255 
2256           /* When set to retry the connection, we must go back to the CONNECT
2257            * state */
2258           if(newurl) {
2259             if(!drc || (drc == CURLE_SEND_ERROR)) {
2260               follow = FOLLOW_RETRY;
2261               drc = Curl_follow(data, newurl, follow);
2262               if(!drc) {
2263                 multistate(data, MSTATE_CONNECT);
2264                 rc = CURLM_CALL_MULTI_PERFORM;
2265                 result = CURLE_OK;
2266               }
2267               else {
2268                 /* Follow failed */
2269                 result = drc;
2270               }
2271             }
2272             else {
2273               /* done didn't return OK or SEND_ERROR */
2274               result = drc;
2275             }
2276           }
2277           else {
2278             /* Have error handler disconnect conn if we can't retry */
2279             stream_error = TRUE;
2280           }
2281           free(newurl);
2282         }
2283         else {
2284           /* failure detected */
2285           Curl_posttransfer(data);
2286           if(data->conn)
2287             multi_done(data, result, FALSE);
2288           stream_error = TRUE;
2289         }
2290       }
2291       break;
2292 
2293     case MSTATE_DOING:
2294       /* we continue DOING until the DO phase is complete */
2295       DEBUGASSERT(data->conn);
2296       result = protocol_doing(data, &dophase_done);
2297       if(!result) {
2298         if(dophase_done) {
2299           /* after DO, go DO_DONE or DO_MORE */
2300           multistate(data, data->conn->bits.do_more?
2301                      MSTATE_DOING_MORE : MSTATE_DID);
2302           rc = CURLM_CALL_MULTI_PERFORM;
2303         } /* dophase_done */
2304       }
2305       else {
2306         /* failure detected */
2307         Curl_posttransfer(data);
2308         multi_done(data, result, FALSE);
2309         stream_error = TRUE;
2310       }
2311       break;
2312 
2313     case MSTATE_DOING_MORE:
2314       /*
2315        * When we are connected, DOING MORE and then go DID
2316        */
2317       DEBUGASSERT(data->conn);
2318       result = multi_do_more(data, &control);
2319 
2320       if(!result) {
2321         if(control) {
2322           /* if positive, advance to DO_DONE
2323              if negative, go back to DOING */
2324           multistate(data, control == 1?
2325                      MSTATE_DID : MSTATE_DOING);
2326           rc = CURLM_CALL_MULTI_PERFORM;
2327         }
2328         /* else
2329            stay in DO_MORE */
2330       }
2331       else {
2332         /* failure detected */
2333         Curl_posttransfer(data);
2334         multi_done(data, result, FALSE);
2335         stream_error = TRUE;
2336       }
2337       break;
2338 
2339     case MSTATE_DID:
2340       DEBUGASSERT(data->conn);
2341       if(data->conn->bits.multiplex)
2342         /* Check if we can move pending requests to send pipe */
2343         process_pending_handles(multi); /*  multiplexed */
2344 
2345       /* Only perform the transfer if there's a good socket to work with.
2346          Having both BAD is a signal to skip immediately to DONE */
2347       if((data->conn->sockfd != CURL_SOCKET_BAD) ||
2348          (data->conn->writesockfd != CURL_SOCKET_BAD))
2349         multistate(data, MSTATE_PERFORMING);
2350       else {
2351 #ifndef CURL_DISABLE_FTP
2352         if(data->state.wildcardmatch &&
2353            ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
2354           data->wildcard->state = CURLWC_DONE;
2355         }
2356 #endif
2357         multistate(data, MSTATE_DONE);
2358       }
2359       rc = CURLM_CALL_MULTI_PERFORM;
2360       break;
2361 
2362     case MSTATE_RATELIMITING: /* limit-rate exceeded in either direction */
2363       DEBUGASSERT(data->conn);
2364       /* if both rates are within spec, resume transfer */
2365       if(Curl_pgrsUpdate(data))
2366         result = CURLE_ABORTED_BY_CALLBACK;
2367       else
2368         result = Curl_speedcheck(data, *nowp);
2369 
2370       if(result) {
2371         if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2372            result != CURLE_HTTP2_STREAM)
2373           streamclose(data->conn, "Transfer returned error");
2374 
2375         Curl_posttransfer(data);
2376         multi_done(data, result, TRUE);
2377       }
2378       else {
2379         send_timeout_ms = 0;
2380         if(data->set.max_send_speed)
2381           send_timeout_ms =
2382             Curl_pgrsLimitWaitTime(data->progress.uploaded,
2383                                    data->progress.ul_limit_size,
2384                                    data->set.max_send_speed,
2385                                    data->progress.ul_limit_start,
2386                                    *nowp);
2387 
2388         recv_timeout_ms = 0;
2389         if(data->set.max_recv_speed)
2390           recv_timeout_ms =
2391             Curl_pgrsLimitWaitTime(data->progress.downloaded,
2392                                    data->progress.dl_limit_size,
2393                                    data->set.max_recv_speed,
2394                                    data->progress.dl_limit_start,
2395                                    *nowp);
2396 
2397         if(!send_timeout_ms && !recv_timeout_ms) {
2398           multistate(data, MSTATE_PERFORMING);
2399           Curl_ratelimit(data, *nowp);
2400         }
2401         else if(send_timeout_ms >= recv_timeout_ms)
2402           Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2403         else
2404           Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2405       }
2406       break;
2407 
2408     case MSTATE_PERFORMING:
2409     {
2410       char *newurl = NULL;
2411       bool retry = FALSE;
2412       bool comeback = FALSE;
2413       DEBUGASSERT(data->state.buffer);
2414       /* check if over send speed */
2415       send_timeout_ms = 0;
2416       if(data->set.max_send_speed)
2417         send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
2418                                                  data->progress.ul_limit_size,
2419                                                  data->set.max_send_speed,
2420                                                  data->progress.ul_limit_start,
2421                                                  *nowp);
2422 
2423       /* check if over recv speed */
2424       recv_timeout_ms = 0;
2425       if(data->set.max_recv_speed)
2426         recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
2427                                                  data->progress.dl_limit_size,
2428                                                  data->set.max_recv_speed,
2429                                                  data->progress.dl_limit_start,
2430                                                  *nowp);
2431 
2432       if(send_timeout_ms || recv_timeout_ms) {
2433         Curl_ratelimit(data, *nowp);
2434         multistate(data, MSTATE_RATELIMITING);
2435         if(send_timeout_ms >= recv_timeout_ms)
2436           Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2437         else
2438           Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2439         break;
2440       }
2441 
2442       /* read/write data if it is ready to do so */
2443       result = Curl_readwrite(data->conn, data, &done, &comeback);
2444 
2445       if(done || (result == CURLE_RECV_ERROR)) {
2446         /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
2447          * condition and the server closed the reused connection exactly when
2448          * we wanted to use it, so figure out if that is indeed the case.
2449          */
2450         CURLcode ret = Curl_retry_request(data, &newurl);
2451         if(!ret)
2452           retry = (newurl)?TRUE:FALSE;
2453         else if(!result)
2454           result = ret;
2455 
2456         if(retry) {
2457           /* if we are to retry, set the result to OK and consider the
2458              request as done */
2459           result = CURLE_OK;
2460           done = TRUE;
2461         }
2462       }
2463       else if((CURLE_HTTP2_STREAM == result) &&
2464               Curl_h2_http_1_1_error(data)) {
2465         CURLcode ret = Curl_retry_request(data, &newurl);
2466 
2467         if(!ret) {
2468           infof(data, "Downgrades to HTTP/1.1");
2469           streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
2470           data->state.httpwant = CURL_HTTP_VERSION_1_1;
2471           /* clear the error message bit too as we ignore the one we got */
2472           data->state.errorbuf = FALSE;
2473           if(!newurl)
2474             /* typically for HTTP_1_1_REQUIRED error on first flight */
2475             newurl = strdup(data->state.url);
2476           /* if we are to retry, set the result to OK and consider the request
2477              as done */
2478           retry = TRUE;
2479           result = CURLE_OK;
2480           done = TRUE;
2481         }
2482         else
2483           result = ret;
2484       }
2485 
2486       if(result) {
2487         /*
2488          * The transfer phase returned error, we mark the connection to get
2489          * closed to prevent being reused. This is because we can't possibly
2490          * know if the connection is in a good shape or not now.  Unless it is
2491          * a protocol which uses two "channels" like FTP, as then the error
2492          * happened in the data connection.
2493          */
2494 
2495         if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2496            result != CURLE_HTTP2_STREAM)
2497           streamclose(data->conn, "Transfer returned error");
2498 
2499         Curl_posttransfer(data);
2500         multi_done(data, result, TRUE);
2501       }
2502       else if(done) {
2503 
2504         /* call this even if the readwrite function returned error */
2505         Curl_posttransfer(data);
2506 
2507         /* When we follow redirects or is set to retry the connection, we must
2508            to go back to the CONNECT state */
2509         if(data->req.newurl || retry) {
2510           followtype follow = FOLLOW_NONE;
2511           if(!retry) {
2512             /* if the URL is a follow-location and not just a retried request
2513                then figure out the URL here */
2514             free(newurl);
2515             newurl = data->req.newurl;
2516             data->req.newurl = NULL;
2517             follow = FOLLOW_REDIR;
2518           }
2519           else
2520             follow = FOLLOW_RETRY;
2521           (void)multi_done(data, CURLE_OK, FALSE);
2522           /* multi_done() might return CURLE_GOT_NOTHING */
2523           result = Curl_follow(data, newurl, follow);
2524           if(!result) {
2525             multistate(data, MSTATE_CONNECT);
2526             rc = CURLM_CALL_MULTI_PERFORM;
2527           }
2528           free(newurl);
2529         }
2530         else {
2531           /* after the transfer is done, go DONE */
2532 
2533           /* but first check to see if we got a location info even though we're
2534              not following redirects */
2535           if(data->req.location) {
2536             free(newurl);
2537             newurl = data->req.location;
2538             data->req.location = NULL;
2539             result = Curl_follow(data, newurl, FOLLOW_FAKE);
2540             free(newurl);
2541             if(result) {
2542               stream_error = TRUE;
2543               result = multi_done(data, result, TRUE);
2544             }
2545           }
2546 
2547           if(!result) {
2548             multistate(data, MSTATE_DONE);
2549             rc = CURLM_CALL_MULTI_PERFORM;
2550           }
2551         }
2552       }
2553       else if(comeback) {
2554         /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer
2555            won't get stuck on this transfer at the expense of other concurrent
2556            transfers */
2557         Curl_expire(data, 0, EXPIRE_RUN_NOW);
2558       }
2559       break;
2560     }
2561 
2562     case MSTATE_DONE:
2563       /* this state is highly transient, so run another loop after this */
2564       rc = CURLM_CALL_MULTI_PERFORM;
2565 
2566       if(data->conn) {
2567         CURLcode res;
2568 
2569         if(data->conn->bits.multiplex)
2570           /* Check if we can move pending requests to connection */
2571           process_pending_handles(multi); /* multiplexing */
2572 
2573         /* post-transfer command */
2574         res = multi_done(data, result, FALSE);
2575 
2576         /* allow a previously set error code take precedence */
2577         if(!result)
2578           result = res;
2579       }
2580 
2581 #ifndef CURL_DISABLE_FTP
2582       if(data->state.wildcardmatch) {
2583         if(data->wildcard->state != CURLWC_DONE) {
2584           /* if a wildcard is set and we are not ending -> lets start again
2585              with MSTATE_INIT */
2586           multistate(data, MSTATE_INIT);
2587           break;
2588         }
2589       }
2590 #endif
2591       /* after we have DONE what we're supposed to do, go COMPLETED, and
2592          it doesn't matter what the multi_done() returned! */
2593       multistate(data, MSTATE_COMPLETED);
2594       break;
2595 
2596     case MSTATE_COMPLETED:
2597       break;
2598 
2599     case MSTATE_PENDING:
2600     case MSTATE_MSGSENT:
2601       /* handles in these states should NOT be in this list */
2602       DEBUGASSERT(0);
2603       break;
2604 
2605     default:
2606       return CURLM_INTERNAL_ERROR;
2607     }
2608 
2609     if(data->conn &&
2610        data->mstate >= MSTATE_CONNECT &&
2611        data->mstate < MSTATE_DO &&
2612        rc != CURLM_CALL_MULTI_PERFORM &&
2613        !multi_ischanged(multi, false)) {
2614       /* We now handle stream timeouts if and only if this will be the last
2615        * loop iteration. We only check this on the last iteration to ensure
2616        * that if we know we have additional work to do immediately
2617        * (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before
2618        * declaring the connection timed out as we may almost have a completed
2619        * connection. */
2620       multi_handle_timeout(data, nowp, &stream_error, &result, TRUE);
2621     }
2622 
2623 statemachine_end:
2624 
2625     if(data->mstate < MSTATE_COMPLETED) {
2626       if(result) {
2627         /*
2628          * If an error was returned, and we aren't in completed state now,
2629          * then we go to completed and consider this transfer aborted.
2630          */
2631 
2632         /* NOTE: no attempt to disconnect connections must be made
2633            in the case blocks above - cleanup happens only here */
2634 
2635         /* Check if we can move pending requests to send pipe */
2636         process_pending_handles(multi); /* connection */
2637 
2638         if(data->conn) {
2639           if(stream_error) {
2640             /* Don't attempt to send data over a connection that timed out */
2641             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2642             struct connectdata *conn = data->conn;
2643 
2644             /* This is where we make sure that the conn pointer is reset.
2645                We don't have to do this in every case block above where a
2646                failure is detected */
2647             Curl_detach_connection(data);
2648 
2649             /* remove connection from cache */
2650             Curl_conncache_remove_conn(data, conn, TRUE);
2651 
2652             /* disconnect properly */
2653             Curl_disconnect(data, conn, dead_connection);
2654           }
2655         }
2656         else if(data->mstate == MSTATE_CONNECT) {
2657           /* Curl_connect() failed */
2658           (void)Curl_posttransfer(data);
2659         }
2660 
2661         multistate(data, MSTATE_COMPLETED);
2662         rc = CURLM_CALL_MULTI_PERFORM;
2663       }
2664       /* if there's still a connection to use, call the progress function */
2665       else if(data->conn && Curl_pgrsUpdate(data)) {
2666         /* aborted due to progress callback return code must close the
2667            connection */
2668         result = CURLE_ABORTED_BY_CALLBACK;
2669         streamclose(data->conn, "Aborted by callback");
2670 
2671         /* if not yet in DONE state, go there, otherwise COMPLETED */
2672         multistate(data, (data->mstate < MSTATE_DONE)?
2673                    MSTATE_DONE: MSTATE_COMPLETED);
2674         rc = CURLM_CALL_MULTI_PERFORM;
2675       }
2676     }
2677 
2678     if(MSTATE_COMPLETED == data->mstate) {
2679       if(data->set.fmultidone) {
2680         /* signal via callback instead */
2681         data->set.fmultidone(data, result);
2682       }
2683       else {
2684         /* now fill in the Curl_message with this info */
2685         msg = &data->msg;
2686 
2687         msg->extmsg.msg = CURLMSG_DONE;
2688         msg->extmsg.easy_handle = data;
2689         msg->extmsg.data.result = result;
2690 
2691         multi_addmsg(multi, msg);
2692         DEBUGASSERT(!data->conn);
2693       }
2694       multistate(data, MSTATE_MSGSENT);
2695 
2696       /* add this handle to the list of msgsent handles */
2697       Curl_llist_insert_next(&multi->msgsent, multi->msgsent.tail, data,
2698                              &data->connect_queue);
2699       /* unlink from the main list */
2700       unlink_easy(multi, data);
2701       return CURLM_OK;
2702     }
2703   } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2704 
2705   data->result = result;
2706   return rc;
2707 }
2708 
2709 
2710 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
2711 {
2712   struct Curl_easy *data;
2713   CURLMcode returncode = CURLM_OK;
2714   struct Curl_tree *t;
2715   struct curltime now = Curl_now();
2716 
2717   if(!GOOD_MULTI_HANDLE(multi))
2718     return CURLM_BAD_HANDLE;
2719 
2720   if(multi->in_callback)
2721     return CURLM_RECURSIVE_API_CALL;
2722 
2723   data = multi->easyp;
2724   if(data) {
2725     CURLMcode result;
2726     bool nosig = data->set.no_signal;
2727     SIGPIPE_VARIABLE(pipe_st);
2728     sigpipe_ignore(data, &pipe_st);
2729     /* Do the loop and only alter the signal ignore state if the next handle
2730        has a different NO_SIGNAL state than the previous */
2731     do {
2732       /* the current node might be unlinked in multi_runsingle(), get the next
2733          pointer now */
2734       struct Curl_easy *datanext = data->next;
2735       if(data->set.no_signal != nosig) {
2736         sigpipe_restore(&pipe_st);
2737         sigpipe_ignore(data, &pipe_st);
2738         nosig = data->set.no_signal;
2739       }
2740       result = multi_runsingle(multi, &now, data);
2741       if(result)
2742         returncode = result;
2743       data = datanext; /* operate on next handle */
2744     } while(data);
2745     sigpipe_restore(&pipe_st);
2746   }
2747 
2748   /*
2749    * Simply remove all expired timers from the splay since handles are dealt
2750    * with unconditionally by this function and curl_multi_timeout() requires
2751    * that already passed/handled expire times are removed from the splay.
2752    *
2753    * It is important that the 'now' value is set at the entry of this function
2754    * and not for the current time as it may have ticked a little while since
2755    * then and then we risk this loop to remove timers that actually have not
2756    * been handled!
2757    */
2758   do {
2759     multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2760     if(t)
2761       /* the removed may have another timeout in queue */
2762       (void)add_next_timeout(now, multi, t->payload);
2763 
2764   } while(t);
2765 
2766   *running_handles = multi->num_alive;
2767 
2768   if(CURLM_OK >= returncode)
2769     returncode = Curl_update_timer(multi);
2770 
2771   return returncode;
2772 }
2773 
2774 /* unlink_all_msgsent_handles() detaches all those easy handles from this
2775    multi handle */
2776 static void unlink_all_msgsent_handles(struct Curl_multi *multi)
2777 {
2778   struct Curl_llist_element *e = multi->msgsent.head;
2779   if(e) {
2780     struct Curl_easy *data = e->ptr;
2781     DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
2782     data->multi = NULL;
2783   }
2784 }
2785 
2786 CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
2787 {
2788   struct Curl_easy *data;
2789   struct Curl_easy *nextdata;
2790 
2791   if(GOOD_MULTI_HANDLE(multi)) {
2792     if(multi->in_callback)
2793       return CURLM_RECURSIVE_API_CALL;
2794 
2795     multi->magic = 0; /* not good anymore */
2796 
2797     unlink_all_msgsent_handles(multi);
2798     process_pending_handles(multi);
2799     /* First remove all remaining easy handles */
2800     data = multi->easyp;
2801     while(data) {
2802       nextdata = data->next;
2803       if(!data->state.done && data->conn)
2804         /* if DONE was never called for this handle */
2805         (void)multi_done(data, CURLE_OK, TRUE);
2806       if(data->dns.hostcachetype == HCACHE_MULTI) {
2807         /* clear out the usage of the shared DNS cache */
2808         Curl_hostcache_clean(data, data->dns.hostcache);
2809         data->dns.hostcache = NULL;
2810         data->dns.hostcachetype = HCACHE_NONE;
2811       }
2812 
2813       /* Clear the pointer to the connection cache */
2814       data->state.conn_cache = NULL;
2815       data->multi = NULL; /* clear the association */
2816 
2817 #ifdef USE_LIBPSL
2818       if(data->psl == &multi->psl)
2819         data->psl = NULL;
2820 #endif
2821 
2822       data = nextdata;
2823     }
2824 
2825     /* Close all the connections in the connection cache */
2826     Curl_conncache_close_all_connections(&multi->conn_cache);
2827 
2828     sockhash_destroy(&multi->sockhash);
2829     Curl_conncache_destroy(&multi->conn_cache);
2830     Curl_hash_destroy(&multi->hostcache);
2831     Curl_psl_destroy(&multi->psl);
2832 
2833 #ifdef USE_WINSOCK
2834     WSACloseEvent(multi->wsa_event);
2835 #else
2836 #ifdef ENABLE_WAKEUP
2837     wakeup_close(multi->wakeup_pair[0]);
2838     wakeup_close(multi->wakeup_pair[1]);
2839 #endif
2840 #endif
2841 
2842 #ifdef USE_SSL
2843     Curl_free_multi_ssl_backend_data(multi->ssl_backend_data);
2844 #endif
2845 
2846     free(multi);
2847 
2848     return CURLM_OK;
2849   }
2850   return CURLM_BAD_HANDLE;
2851 }
2852 
2853 /*
2854  * curl_multi_info_read()
2855  *
2856  * This function is the primary way for a multi/multi_socket application to
2857  * figure out if a transfer has ended. We MUST make this function as fast as
2858  * possible as it will be polled frequently and we MUST NOT scan any lists in
2859  * here to figure out things. We must scale fine to thousands of handles and
2860  * beyond. The current design is fully O(1).
2861  */
2862 
2863 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
2864 {
2865   struct Curl_message *msg;
2866 
2867   *msgs_in_queue = 0; /* default to none */
2868 
2869   if(GOOD_MULTI_HANDLE(multi) &&
2870      !multi->in_callback &&
2871      Curl_llist_count(&multi->msglist)) {
2872     /* there is one or more messages in the list */
2873     struct Curl_llist_element *e;
2874 
2875     /* extract the head of the list to return */
2876     e = multi->msglist.head;
2877 
2878     msg = e->ptr;
2879 
2880     /* remove the extracted entry */
2881     Curl_llist_remove(&multi->msglist, e, NULL);
2882 
2883     *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
2884 
2885     return &msg->extmsg;
2886   }
2887   return NULL;
2888 }
2889 
2890 /*
2891  * singlesocket() checks what sockets we deal with and their "action state"
2892  * and if we have a different state in any of those sockets from last time we
2893  * call the callback accordingly.
2894  */
2895 static CURLMcode singlesocket(struct Curl_multi *multi,
2896                               struct Curl_easy *data)
2897 {
2898   curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
2899   int i;
2900   struct Curl_sh_entry *entry;
2901   curl_socket_t s;
2902   int num;
2903   unsigned int curraction;
2904   unsigned char actions[MAX_SOCKSPEREASYHANDLE];
2905   int rc;
2906 
2907   for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
2908     socks[i] = CURL_SOCKET_BAD;
2909 
2910   /* Fill in the 'current' struct with the state as it is now: what sockets to
2911      supervise and for what actions */
2912   curraction = multi_getsock(data, socks);
2913 
2914   /* We have 0 .. N sockets already and we get to know about the 0 .. M
2915      sockets we should have from now on. Detect the differences, remove no
2916      longer supervised ones and add new ones */
2917 
2918   /* walk over the sockets we got right now */
2919   for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) &&
2920       (curraction & GETSOCK_MASK_RW(i));
2921       i++) {
2922     unsigned char action = CURL_POLL_NONE;
2923     unsigned char prevaction = 0;
2924     int comboaction;
2925     bool sincebefore = FALSE;
2926 
2927     s = socks[i];
2928 
2929     /* get it from the hash */
2930     entry = sh_getentry(&multi->sockhash, s);
2931 
2932     if(curraction & GETSOCK_READSOCK(i))
2933       action |= CURL_POLL_IN;
2934     if(curraction & GETSOCK_WRITESOCK(i))
2935       action |= CURL_POLL_OUT;
2936 
2937     actions[i] = action;
2938     if(entry) {
2939       /* check if new for this transfer */
2940       int j;
2941       for(j = 0; j< data->numsocks; j++) {
2942         if(s == data->sockets[j]) {
2943           prevaction = data->actions[j];
2944           sincebefore = TRUE;
2945           break;
2946         }
2947       }
2948     }
2949     else {
2950       /* this is a socket we didn't have before, add it to the hash! */
2951       entry = sh_addentry(&multi->sockhash, s);
2952       if(!entry)
2953         /* fatal */
2954         return CURLM_OUT_OF_MEMORY;
2955     }
2956     if(sincebefore && (prevaction != action)) {
2957       /* Socket was used already, but different action now */
2958       if(prevaction & CURL_POLL_IN)
2959         entry->readers--;
2960       if(prevaction & CURL_POLL_OUT)
2961         entry->writers--;
2962       if(action & CURL_POLL_IN)
2963         entry->readers++;
2964       if(action & CURL_POLL_OUT)
2965         entry->writers++;
2966     }
2967     else if(!sincebefore) {
2968       /* a new user */
2969       entry->users++;
2970       if(action & CURL_POLL_IN)
2971         entry->readers++;
2972       if(action & CURL_POLL_OUT)
2973         entry->writers++;
2974 
2975       /* add 'data' to the transfer hash on this socket! */
2976       if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
2977                         sizeof(struct Curl_easy *), data)) {
2978         Curl_hash_destroy(&entry->transfers);
2979         return CURLM_OUT_OF_MEMORY;
2980       }
2981     }
2982 
2983     comboaction = (entry->writers? CURL_POLL_OUT : 0) |
2984                    (entry->readers ? CURL_POLL_IN : 0);
2985 
2986     /* socket existed before and has the same action set as before */
2987     if(sincebefore && ((int)entry->action == comboaction))
2988       /* same, continue */
2989       continue;
2990 
2991     if(multi->socket_cb) {
2992       set_in_callback(multi, TRUE);
2993       rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
2994                             entry->socketp);
2995       set_in_callback(multi, FALSE);
2996       if(rc == -1) {
2997         multi->dead = TRUE;
2998         return CURLM_ABORTED_BY_CALLBACK;
2999       }
3000     }
3001 
3002     entry->action = comboaction; /* store the current action state */
3003   }
3004 
3005   num = i; /* number of sockets */
3006 
3007   /* when we've walked over all the sockets we should have right now, we must
3008      make sure to detect sockets that are removed */
3009   for(i = 0; i< data->numsocks; i++) {
3010     int j;
3011     bool stillused = FALSE;
3012     s = data->sockets[i];
3013     for(j = 0; j < num; j++) {
3014       if(s == socks[j]) {
3015         /* this is still supervised */
3016         stillused = TRUE;
3017         break;
3018       }
3019     }
3020     if(stillused)
3021       continue;
3022 
3023     entry = sh_getentry(&multi->sockhash, s);
3024     /* if this is NULL here, the socket has been closed and notified so
3025        already by Curl_multi_closed() */
3026     if(entry) {
3027       unsigned char oldactions = data->actions[i];
3028       /* this socket has been removed. Decrease user count */
3029       entry->users--;
3030       if(oldactions & CURL_POLL_OUT)
3031         entry->writers--;
3032       if(oldactions & CURL_POLL_IN)
3033         entry->readers--;
3034       if(!entry->users) {
3035         if(multi->socket_cb) {
3036           set_in_callback(multi, TRUE);
3037           rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3038                                 multi->socket_userp, entry->socketp);
3039           set_in_callback(multi, FALSE);
3040           if(rc == -1) {
3041             multi->dead = TRUE;
3042             return CURLM_ABORTED_BY_CALLBACK;
3043           }
3044         }
3045         sh_delentry(entry, &multi->sockhash, s);
3046       }
3047       else {
3048         /* still users, but remove this handle as a user of this socket */
3049         if(Curl_hash_delete(&entry->transfers, (char *)&data,
3050                             sizeof(struct Curl_easy *))) {
3051           DEBUGASSERT(NULL);
3052         }
3053       }
3054     }
3055   } /* for loop over numsocks */
3056 
3057   memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
3058   memcpy(data->actions, actions, num*sizeof(char));
3059   data->numsocks = num;
3060   return CURLM_OK;
3061 }
3062 
3063 CURLcode Curl_updatesocket(struct Curl_easy *data)
3064 {
3065   if(singlesocket(data->multi, data))
3066     return CURLE_ABORTED_BY_CALLBACK;
3067   return CURLE_OK;
3068 }
3069 
3070 
3071 /*
3072  * Curl_multi_closed()
3073  *
3074  * Used by the connect code to tell the multi_socket code that one of the
3075  * sockets we were using is about to be closed.  This function will then
3076  * remove it from the sockethash for this handle to make the multi_socket API
3077  * behave properly, especially for the case when libcurl will create another
3078  * socket again and it gets the same file descriptor number.
3079  */
3080 
3081 void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
3082 {
3083   if(data) {
3084     /* if there's still an easy handle associated with this connection */
3085     struct Curl_multi *multi = data->multi;
3086     if(multi) {
3087       /* this is set if this connection is part of a handle that is added to
3088          a multi handle, and only then this is necessary */
3089       struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3090 
3091       if(entry) {
3092         int rc = 0;
3093         if(multi->socket_cb) {
3094           set_in_callback(multi, TRUE);
3095           rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3096                                 multi->socket_userp, entry->socketp);
3097           set_in_callback(multi, FALSE);
3098         }
3099 
3100         /* now remove it from the socket hash */
3101         sh_delentry(entry, &multi->sockhash, s);
3102         if(rc == -1)
3103           /* This just marks the multi handle as "dead" without returning an
3104              error code primarily because this function is used from many
3105              places where propagating an error back is tricky. */
3106           multi->dead = TRUE;
3107       }
3108     }
3109   }
3110 }
3111 
3112 /*
3113  * add_next_timeout()
3114  *
3115  * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
3116  * when it has just been removed from the splay tree because the timeout has
3117  * expired. This function is then to advance in the list to pick the next
3118  * timeout to use (skip the already expired ones) and add this node back to
3119  * the splay tree again.
3120  *
3121  * The splay tree only has each sessionhandle as a single node and the nearest
3122  * timeout is used to sort it on.
3123  */
3124 static CURLMcode add_next_timeout(struct curltime now,
3125                                   struct Curl_multi *multi,
3126                                   struct Curl_easy *d)
3127 {
3128   struct curltime *tv = &d->state.expiretime;
3129   struct Curl_llist *list = &d->state.timeoutlist;
3130   struct Curl_llist_element *e;
3131   struct time_node *node = NULL;
3132 
3133   /* move over the timeout list for this specific handle and remove all
3134      timeouts that are now passed tense and store the next pending
3135      timeout in *tv */
3136   for(e = list->head; e;) {
3137     struct Curl_llist_element *n = e->next;
3138     timediff_t diff;
3139     node = (struct time_node *)e->ptr;
3140     diff = Curl_timediff_us(node->time, now);
3141     if(diff <= 0)
3142       /* remove outdated entry */
3143       Curl_llist_remove(list, e, NULL);
3144     else
3145       /* the list is sorted so get out on the first mismatch */
3146       break;
3147     e = n;
3148   }
3149   e = list->head;
3150   if(!e) {
3151     /* clear the expire times within the handles that we remove from the
3152        splay tree */
3153     tv->tv_sec = 0;
3154     tv->tv_usec = 0;
3155   }
3156   else {
3157     /* copy the first entry to 'tv' */
3158     memcpy(tv, &node->time, sizeof(*tv));
3159 
3160     /* Insert this node again into the splay.  Keep the timer in the list in
3161        case we need to recompute future timers. */
3162     multi->timetree = Curl_splayinsert(*tv, multi->timetree,
3163                                        &d->state.timenode);
3164   }
3165   return CURLM_OK;
3166 }
3167 
3168 static CURLMcode multi_socket(struct Curl_multi *multi,
3169                               bool checkall,
3170                               curl_socket_t s,
3171                               int ev_bitmask,
3172                               int *running_handles)
3173 {
3174   CURLMcode result = CURLM_OK;
3175   struct Curl_easy *data = NULL;
3176   struct Curl_tree *t;
3177   struct curltime now = Curl_now();
3178   bool first = FALSE;
3179   bool nosig = FALSE;
3180   SIGPIPE_VARIABLE(pipe_st);
3181 
3182   if(checkall) {
3183     /* *perform() deals with running_handles on its own */
3184     result = curl_multi_perform(multi, running_handles);
3185 
3186     /* walk through each easy handle and do the socket state change magic
3187        and callbacks */
3188     if(result != CURLM_BAD_HANDLE) {
3189       data = multi->easyp;
3190       while(data && !result) {
3191         result = singlesocket(multi, data);
3192         data = data->next;
3193       }
3194     }
3195 
3196     /* or should we fall-through and do the timer-based stuff? */
3197     return result;
3198   }
3199   if(s != CURL_SOCKET_TIMEOUT) {
3200     struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3201 
3202     if(!entry)
3203       /* Unmatched socket, we can't act on it but we ignore this fact.  In
3204          real-world tests it has been proved that libevent can in fact give
3205          the application actions even though the socket was just previously
3206          asked to get removed, so thus we better survive stray socket actions
3207          and just move on. */
3208       ;
3209     else {
3210       struct Curl_hash_iterator iter;
3211       struct Curl_hash_element *he;
3212 
3213       /* the socket can be shared by many transfers, iterate */
3214       Curl_hash_start_iterate(&entry->transfers, &iter);
3215       for(he = Curl_hash_next_element(&iter); he;
3216           he = Curl_hash_next_element(&iter)) {
3217         data = (struct Curl_easy *)he->ptr;
3218         DEBUGASSERT(data);
3219         DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
3220 
3221         if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
3222           /* set socket event bitmask if they're not locked */
3223           data->conn->cselect_bits = (unsigned char)ev_bitmask;
3224 
3225         Curl_expire(data, 0, EXPIRE_RUN_NOW);
3226       }
3227 
3228       /* Now we fall-through and do the timer-based stuff, since we don't want
3229          to force the user to have to deal with timeouts as long as at least
3230          one connection in fact has traffic. */
3231 
3232       data = NULL; /* set data to NULL again to avoid calling
3233                       multi_runsingle() in case there's no need to */
3234       now = Curl_now(); /* get a newer time since the multi_runsingle() loop
3235                            may have taken some time */
3236     }
3237   }
3238   else {
3239     /* Asked to run due to time-out. Clear the 'lastcall' variable to force
3240        Curl_update_timer() to trigger a callback to the app again even if the
3241        same timeout is still the one to run after this call. That handles the
3242        case when the application asks libcurl to run the timeout
3243        prematurely. */
3244     memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
3245   }
3246 
3247   /*
3248    * The loop following here will go on as long as there are expire-times left
3249    * to process in the splay and 'data' will be re-assigned for every expired
3250    * handle we deal with.
3251    */
3252   do {
3253     /* the first loop lap 'data' can be NULL */
3254     if(data) {
3255       if(!first) {
3256         first = TRUE;
3257         nosig = data->set.no_signal; /* initial state */
3258         sigpipe_ignore(data, &pipe_st);
3259       }
3260       else if(data->set.no_signal != nosig) {
3261         sigpipe_restore(&pipe_st);
3262         sigpipe_ignore(data, &pipe_st);
3263         nosig = data->set.no_signal; /* remember new state */
3264       }
3265       result = multi_runsingle(multi, &now, data);
3266 
3267       if(CURLM_OK >= result) {
3268         /* get the socket(s) and check if the state has been changed since
3269            last */
3270         result = singlesocket(multi, data);
3271         if(result)
3272           break;
3273       }
3274     }
3275 
3276     /* Check if there's one (more) expired timer to deal with! This function
3277        extracts a matching node if there is one */
3278 
3279     multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3280     if(t) {
3281       data = t->payload; /* assign this for next loop */
3282       (void)add_next_timeout(now, multi, t->payload);
3283     }
3284 
3285   } while(t);
3286   if(first)
3287     sigpipe_restore(&pipe_st);
3288 
3289   *running_handles = multi->num_alive;
3290   return result;
3291 }
3292 
3293 #undef curl_multi_setopt
3294 CURLMcode curl_multi_setopt(struct Curl_multi *multi,
3295                             CURLMoption option, ...)
3296 {
3297   CURLMcode res = CURLM_OK;
3298   va_list param;
3299 
3300   if(!GOOD_MULTI_HANDLE(multi))
3301     return CURLM_BAD_HANDLE;
3302 
3303   if(multi->in_callback)
3304     return CURLM_RECURSIVE_API_CALL;
3305 
3306   va_start(param, option);
3307 
3308   switch(option) {
3309   case CURLMOPT_SOCKETFUNCTION:
3310     multi->socket_cb = va_arg(param, curl_socket_callback);
3311     break;
3312   case CURLMOPT_SOCKETDATA:
3313     multi->socket_userp = va_arg(param, void *);
3314     break;
3315   case CURLMOPT_PUSHFUNCTION:
3316     multi->push_cb = va_arg(param, curl_push_callback);
3317     break;
3318   case CURLMOPT_PUSHDATA:
3319     multi->push_userp = va_arg(param, void *);
3320     break;
3321   case CURLMOPT_PIPELINING:
3322     multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0;
3323     break;
3324   case CURLMOPT_TIMERFUNCTION:
3325     multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3326     break;
3327   case CURLMOPT_TIMERDATA:
3328     multi->timer_userp = va_arg(param, void *);
3329     break;
3330   case CURLMOPT_MAXCONNECTS:
3331     multi->maxconnects = va_arg(param, long);
3332     break;
3333   case CURLMOPT_MAX_HOST_CONNECTIONS:
3334     multi->max_host_connections = va_arg(param, long);
3335     break;
3336   case CURLMOPT_MAX_TOTAL_CONNECTIONS:
3337     multi->max_total_connections = va_arg(param, long);
3338     break;
3339     /* options formerly used for pipelining */
3340   case CURLMOPT_MAX_PIPELINE_LENGTH:
3341     break;
3342   case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
3343     break;
3344   case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
3345     break;
3346   case CURLMOPT_PIPELINING_SITE_BL:
3347     break;
3348   case CURLMOPT_PIPELINING_SERVER_BL:
3349     break;
3350   case CURLMOPT_MAX_CONCURRENT_STREAMS:
3351     {
3352       long streams = va_arg(param, long);
3353       if(streams < 1)
3354         streams = 100;
3355       multi->max_concurrent_streams = curlx_sltoui(streams);
3356     }
3357     break;
3358   default:
3359     res = CURLM_UNKNOWN_OPTION;
3360     break;
3361   }
3362   va_end(param);
3363   return res;
3364 }
3365 
3366 /* we define curl_multi_socket() in the public multi.h header */
3367 #undef curl_multi_socket
3368 
3369 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
3370                             int *running_handles)
3371 {
3372   CURLMcode result;
3373   if(multi->in_callback)
3374     return CURLM_RECURSIVE_API_CALL;
3375   result = multi_socket(multi, FALSE, s, 0, running_handles);
3376   if(CURLM_OK >= result)
3377     result = Curl_update_timer(multi);
3378   return result;
3379 }
3380 
3381 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
3382                                    int ev_bitmask, int *running_handles)
3383 {
3384   CURLMcode result;
3385   if(multi->in_callback)
3386     return CURLM_RECURSIVE_API_CALL;
3387   result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3388   if(CURLM_OK >= result)
3389     result = Curl_update_timer(multi);
3390   return result;
3391 }
3392 
3393 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
3394 {
3395   CURLMcode result;
3396   if(multi->in_callback)
3397     return CURLM_RECURSIVE_API_CALL;
3398   result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3399   if(CURLM_OK >= result)
3400     result = Curl_update_timer(multi);
3401   return result;
3402 }
3403 
3404 static CURLMcode multi_timeout(struct Curl_multi *multi,
3405                                long *timeout_ms)
3406 {
3407   static const struct curltime tv_zero = {0, 0};
3408 
3409   if(multi->dead) {
3410     *timeout_ms = 0;
3411     return CURLM_OK;
3412   }
3413 
3414   if(multi->timetree) {
3415     /* we have a tree of expire times */
3416     struct curltime now = Curl_now();
3417 
3418     /* splay the lowest to the bottom */
3419     multi->timetree = Curl_splay(tv_zero, multi->timetree);
3420 
3421     if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
3422       /* some time left before expiration */
3423       timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now);
3424       /* this should be safe even on 32 bit archs, as we don't use that
3425          overly long timeouts */
3426       *timeout_ms = (long)diff;
3427     }
3428     else
3429       /* 0 means immediately */
3430       *timeout_ms = 0;
3431   }
3432   else
3433     *timeout_ms = -1;
3434 
3435   return CURLM_OK;
3436 }
3437 
3438 CURLMcode curl_multi_timeout(struct Curl_multi *multi,
3439                              long *timeout_ms)
3440 {
3441   /* First, make some basic checks that the CURLM handle is a good handle */
3442   if(!GOOD_MULTI_HANDLE(multi))
3443     return CURLM_BAD_HANDLE;
3444 
3445   if(multi->in_callback)
3446     return CURLM_RECURSIVE_API_CALL;
3447 
3448   return multi_timeout(multi, timeout_ms);
3449 }
3450 
3451 /*
3452  * Tell the application it should update its timers, if it subscribes to the
3453  * update timer callback.
3454  */
3455 CURLMcode Curl_update_timer(struct Curl_multi *multi)
3456 {
3457   long timeout_ms;
3458   int rc;
3459 
3460   if(!multi->timer_cb || multi->dead)
3461     return CURLM_OK;
3462   if(multi_timeout(multi, &timeout_ms)) {
3463     return CURLM_OK;
3464   }
3465   if(timeout_ms < 0) {
3466     static const struct curltime none = {0, 0};
3467     if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
3468       multi->timer_lastcall = none;
3469       /* there's no timeout now but there was one previously, tell the app to
3470          disable it */
3471       set_in_callback(multi, TRUE);
3472       rc = multi->timer_cb(multi, -1, multi->timer_userp);
3473       set_in_callback(multi, FALSE);
3474       if(rc == -1) {
3475         multi->dead = TRUE;
3476         return CURLM_ABORTED_BY_CALLBACK;
3477       }
3478       return CURLM_OK;
3479     }
3480     return CURLM_OK;
3481   }
3482 
3483   /* When multi_timeout() is done, multi->timetree points to the node with the
3484    * timeout we got the (relative) time-out time for. We can thus easily check
3485    * if this is the same (fixed) time as we got in a previous call and then
3486    * avoid calling the callback again. */
3487   if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
3488     return CURLM_OK;
3489 
3490   multi->timer_lastcall = multi->timetree->key;
3491 
3492   set_in_callback(multi, TRUE);
3493   rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3494   set_in_callback(multi, FALSE);
3495   if(rc == -1) {
3496     multi->dead = TRUE;
3497     return CURLM_ABORTED_BY_CALLBACK;
3498   }
3499   return CURLM_OK;
3500 }
3501 
3502 /*
3503  * multi_deltimeout()
3504  *
3505  * Remove a given timestamp from the list of timeouts.
3506  */
3507 static void
3508 multi_deltimeout(struct Curl_easy *data, expire_id eid)
3509 {
3510   struct Curl_llist_element *e;
3511   struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3512   /* find and remove the specific node from the list */
3513   for(e = timeoutlist->head; e; e = e->next) {
3514     struct time_node *n = (struct time_node *)e->ptr;
3515     if(n->eid == eid) {
3516       Curl_llist_remove(timeoutlist, e, NULL);
3517       return;
3518     }
3519   }
3520 }
3521 
3522 /*
3523  * multi_addtimeout()
3524  *
3525  * Add a timestamp to the list of timeouts. Keep the list sorted so that head
3526  * of list is always the timeout nearest in time.
3527  *
3528  */
3529 static CURLMcode
3530 multi_addtimeout(struct Curl_easy *data,
3531                  struct curltime *stamp,
3532                  expire_id eid)
3533 {
3534   struct Curl_llist_element *e;
3535   struct time_node *node;
3536   struct Curl_llist_element *prev = NULL;
3537   size_t n;
3538   struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3539 
3540   node = &data->state.expires[eid];
3541 
3542   /* copy the timestamp and id */
3543   memcpy(&node->time, stamp, sizeof(*stamp));
3544   node->eid = eid; /* also marks it as in use */
3545 
3546   n = Curl_llist_count(timeoutlist);
3547   if(n) {
3548     /* find the correct spot in the list */
3549     for(e = timeoutlist->head; e; e = e->next) {
3550       struct time_node *check = (struct time_node *)e->ptr;
3551       timediff_t diff = Curl_timediff(check->time, node->time);
3552       if(diff > 0)
3553         break;
3554       prev = e;
3555     }
3556 
3557   }
3558   /* else
3559      this is the first timeout on the list */
3560 
3561   Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
3562   return CURLM_OK;
3563 }
3564 
3565 /*
3566  * Curl_expire()
3567  *
3568  * given a number of milliseconds from now to use to set the 'act before
3569  * this'-time for the transfer, to be extracted by curl_multi_timeout()
3570  *
3571  * The timeout will be added to a queue of timeouts if it defines a moment in
3572  * time that is later than the current head of queue.
3573  *
3574  * Expire replaces a former timeout using the same id if already set.
3575  */
3576 void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
3577 {
3578   struct Curl_multi *multi = data->multi;
3579   struct curltime *nowp = &data->state.expiretime;
3580   struct curltime set;
3581 
3582   /* this is only interesting while there is still an associated multi struct
3583      remaining! */
3584   if(!multi)
3585     return;
3586 
3587   DEBUGASSERT(id < EXPIRE_LAST);
3588 
3589   set = Curl_now();
3590   set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */
3591   set.tv_usec += (unsigned int)(milli%1000)*1000;
3592 
3593   if(set.tv_usec >= 1000000) {
3594     set.tv_sec++;
3595     set.tv_usec -= 1000000;
3596   }
3597 
3598   /* Remove any timer with the same id just in case. */
3599   multi_deltimeout(data, id);
3600 
3601   /* Add it to the timer list.  It must stay in the list until it has expired
3602      in case we need to recompute the minimum timer later. */
3603   multi_addtimeout(data, &set, id);
3604 
3605   if(nowp->tv_sec || nowp->tv_usec) {
3606     /* This means that the struct is added as a node in the splay tree.
3607        Compare if the new time is earlier, and only remove-old/add-new if it
3608        is. */
3609     timediff_t diff = Curl_timediff(set, *nowp);
3610     int rc;
3611 
3612     if(diff > 0) {
3613       /* The current splay tree entry is sooner than this new expiry time.
3614          We don't need to update our splay tree entry. */
3615       return;
3616     }
3617 
3618     /* Since this is an updated time, we must remove the previous entry from
3619        the splay tree first and then re-add the new value */
3620     rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3621                           &multi->timetree);
3622     if(rc)
3623       infof(data, "Internal error removing splay node = %d", rc);
3624   }
3625 
3626   /* Indicate that we are in the splay tree and insert the new timer expiry
3627      value since it is our local minimum. */
3628   *nowp = set;
3629   data->state.timenode.payload = data;
3630   multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
3631                                      &data->state.timenode);
3632 }
3633 
3634 /*
3635  * Curl_expire_done()
3636  *
3637  * Removes the expire timer. Marks it as done.
3638  *
3639  */
3640 void Curl_expire_done(struct Curl_easy *data, expire_id id)
3641 {
3642   /* remove the timer, if there */
3643   multi_deltimeout(data, id);
3644 }
3645 
3646 /*
3647  * Curl_expire_clear()
3648  *
3649  * Clear ALL timeout values for this handle.
3650  */
3651 void Curl_expire_clear(struct Curl_easy *data)
3652 {
3653   struct Curl_multi *multi = data->multi;
3654   struct curltime *nowp = &data->state.expiretime;
3655 
3656   /* this is only interesting while there is still an associated multi struct
3657      remaining! */
3658   if(!multi)
3659     return;
3660 
3661   if(nowp->tv_sec || nowp->tv_usec) {
3662     /* Since this is an cleared time, we must remove the previous entry from
3663        the splay tree */
3664     struct Curl_llist *list = &data->state.timeoutlist;
3665     int rc;
3666 
3667     rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3668                           &multi->timetree);
3669     if(rc)
3670       infof(data, "Internal error clearing splay node = %d", rc);
3671 
3672     /* flush the timeout list too */
3673     while(list->size > 0) {
3674       Curl_llist_remove(list, list->tail, NULL);
3675     }
3676 
3677 #ifdef DEBUGBUILD
3678     infof(data, "Expire cleared");
3679 #endif
3680     nowp->tv_sec = 0;
3681     nowp->tv_usec = 0;
3682   }
3683 }
3684 
3685 
3686 
3687 
3688 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
3689                             void *hashp)
3690 {
3691   struct Curl_sh_entry *there = NULL;
3692 
3693   there = sh_getentry(&multi->sockhash, s);
3694 
3695   if(!there)
3696     return CURLM_BAD_SOCKET;
3697 
3698   there->socketp = hashp;
3699 
3700   return CURLM_OK;
3701 }
3702 
3703 size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
3704 {
3705   return multi ? multi->max_host_connections : 0;
3706 }
3707 
3708 size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
3709 {
3710   return multi ? multi->max_total_connections : 0;
3711 }
3712 
3713 /*
3714  * When information about a connection has appeared, call this!
3715  */
3716 
3717 void Curl_multiuse_state(struct Curl_easy *data,
3718                          int bundlestate) /* use BUNDLE_* defines */
3719 {
3720   struct connectdata *conn;
3721   DEBUGASSERT(data);
3722   DEBUGASSERT(data->multi);
3723   conn = data->conn;
3724   DEBUGASSERT(conn);
3725   DEBUGASSERT(conn->bundle);
3726 
3727   conn->bundle->multiuse = bundlestate;
3728   process_pending_handles(data->multi);
3729 }
3730 
3731 /* process_pending_handles() moves all handles from PENDING
3732    back into the main list and change state to CONNECT */
3733 static void process_pending_handles(struct Curl_multi *multi)
3734 {
3735   struct Curl_llist_element *e = multi->pending.head;
3736   if(e) {
3737     struct Curl_easy *data = e->ptr;
3738 
3739     DEBUGASSERT(data->mstate == MSTATE_PENDING);
3740 
3741     /* put it back into the main list */
3742     link_easy(multi, data);
3743 
3744     multistate(data, MSTATE_CONNECT);
3745 
3746     /* Remove this node from the list */
3747     Curl_llist_remove(&multi->pending, e, NULL);
3748 
3749     /* Make sure that the handle will be processed soonish. */
3750     Curl_expire(data, 0, EXPIRE_RUN_NOW);
3751 
3752     /* mark this as having been in the pending queue */
3753     data->state.previouslypending = TRUE;
3754   }
3755 }
3756 
3757 void Curl_set_in_callback(struct Curl_easy *data, bool value)
3758 {
3759   /* might get called when there is no data pointer! */
3760   if(data) {
3761     if(data->multi_easy)
3762       data->multi_easy->in_callback = value;
3763     else if(data->multi)
3764       data->multi->in_callback = value;
3765   }
3766 }
3767 
3768 bool Curl_is_in_callback(struct Curl_easy *easy)
3769 {
3770   return ((easy->multi && easy->multi->in_callback) ||
3771           (easy->multi_easy && easy->multi_easy->in_callback));
3772 }
3773 
3774 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
3775 {
3776   DEBUGASSERT(multi);
3777   return multi->max_concurrent_streams;
3778 }
3779 
3780 struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi)
3781 {
3782   struct Curl_easy **a = malloc(sizeof(struct Curl_easy *) *
3783                                 (multi->num_easy + 1));
3784   if(a) {
3785     int i = 0;
3786     struct Curl_easy *e = multi->easyp;
3787     while(e) {
3788       DEBUGASSERT(i < multi->num_easy);
3789       if(!e->internal)
3790         a[i++] = e;
3791       e = e->next;
3792     }
3793     a[i] = NULL; /* last entry is a NULL */
3794   }
3795   return a;
3796 }
3797