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