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