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