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