xref: /curl/lib/multi.c (revision c56dee68)
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     /* eventfd has a stringent rule of requiring the 8-byte buffer when
1545        calling write(2) on it, which makes the sizeof(buf) below fine since
1546        this is only used on 64-bit systems and then the pointer is 64-bit */
1547 #else
1548     buf[0] = 1;
1549 #endif
1550     while(1) {
1551       /* swrite() is not thread-safe in general, because concurrent calls
1552          can have their messages interleaved, but in this case the content
1553          of the messages does not matter, which makes it ok to call.
1554 
1555          The write socket is set to non-blocking, this way this function
1556          cannot block, making it safe to call even from the same thread
1557          that will call curl_multi_wait(). If swrite() returns that it
1558          would block, it is considered successful because it means that
1559          previous calls to this function will wake up the poll(). */
1560       if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1561         int err = SOCKERRNO;
1562         int return_success;
1563 #ifdef USE_WINSOCK
1564         return_success = WSAEWOULDBLOCK == err;
1565 #else
1566         if(EINTR == err)
1567           continue;
1568         return_success = EWOULDBLOCK == err || EAGAIN == err;
1569 #endif
1570         if(!return_success)
1571           return CURLM_WAKEUP_FAILURE;
1572       }
1573       return CURLM_OK;
1574     }
1575   }
1576 #endif
1577 #endif
1578   return CURLM_WAKEUP_FAILURE;
1579 }
1580 
1581 /*
1582  * multi_ischanged() is called
1583  *
1584  * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1585  * => CONNECT action.
1586  *
1587  * Set 'clear' to TRUE to have it also clear the state variable.
1588  */
1589 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1590 {
1591   bool retval = multi->recheckstate;
1592   if(clear)
1593     multi->recheckstate = FALSE;
1594   return retval;
1595 }
1596 
1597 /*
1598  * Curl_multi_connchanged() is called to tell that there is a connection in
1599  * this multi handle that has changed state (multiplexing become possible, the
1600  * number of allowed streams changed or similar), and a subsequent use of this
1601  * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1602  * retry.
1603  */
1604 void Curl_multi_connchanged(struct Curl_multi *multi)
1605 {
1606   multi->recheckstate = TRUE;
1607 }
1608 
1609 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1610                                  struct Curl_easy *data,
1611                                  struct connectdata *conn)
1612 {
1613   CURLMcode rc;
1614 
1615   if(multi->in_callback)
1616     return CURLM_RECURSIVE_API_CALL;
1617 
1618   rc = curl_multi_add_handle(multi, data);
1619   if(!rc) {
1620     struct SingleRequest *k = &data->req;
1621 
1622     /* pass in NULL for 'conn' here since we do not want to init the
1623        connection, only this transfer */
1624     Curl_init_do(data, NULL);
1625 
1626     /* take this handle to the perform state right away */
1627     multistate(data, MSTATE_PERFORMING);
1628     Curl_attach_connection(data, conn);
1629     k->keepon |= KEEP_RECV; /* setup to receive! */
1630   }
1631   return rc;
1632 }
1633 
1634 static CURLcode multi_do(struct Curl_easy *data, bool *done)
1635 {
1636   CURLcode result = CURLE_OK;
1637   struct connectdata *conn = data->conn;
1638 
1639   DEBUGASSERT(conn);
1640   DEBUGASSERT(conn->handler);
1641 
1642   if(conn->handler->do_it)
1643     result = conn->handler->do_it(data, done);
1644 
1645   return result;
1646 }
1647 
1648 /*
1649  * multi_do_more() is called during the DO_MORE multi state. It is basically a
1650  * second stage DO state which (wrongly) was introduced to support FTP's
1651  * second connection.
1652  *
1653  * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1654  * DOING state there is more work to do!
1655  */
1656 
1657 static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
1658 {
1659   CURLcode result = CURLE_OK;
1660   struct connectdata *conn = data->conn;
1661 
1662   *complete = 0;
1663 
1664   if(conn->handler->do_more)
1665     result = conn->handler->do_more(data, complete);
1666 
1667   return result;
1668 }
1669 
1670 /*
1671  * Check whether a timeout occurred, and handle it if it did
1672  */
1673 static bool multi_handle_timeout(struct Curl_easy *data,
1674                                  struct curltime *now,
1675                                  bool *stream_error,
1676                                  CURLcode *result)
1677 {
1678   bool connect_timeout = data->mstate < MSTATE_DO;
1679   timediff_t timeout_ms = Curl_timeleft(data, now, connect_timeout);
1680   if(timeout_ms < 0) {
1681     /* Handle timed out */
1682     struct curltime since;
1683     if(connect_timeout)
1684       since = data->progress.t_startsingle;
1685     else
1686       since = data->progress.t_startop;
1687     if(data->mstate == MSTATE_RESOLVING)
1688       failf(data, "Resolving timed out after %" FMT_TIMEDIFF_T
1689             " milliseconds", Curl_timediff(*now, since));
1690     else if(data->mstate == MSTATE_CONNECTING)
1691       failf(data, "Connection timed out after %" FMT_TIMEDIFF_T
1692             " milliseconds", Curl_timediff(*now, since));
1693     else {
1694       struct SingleRequest *k = &data->req;
1695       if(k->size != -1) {
1696         failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
1697               " milliseconds with %" FMT_OFF_T " out of %"
1698               FMT_OFF_T " bytes received",
1699               Curl_timediff(*now, since), k->bytecount, k->size);
1700       }
1701       else {
1702         failf(data, "Operation timed out after %" FMT_TIMEDIFF_T
1703               " milliseconds with %" FMT_OFF_T " bytes received",
1704               Curl_timediff(*now, since), k->bytecount);
1705       }
1706     }
1707     *result = CURLE_OPERATION_TIMEDOUT;
1708     if(data->conn) {
1709       /* Force connection closed if the connection has indeed been used */
1710       if(data->mstate > MSTATE_DO) {
1711         streamclose(data->conn, "Disconnect due to timeout");
1712         *stream_error = TRUE;
1713       }
1714       (void)multi_done(data, *result, TRUE);
1715     }
1716     return TRUE;
1717   }
1718 
1719   return FALSE;
1720 }
1721 
1722 /*
1723  * We are doing protocol-specific connecting and this is being called over and
1724  * over from the multi interface until the connection phase is done on
1725  * protocol layer.
1726  */
1727 
1728 static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
1729 {
1730   CURLcode result = CURLE_OK;
1731   struct connectdata *conn = data->conn;
1732 
1733   if(conn && conn->handler->connecting) {
1734     *done = FALSE;
1735     result = conn->handler->connecting(data, done);
1736   }
1737   else
1738     *done = TRUE;
1739 
1740   return result;
1741 }
1742 
1743 /*
1744  * We are DOING this is being called over and over from the multi interface
1745  * until the DOING phase is done on protocol layer.
1746  */
1747 
1748 static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
1749 {
1750   CURLcode result = CURLE_OK;
1751   struct connectdata *conn = data->conn;
1752 
1753   if(conn && conn->handler->doing) {
1754     *done = FALSE;
1755     result = conn->handler->doing(data, done);
1756   }
1757   else
1758     *done = TRUE;
1759 
1760   return result;
1761 }
1762 
1763 /*
1764  * We have discovered that the TCP connection has been successful, we can now
1765  * proceed with some action.
1766  *
1767  */
1768 static CURLcode protocol_connect(struct Curl_easy *data,
1769                                  bool *protocol_done)
1770 {
1771   CURLcode result = CURLE_OK;
1772   struct connectdata *conn = data->conn;
1773   DEBUGASSERT(conn);
1774   DEBUGASSERT(protocol_done);
1775 
1776   *protocol_done = FALSE;
1777 
1778   if(Curl_conn_is_connected(conn, FIRSTSOCKET)
1779      && conn->bits.protoconnstart) {
1780     /* We already are connected, get back. This may happen when the connect
1781        worked fine in the first call, like when we connect to a local server
1782        or proxy. Note that we do not know if the protocol is actually done.
1783 
1784        Unless this protocol does not have any protocol-connect callback, as
1785        then we know we are done. */
1786     if(!conn->handler->connecting)
1787       *protocol_done = TRUE;
1788 
1789     return CURLE_OK;
1790   }
1791 
1792   if(!conn->bits.protoconnstart) {
1793     if(conn->handler->connect_it) {
1794       /* is there a protocol-specific connect() procedure? */
1795 
1796       /* Call the protocol-specific connect function */
1797       result = conn->handler->connect_it(data, protocol_done);
1798     }
1799     else
1800       *protocol_done = TRUE;
1801 
1802     /* it has started, possibly even completed but that knowledge is not stored
1803        in this bit! */
1804     if(!result)
1805       conn->bits.protoconnstart = TRUE;
1806   }
1807 
1808   return result; /* pass back status */
1809 }
1810 
1811 static void set_in_callback(struct Curl_multi *multi, bool value)
1812 {
1813   multi->in_callback = value;
1814 }
1815 
1816 /*
1817  * posttransfer() is called immediately after a transfer ends
1818  */
1819 static void multi_posttransfer(struct Curl_easy *data)
1820 {
1821 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
1822   /* restore the signal handler for SIGPIPE before we get back */
1823   if(!data->set.no_signal)
1824     signal(SIGPIPE, data->state.prev_signal);
1825 #else
1826   (void)data; /* unused parameter */
1827 #endif
1828 }
1829 
1830 /*
1831  * multi_follow() handles the URL redirect magic. Pass in the 'newurl' string
1832  * as given by the remote server and set up the new URL to request.
1833  *
1834  * This function DOES NOT FREE the given url.
1835  */
1836 static CURLcode multi_follow(struct Curl_easy *data,
1837                              char *newurl,    /* the Location: string */
1838                              followtype type) /* see transfer.h */
1839 {
1840 #ifdef CURL_DISABLE_HTTP
1841   (void)data;
1842   (void)newurl;
1843   (void)type;
1844   /* Location: following will not happen when HTTP is disabled */
1845   return CURLE_TOO_MANY_REDIRECTS;
1846 #else
1847 
1848   /* Location: redirect */
1849   bool disallowport = FALSE;
1850   bool reachedmax = FALSE;
1851   CURLUcode uc;
1852 
1853   DEBUGASSERT(type != FOLLOW_NONE);
1854 
1855   if(type != FOLLOW_FAKE)
1856     data->state.requests++; /* count all real follows */
1857   if(type == FOLLOW_REDIR) {
1858     if((data->set.maxredirs != -1) &&
1859        (data->state.followlocation >= data->set.maxredirs)) {
1860       reachedmax = TRUE;
1861       type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected
1862                              to URL */
1863     }
1864     else {
1865       data->state.followlocation++; /* count redirect-followings, including
1866                                        auth reloads */
1867 
1868       if(data->set.http_auto_referer) {
1869         CURLU *u;
1870         char *referer = NULL;
1871 
1872         /* We are asked to automatically set the previous URL as the referer
1873            when we get the next URL. We pick the ->url field, which may or may
1874            not be 100% correct */
1875 
1876         if(data->state.referer_alloc) {
1877           Curl_safefree(data->state.referer);
1878           data->state.referer_alloc = FALSE;
1879         }
1880 
1881         /* Make a copy of the URL without credentials and fragment */
1882         u = curl_url();
1883         if(!u)
1884           return CURLE_OUT_OF_MEMORY;
1885 
1886         uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0);
1887         if(!uc)
1888           uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0);
1889         if(!uc)
1890           uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
1891         if(!uc)
1892           uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
1893         if(!uc)
1894           uc = curl_url_get(u, CURLUPART_URL, &referer, 0);
1895 
1896         curl_url_cleanup(u);
1897 
1898         if(uc || !referer)
1899           return CURLE_OUT_OF_MEMORY;
1900 
1901         data->state.referer = referer;
1902         data->state.referer_alloc = TRUE; /* yes, free this later */
1903       }
1904     }
1905   }
1906 
1907   if((type != FOLLOW_RETRY) &&
1908      (data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1909      Curl_is_absolute_url(newurl, NULL, 0, FALSE)) {
1910     /* If this is not redirect due to a 401 or 407 response and an absolute
1911        URL: do not allow a custom port number */
1912     disallowport = TRUE;
1913   }
1914 
1915   DEBUGASSERT(data->state.uh);
1916   uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, (unsigned int)
1917                     ((type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
1918                      ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) |
1919                      CURLU_ALLOW_SPACE |
1920                      (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)));
1921   if(uc) {
1922     if(type != FOLLOW_FAKE) {
1923       failf(data, "The redirect target URL could not be parsed: %s",
1924             curl_url_strerror(uc));
1925       return Curl_uc_to_curlcode(uc);
1926     }
1927 
1928     /* the URL could not be parsed for some reason, but since this is FAKE
1929        mode, just duplicate the field as-is */
1930     newurl = strdup(newurl);
1931     if(!newurl)
1932       return CURLE_OUT_OF_MEMORY;
1933   }
1934   else {
1935     uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
1936     if(uc)
1937       return Curl_uc_to_curlcode(uc);
1938 
1939     /* Clear auth if this redirects to a different port number or protocol,
1940        unless permitted */
1941     if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
1942       char *portnum;
1943       int port;
1944       bool clear = FALSE;
1945 
1946       if(data->set.use_port && data->state.allow_port)
1947         /* a custom port is used */
1948         port = (int)data->set.use_port;
1949       else {
1950         uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum,
1951                           CURLU_DEFAULT_PORT);
1952         if(uc) {
1953           free(newurl);
1954           return Curl_uc_to_curlcode(uc);
1955         }
1956         port = atoi(portnum);
1957         free(portnum);
1958       }
1959       if(port != data->info.conn_remote_port) {
1960         infof(data, "Clear auth, redirects to port from %u to %u",
1961               data->info.conn_remote_port, port);
1962         clear = TRUE;
1963       }
1964       else {
1965         char *scheme;
1966         const struct Curl_handler *p;
1967         uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
1968         if(uc) {
1969           free(newurl);
1970           return Curl_uc_to_curlcode(uc);
1971         }
1972 
1973         p = Curl_get_scheme_handler(scheme);
1974         if(p && (p->protocol != data->info.conn_protocol)) {
1975           infof(data, "Clear auth, redirects scheme from %s to %s",
1976                 data->info.conn_scheme, scheme);
1977           clear = TRUE;
1978         }
1979         free(scheme);
1980       }
1981       if(clear) {
1982         Curl_safefree(data->state.aptr.user);
1983         Curl_safefree(data->state.aptr.passwd);
1984       }
1985     }
1986   }
1987 
1988   if(type == FOLLOW_FAKE) {
1989     /* we are only figuring out the new URL if we would have followed locations
1990        but now we are done so we can get out! */
1991     data->info.wouldredirect = newurl;
1992 
1993     if(reachedmax) {
1994       failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
1995       return CURLE_TOO_MANY_REDIRECTS;
1996     }
1997     return CURLE_OK;
1998   }
1999 
2000   if(disallowport)
2001     data->state.allow_port = FALSE;
2002 
2003   if(data->state.url_alloc)
2004     Curl_safefree(data->state.url);
2005 
2006   data->state.url = newurl;
2007   data->state.url_alloc = TRUE;
2008   Curl_req_soft_reset(&data->req, data);
2009   infof(data, "Issue another request to this URL: '%s'", data->state.url);
2010 
2011   /*
2012    * We get here when the HTTP code is 300-399 (and 401). We need to perform
2013    * differently based on exactly what return code there was.
2014    *
2015    * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
2016    * an HTTP (proxy-) authentication scheme other than Basic.
2017    */
2018   switch(data->info.httpcode) {
2019     /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
2020        Authorization: XXXX header in the HTTP request code snippet */
2021     /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
2022        Proxy-Authorization: XXXX header in the HTTP request code snippet */
2023     /* 300 - Multiple Choices */
2024     /* 306 - Not used */
2025     /* 307 - Temporary Redirect */
2026   default:  /* for all above (and the unknown ones) */
2027     /* Some codes are explicitly mentioned since I have checked RFC2616 and
2028      * they seem to be OK to POST to.
2029      */
2030     break;
2031   case 301: /* Moved Permanently */
2032     /* (quote from RFC7231, section 6.4.2)
2033      *
2034      * Note: For historical reasons, a user agent MAY change the request
2035      * method from POST to GET for the subsequent request. If this
2036      * behavior is undesired, the 307 (Temporary Redirect) status code
2037      * can be used instead.
2038      *
2039      * ----
2040      *
2041      * Many webservers expect this, so these servers often answers to a POST
2042      * request with an error page. To be sure that libcurl gets the page that
2043      * most user agents would get, libcurl has to force GET.
2044      *
2045      * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and
2046      * can be overridden with CURLOPT_POSTREDIR.
2047      */
2048     if((data->state.httpreq == HTTPREQ_POST
2049         || data->state.httpreq == HTTPREQ_POST_FORM
2050         || data->state.httpreq == HTTPREQ_POST_MIME)
2051        && !(data->set.keep_post & CURL_REDIR_POST_301)) {
2052       infof(data, "Switch from POST to GET");
2053       data->state.httpreq = HTTPREQ_GET;
2054       Curl_creader_set_rewind(data, FALSE);
2055     }
2056     break;
2057   case 302: /* Found */
2058     /* (quote from RFC7231, section 6.4.3)
2059      *
2060      * Note: For historical reasons, a user agent MAY change the request
2061      * method from POST to GET for the subsequent request. If this
2062      * behavior is undesired, the 307 (Temporary Redirect) status code
2063      * can be used instead.
2064      *
2065      * ----
2066      *
2067      * Many webservers expect this, so these servers often answers to a POST
2068      * request with an error page. To be sure that libcurl gets the page that
2069      * most user agents would get, libcurl has to force GET.
2070      *
2071      * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and
2072      * can be overridden with CURLOPT_POSTREDIR.
2073      */
2074     if((data->state.httpreq == HTTPREQ_POST
2075         || data->state.httpreq == HTTPREQ_POST_FORM
2076         || data->state.httpreq == HTTPREQ_POST_MIME)
2077        && !(data->set.keep_post & CURL_REDIR_POST_302)) {
2078       infof(data, "Switch from POST to GET");
2079       data->state.httpreq = HTTPREQ_GET;
2080       Curl_creader_set_rewind(data, FALSE);
2081     }
2082     break;
2083 
2084   case 303: /* See Other */
2085     /* 'See Other' location is not the resource but a substitute for the
2086      * resource. In this case we switch the method to GET/HEAD, unless the
2087      * method is POST and the user specified to keep it as POST.
2088      * https://github.com/curl/curl/issues/5237#issuecomment-614641049
2089      */
2090     if(data->state.httpreq != HTTPREQ_GET &&
2091        ((data->state.httpreq != HTTPREQ_POST &&
2092          data->state.httpreq != HTTPREQ_POST_FORM &&
2093          data->state.httpreq != HTTPREQ_POST_MIME) ||
2094         !(data->set.keep_post & CURL_REDIR_POST_303))) {
2095       data->state.httpreq = HTTPREQ_GET;
2096       infof(data, "Switch to %s",
2097             data->req.no_body ? "HEAD" : "GET");
2098     }
2099     break;
2100   case 304: /* Not Modified */
2101     /* 304 means we did a conditional request and it was "Not modified".
2102      * We should not get any Location: header in this response!
2103      */
2104     break;
2105   case 305: /* Use Proxy */
2106     /* (quote from RFC2616, section 10.3.6):
2107      * "The requested resource MUST be accessed through the proxy given
2108      * by the Location field. The Location field gives the URI of the
2109      * proxy. The recipient is expected to repeat this single request
2110      * via the proxy. 305 responses MUST only be generated by origin
2111      * servers."
2112      */
2113     break;
2114   }
2115   Curl_pgrsTime(data, TIMER_REDIRECT);
2116   Curl_pgrsResetTransferSizes(data);
2117 
2118   return CURLE_OK;
2119 #endif /* CURL_DISABLE_HTTP */
2120 }
2121 
2122 static CURLMcode state_performing(struct Curl_easy *data,
2123                                   struct curltime *nowp,
2124                                   bool *stream_errorp,
2125                                   CURLcode *resultp)
2126 {
2127   char *newurl = NULL;
2128   bool retry = FALSE;
2129   timediff_t recv_timeout_ms = 0;
2130   timediff_t send_timeout_ms = 0;
2131   CURLMcode rc = CURLM_OK;
2132   CURLcode result = *resultp = CURLE_OK;
2133   *stream_errorp = FALSE;
2134 
2135   /* check if over send speed */
2136   if(data->set.max_send_speed)
2137     send_timeout_ms = Curl_pgrsLimitWaitTime(&data->progress.ul,
2138                                              data->set.max_send_speed,
2139                                              *nowp);
2140 
2141   /* check if over recv speed */
2142   if(data->set.max_recv_speed)
2143     recv_timeout_ms = Curl_pgrsLimitWaitTime(&data->progress.dl,
2144                                              data->set.max_recv_speed,
2145                                              *nowp);
2146 
2147   if(send_timeout_ms || recv_timeout_ms) {
2148     Curl_ratelimit(data, *nowp);
2149     multistate(data, MSTATE_RATELIMITING);
2150     if(send_timeout_ms >= recv_timeout_ms)
2151       Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2152     else
2153       Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2154     return CURLM_OK;
2155   }
2156 
2157   /* read/write data if it is ready to do so */
2158   result = Curl_sendrecv(data, nowp);
2159 
2160   if(data->req.done || (result == CURLE_RECV_ERROR)) {
2161     /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
2162      * condition and the server closed the reused connection exactly when we
2163      * wanted to use it, so figure out if that is indeed the case.
2164      */
2165     CURLcode ret = Curl_retry_request(data, &newurl);
2166     if(!ret)
2167       retry = !!newurl;
2168     else if(!result)
2169       result = ret;
2170 
2171     if(retry) {
2172       /* if we are to retry, set the result to OK and consider the
2173          request as done */
2174       result = CURLE_OK;
2175       data->req.done = TRUE;
2176     }
2177   }
2178   else if((CURLE_HTTP2_STREAM == result) &&
2179           Curl_h2_http_1_1_error(data)) {
2180     CURLcode ret = Curl_retry_request(data, &newurl);
2181 
2182     if(!ret) {
2183       infof(data, "Downgrades to HTTP/1.1");
2184       streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
2185       data->state.httpwant = CURL_HTTP_VERSION_1_1;
2186       /* clear the error message bit too as we ignore the one we got */
2187       data->state.errorbuf = FALSE;
2188       if(!newurl)
2189         /* typically for HTTP_1_1_REQUIRED error on first flight */
2190         newurl = strdup(data->state.url);
2191       /* if we are to retry, set the result to OK and consider the request
2192          as done */
2193       retry = TRUE;
2194       result = CURLE_OK;
2195       data->req.done = TRUE;
2196     }
2197     else
2198       result = ret;
2199   }
2200 
2201   if(result) {
2202     /*
2203      * The transfer phase returned error, we mark the connection to get closed
2204      * to prevent being reused. This is because we cannot possibly know if the
2205      * connection is in a good shape or not now. Unless it is a protocol which
2206      * uses two "channels" like FTP, as then the error happened in the data
2207      * connection.
2208      */
2209 
2210     if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2211        result != CURLE_HTTP2_STREAM)
2212       streamclose(data->conn, "Transfer returned error");
2213 
2214     multi_posttransfer(data);
2215     multi_done(data, result, TRUE);
2216   }
2217   else if(data->req.done && !Curl_cwriter_is_paused(data)) {
2218 
2219     /* call this even if the readwrite function returned error */
2220     multi_posttransfer(data);
2221 
2222     /* When we follow redirects or is set to retry the connection, we must to
2223        go back to the CONNECT state */
2224     if(data->req.newurl || retry) {
2225       followtype follow = FOLLOW_NONE;
2226       if(!retry) {
2227         /* if the URL is a follow-location and not just a retried request then
2228            figure out the URL here */
2229         free(newurl);
2230         newurl = data->req.newurl;
2231         data->req.newurl = NULL;
2232         follow = FOLLOW_REDIR;
2233       }
2234       else
2235         follow = FOLLOW_RETRY;
2236       (void)multi_done(data, CURLE_OK, FALSE);
2237       /* multi_done() might return CURLE_GOT_NOTHING */
2238       result = multi_follow(data, newurl, follow);
2239       if(!result) {
2240         multistate(data, MSTATE_SETUP);
2241         rc = CURLM_CALL_MULTI_PERFORM;
2242       }
2243     }
2244     else {
2245       /* after the transfer is done, go DONE */
2246 
2247       /* but first check to see if we got a location info even though we are
2248          not following redirects */
2249       if(data->req.location) {
2250         free(newurl);
2251         newurl = data->req.location;
2252         data->req.location = NULL;
2253         result = multi_follow(data, newurl, FOLLOW_FAKE);
2254         if(result) {
2255           *stream_errorp = TRUE;
2256           result = multi_done(data, result, TRUE);
2257         }
2258       }
2259 
2260       if(!result) {
2261         multistate(data, MSTATE_DONE);
2262         rc = CURLM_CALL_MULTI_PERFORM;
2263       }
2264     }
2265   }
2266   else if(data->state.select_bits && !Curl_xfer_is_blocked(data)) {
2267     /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer does
2268        not get stuck on this transfer at the expense of other concurrent
2269        transfers */
2270     Curl_expire(data, 0, EXPIRE_RUN_NOW);
2271   }
2272   free(newurl);
2273   *resultp = result;
2274   return rc;
2275 }
2276 
2277 static CURLMcode state_do(struct Curl_easy *data,
2278                           bool *stream_errorp,
2279                           CURLcode *resultp)
2280 {
2281   CURLMcode rc = CURLM_OK;
2282   CURLcode result = CURLE_OK;
2283   if(data->set.fprereq) {
2284     int prereq_rc;
2285 
2286     /* call the prerequest callback function */
2287     Curl_set_in_callback(data, TRUE);
2288     prereq_rc = data->set.fprereq(data->set.prereq_userp,
2289                                   data->info.primary.remote_ip,
2290                                   data->info.primary.local_ip,
2291                                   data->info.primary.remote_port,
2292                                   data->info.primary.local_port);
2293     Curl_set_in_callback(data, FALSE);
2294     if(prereq_rc != CURL_PREREQFUNC_OK) {
2295       failf(data, "operation aborted by pre-request callback");
2296       /* failure in pre-request callback - do not do any other processing */
2297       result = CURLE_ABORTED_BY_CALLBACK;
2298       multi_posttransfer(data);
2299       multi_done(data, result, FALSE);
2300       *stream_errorp = TRUE;
2301       goto end;
2302     }
2303   }
2304 
2305   if(data->set.connect_only == 1) {
2306     /* keep connection open for application to use the socket */
2307     connkeep(data->conn, "CONNECT_ONLY");
2308     multistate(data, MSTATE_DONE);
2309     rc = CURLM_CALL_MULTI_PERFORM;
2310   }
2311   else {
2312     bool dophase_done = FALSE;
2313     /* Perform the protocol's DO action */
2314     result = multi_do(data, &dophase_done);
2315 
2316     /* When multi_do() returns failure, data->conn might be NULL! */
2317 
2318     if(!result) {
2319       if(!dophase_done) {
2320 #ifndef CURL_DISABLE_FTP
2321         /* some steps needed for wildcard matching */
2322         if(data->state.wildcardmatch) {
2323           struct WildcardData *wc = data->wildcard;
2324           if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
2325             /* skip some states if it is important */
2326             multi_done(data, CURLE_OK, FALSE);
2327 
2328             /* if there is no connection left, skip the DONE state */
2329             multistate(data, data->conn ?
2330                        MSTATE_DONE : MSTATE_COMPLETED);
2331             rc = CURLM_CALL_MULTI_PERFORM;
2332             goto end;
2333           }
2334         }
2335 #endif
2336         /* DO was not completed in one function call, we must continue
2337            DOING... */
2338         multistate(data, MSTATE_DOING);
2339         rc = CURLM_CALL_MULTI_PERFORM;
2340       }
2341 
2342       /* after DO, go DO_DONE... or DO_MORE */
2343       else if(data->conn->bits.do_more) {
2344         /* we are supposed to do more, but we need to sit down, relax and wait
2345            a little while first */
2346         multistate(data, MSTATE_DOING_MORE);
2347         rc = CURLM_CALL_MULTI_PERFORM;
2348       }
2349       else {
2350         /* we are done with the DO, now DID */
2351         multistate(data, MSTATE_DID);
2352         rc = CURLM_CALL_MULTI_PERFORM;
2353       }
2354     }
2355     else if((CURLE_SEND_ERROR == result) &&
2356             data->conn->bits.reuse) {
2357       /*
2358        * In this situation, a connection that we were trying to use may have
2359        * unexpectedly died. If possible, send the connection back to the
2360        * CONNECT phase so we can try again.
2361        */
2362       char *newurl = NULL;
2363       followtype follow = FOLLOW_NONE;
2364       CURLcode drc;
2365 
2366       drc = Curl_retry_request(data, &newurl);
2367       if(drc) {
2368         /* a failure here pretty much implies an out of memory */
2369         result = drc;
2370         *stream_errorp = TRUE;
2371       }
2372 
2373       multi_posttransfer(data);
2374       drc = multi_done(data, result, FALSE);
2375 
2376       /* When set to retry the connection, we must go back to the CONNECT
2377        * state */
2378       if(newurl) {
2379         if(!drc || (drc == CURLE_SEND_ERROR)) {
2380           follow = FOLLOW_RETRY;
2381           drc = multi_follow(data, newurl, follow);
2382           if(!drc) {
2383             multistate(data, MSTATE_SETUP);
2384             rc = CURLM_CALL_MULTI_PERFORM;
2385             result = CURLE_OK;
2386           }
2387           else {
2388             /* Follow failed */
2389             result = drc;
2390           }
2391         }
2392         else {
2393           /* done did not return OK or SEND_ERROR */
2394           result = drc;
2395         }
2396       }
2397       else {
2398         /* Have error handler disconnect conn if we cannot retry */
2399         *stream_errorp = TRUE;
2400       }
2401       free(newurl);
2402     }
2403     else {
2404       /* failure detected */
2405       multi_posttransfer(data);
2406       if(data->conn)
2407         multi_done(data, result, FALSE);
2408       *stream_errorp = TRUE;
2409     }
2410   }
2411 end:
2412   *resultp = result;
2413   return rc;
2414 }
2415 
2416 static CURLMcode state_ratelimiting(struct Curl_easy *data,
2417                                     struct curltime *nowp,
2418                                     CURLcode *resultp)
2419 {
2420   CURLcode result = CURLE_OK;
2421   CURLMcode rc = CURLM_OK;
2422   DEBUGASSERT(data->conn);
2423   /* if both rates are within spec, resume transfer */
2424   if(Curl_pgrsUpdate(data))
2425     result = CURLE_ABORTED_BY_CALLBACK;
2426   else
2427     result = Curl_speedcheck(data, *nowp);
2428 
2429   if(result) {
2430     if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2431        result != CURLE_HTTP2_STREAM)
2432       streamclose(data->conn, "Transfer returned error");
2433 
2434     multi_posttransfer(data);
2435     multi_done(data, result, TRUE);
2436   }
2437   else {
2438     timediff_t recv_timeout_ms = 0;
2439     timediff_t send_timeout_ms = 0;
2440     if(data->set.max_send_speed)
2441       send_timeout_ms =
2442         Curl_pgrsLimitWaitTime(&data->progress.ul,
2443                                data->set.max_send_speed,
2444                                *nowp);
2445 
2446     if(data->set.max_recv_speed)
2447       recv_timeout_ms =
2448         Curl_pgrsLimitWaitTime(&data->progress.dl,
2449                                data->set.max_recv_speed,
2450                                *nowp);
2451 
2452     if(!send_timeout_ms && !recv_timeout_ms) {
2453       multistate(data, MSTATE_PERFORMING);
2454       Curl_ratelimit(data, *nowp);
2455       /* start performing again right away */
2456       rc = CURLM_CALL_MULTI_PERFORM;
2457     }
2458     else if(send_timeout_ms >= recv_timeout_ms)
2459       Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2460     else
2461       Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2462   }
2463   *resultp = result;
2464   return rc;
2465 }
2466 
2467 static CURLMcode state_resolving(struct Curl_multi *multi,
2468                                  struct Curl_easy *data,
2469                                  bool *stream_errorp,
2470                                  CURLcode *resultp)
2471 {
2472   struct Curl_dns_entry *dns = NULL;
2473   struct connectdata *conn = data->conn;
2474   const char *hostname;
2475   CURLcode result = CURLE_OK;
2476   CURLMcode rc = CURLM_OK;
2477 
2478   DEBUGASSERT(conn);
2479 #ifndef CURL_DISABLE_PROXY
2480   if(conn->bits.httpproxy)
2481     hostname = conn->http_proxy.host.name;
2482   else
2483 #endif
2484     if(conn->bits.conn_to_host)
2485       hostname = conn->conn_to_host.name;
2486     else
2487       hostname = conn->host.name;
2488 
2489   /* check if we have the name resolved by now */
2490   dns = Curl_fetch_addr(data, hostname, conn->primary.remote_port);
2491 
2492   if(dns) {
2493 #ifdef CURLRES_ASYNCH
2494     data->state.async.dns = dns;
2495     data->state.async.done = TRUE;
2496 #endif
2497     result = CURLE_OK;
2498     infof(data, "Hostname '%s' was found in DNS cache", hostname);
2499   }
2500 
2501   if(!dns)
2502     result = Curl_resolv_check(data, &dns);
2503 
2504   /* Update sockets here, because the socket(s) may have been closed and the
2505      application thus needs to be told, even if it is likely that the same
2506      socket(s) will again be used further down. If the name has not yet been
2507      resolved, it is likely that new sockets have been opened in an attempt to
2508      contact another resolver. */
2509   rc = singlesocket(multi, data);
2510   if(rc)
2511     return rc;
2512 
2513   if(dns) {
2514     bool connected;
2515     /* Perform the next step in the connection phase, and then move on to the
2516        WAITCONNECT state */
2517     result = Curl_once_resolved(data, &connected);
2518 
2519     if(result)
2520       /* if Curl_once_resolved() returns failure, the connection struct is
2521          already freed and gone */
2522       data->conn = NULL; /* no more connection */
2523     else {
2524       /* call again please so that we get the next socket setup */
2525       rc = CURLM_CALL_MULTI_PERFORM;
2526       if(connected)
2527         multistate(data, MSTATE_PROTOCONNECT);
2528       else {
2529         multistate(data, MSTATE_CONNECTING);
2530       }
2531     }
2532   }
2533 
2534   if(result)
2535     /* failure detected */
2536     *stream_errorp = TRUE;
2537 
2538   *resultp = result;
2539   return rc;
2540 }
2541 
2542 static CURLMcode state_connect(struct Curl_multi *multi,
2543                                struct Curl_easy *data,
2544                                struct curltime *nowp,
2545                                CURLcode *resultp)
2546 {
2547   /* Connect. We want to get a connection identifier filled in. This state can
2548      be entered from SETUP and from PENDING. */
2549   bool connected;
2550   bool async;
2551   CURLMcode rc = CURLM_OK;
2552   CURLcode result = Curl_connect(data, &async, &connected);
2553   if(CURLE_NO_CONNECTION_AVAILABLE == result) {
2554     /* There was no connection available. We will go to the pending state and
2555        wait for an available connection. */
2556     multistate(data, MSTATE_PENDING);
2557     /* unlink from process list */
2558     Curl_node_remove(&data->multi_queue);
2559     /* add handle to pending list */
2560     Curl_llist_append(&multi->pending, data, &data->multi_queue);
2561     *resultp = CURLE_OK;
2562     return rc;
2563   }
2564   else
2565     process_pending_handles(data->multi);
2566 
2567   if(!result) {
2568     *nowp = Curl_pgrsTime(data, TIMER_POSTQUEUE);
2569     if(async)
2570       /* We are now waiting for an asynchronous name lookup */
2571       multistate(data, MSTATE_RESOLVING);
2572     else {
2573       /* after the connect has been sent off, go WAITCONNECT unless the
2574          protocol connect is already done and we can go directly to WAITDO or
2575          DO! */
2576       rc = CURLM_CALL_MULTI_PERFORM;
2577 
2578       if(connected) {
2579         if(!data->conn->bits.reuse &&
2580            Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
2581           /* new connection, can multiplex, wake pending handles */
2582           process_pending_handles(data->multi);
2583         }
2584         multistate(data, MSTATE_PROTOCONNECT);
2585       }
2586       else {
2587         multistate(data, MSTATE_CONNECTING);
2588       }
2589     }
2590   }
2591   *resultp = result;
2592   return rc;
2593 }
2594 
2595 static CURLMcode multi_runsingle(struct Curl_multi *multi,
2596                                  struct curltime *nowp,
2597                                  struct Curl_easy *data)
2598 {
2599   struct Curl_message *msg = NULL;
2600   bool connected;
2601   bool protocol_connected = FALSE;
2602   bool dophase_done = FALSE;
2603   CURLMcode rc;
2604   CURLcode result = CURLE_OK;
2605   int control;
2606 
2607   if(!GOOD_EASY_HANDLE(data))
2608     return CURLM_BAD_EASY_HANDLE;
2609 
2610   if(multi->dead) {
2611     /* a multi-level callback returned error before, meaning every individual
2612      transfer now has failed */
2613     result = CURLE_ABORTED_BY_CALLBACK;
2614     multi_posttransfer(data);
2615     multi_done(data, result, FALSE);
2616     multistate(data, MSTATE_COMPLETED);
2617   }
2618 
2619   multi_warn_debug(multi, data);
2620 
2621   do {
2622     /* A "stream" here is a logical stream if the protocol can handle that
2623        (HTTP/2), or the full connection for older protocols */
2624     bool stream_error = FALSE;
2625     rc = CURLM_OK;
2626 
2627     if(multi_ischanged(multi, TRUE)) {
2628       DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
2629       process_pending_handles(multi); /* multiplexed */
2630     }
2631 
2632     if(data->mstate > MSTATE_CONNECT &&
2633        data->mstate < MSTATE_COMPLETED) {
2634       /* Make sure we set the connection's current owner */
2635       DEBUGASSERT(data->conn);
2636       if(!data->conn)
2637         return CURLM_INTERNAL_ERROR;
2638     }
2639 
2640     /* Wait for the connect state as only then is the start time stored, but
2641        we must not check already completed handles */
2642     if((data->mstate >= MSTATE_CONNECT) && (data->mstate < MSTATE_COMPLETED) &&
2643        multi_handle_timeout(data, nowp, &stream_error, &result))
2644       /* Skip the statemachine and go directly to error handling section. */
2645       goto statemachine_end;
2646 
2647     switch(data->mstate) {
2648     case MSTATE_INIT:
2649       /* Transitional state. init this transfer. A handle never comes back to
2650          this state. */
2651       result = Curl_pretransfer(data);
2652       if(result)
2653         break;
2654 
2655       /* after init, go SETUP */
2656       multistate(data, MSTATE_SETUP);
2657       (void)Curl_pgrsTime(data, TIMER_STARTOP);
2658       FALLTHROUGH();
2659 
2660     case MSTATE_SETUP:
2661       /* Transitional state. Setup things for a new transfer. The handle
2662          can come back to this state on a redirect. */
2663       *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
2664       if(data->set.timeout)
2665         Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
2666       if(data->set.connecttimeout)
2667         /* Since a connection might go to pending and back to CONNECT several
2668            times before it actually takes off, we need to set the timeout once
2669            in SETUP before we enter CONNECT the first time. */
2670         Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
2671 
2672       multistate(data, MSTATE_CONNECT);
2673       FALLTHROUGH();
2674 
2675     case MSTATE_CONNECT:
2676       rc = state_connect(multi, data, nowp, &result);
2677       break;
2678 
2679     case MSTATE_RESOLVING:
2680       /* awaiting an asynch name resolve to complete */
2681       rc = state_resolving(multi, data, &stream_error, &result);
2682       break;
2683 
2684 #ifndef CURL_DISABLE_HTTP
2685     case MSTATE_TUNNELING:
2686       /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
2687       DEBUGASSERT(data->conn);
2688       result = Curl_http_connect(data, &protocol_connected);
2689       if(!result) {
2690         rc = CURLM_CALL_MULTI_PERFORM;
2691         /* initiate protocol connect phase */
2692         multistate(data, MSTATE_PROTOCONNECT);
2693       }
2694       else
2695         stream_error = TRUE;
2696       break;
2697 #endif
2698 
2699     case MSTATE_CONNECTING:
2700       /* awaiting a completion of an asynch TCP connect */
2701       DEBUGASSERT(data->conn);
2702       result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
2703       if(connected && !result) {
2704         if(!data->conn->bits.reuse &&
2705            Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
2706           /* new connection, can multiplex, wake pending handles */
2707           process_pending_handles(data->multi);
2708         }
2709         rc = CURLM_CALL_MULTI_PERFORM;
2710         multistate(data, MSTATE_PROTOCONNECT);
2711       }
2712       else if(result) {
2713         /* failure detected */
2714         multi_posttransfer(data);
2715         multi_done(data, result, TRUE);
2716         stream_error = TRUE;
2717         break;
2718       }
2719       break;
2720 
2721     case MSTATE_PROTOCONNECT:
2722       if(!result && data->conn->bits.reuse) {
2723         /* ftp seems to hang when protoconnect on reused connection since we
2724          * handle PROTOCONNECT in general inside the filers, it seems wrong to
2725          * restart this on a reused connection.
2726          */
2727         multistate(data, MSTATE_DO);
2728         rc = CURLM_CALL_MULTI_PERFORM;
2729         break;
2730       }
2731       if(!result)
2732         result = protocol_connect(data, &protocol_connected);
2733       if(!result && !protocol_connected) {
2734         /* switch to waiting state */
2735         multistate(data, MSTATE_PROTOCONNECTING);
2736         rc = CURLM_CALL_MULTI_PERFORM;
2737       }
2738       else if(!result) {
2739         /* protocol connect has completed, go WAITDO or DO */
2740         multistate(data, MSTATE_DO);
2741         rc = CURLM_CALL_MULTI_PERFORM;
2742       }
2743       else {
2744         /* failure detected */
2745         multi_posttransfer(data);
2746         multi_done(data, result, TRUE);
2747         stream_error = TRUE;
2748       }
2749       break;
2750 
2751     case MSTATE_PROTOCONNECTING:
2752       /* protocol-specific connect phase */
2753       result = protocol_connecting(data, &protocol_connected);
2754       if(!result && protocol_connected) {
2755         /* after the connect has completed, go WAITDO or DO */
2756         multistate(data, MSTATE_DO);
2757         rc = CURLM_CALL_MULTI_PERFORM;
2758       }
2759       else if(result) {
2760         /* failure detected */
2761         multi_posttransfer(data);
2762         multi_done(data, result, TRUE);
2763         stream_error = TRUE;
2764       }
2765       break;
2766 
2767     case MSTATE_DO:
2768       rc = state_do(data, &stream_error, &result);
2769       break;
2770 
2771     case MSTATE_DOING:
2772       /* we continue DOING until the DO phase is complete */
2773       DEBUGASSERT(data->conn);
2774       result = protocol_doing(data, &dophase_done);
2775       if(!result) {
2776         if(dophase_done) {
2777           /* after DO, go DO_DONE or DO_MORE */
2778           multistate(data, data->conn->bits.do_more ?
2779                      MSTATE_DOING_MORE : MSTATE_DID);
2780           rc = CURLM_CALL_MULTI_PERFORM;
2781         } /* dophase_done */
2782       }
2783       else {
2784         /* failure detected */
2785         multi_posttransfer(data);
2786         multi_done(data, result, FALSE);
2787         stream_error = TRUE;
2788       }
2789       break;
2790 
2791     case MSTATE_DOING_MORE:
2792       /*
2793        * When we are connected, DOING MORE and then go DID
2794        */
2795       DEBUGASSERT(data->conn);
2796       result = multi_do_more(data, &control);
2797 
2798       if(!result) {
2799         if(control) {
2800           /* if positive, advance to DO_DONE
2801              if negative, go back to DOING */
2802           multistate(data, control == 1 ?
2803                      MSTATE_DID : MSTATE_DOING);
2804           rc = CURLM_CALL_MULTI_PERFORM;
2805         }
2806         /* else
2807            stay in DO_MORE */
2808       }
2809       else {
2810         /* failure detected */
2811         multi_posttransfer(data);
2812         multi_done(data, result, FALSE);
2813         stream_error = TRUE;
2814       }
2815       break;
2816 
2817     case MSTATE_DID:
2818       DEBUGASSERT(data->conn);
2819       if(data->conn->bits.multiplex)
2820         /* Check if we can move pending requests to send pipe */
2821         process_pending_handles(multi); /*  multiplexed */
2822 
2823       /* Only perform the transfer if there is a good socket to work with.
2824          Having both BAD is a signal to skip immediately to DONE */
2825       if((data->conn->sockfd != CURL_SOCKET_BAD) ||
2826          (data->conn->writesockfd != CURL_SOCKET_BAD))
2827         multistate(data, MSTATE_PERFORMING);
2828       else {
2829 #ifndef CURL_DISABLE_FTP
2830         if(data->state.wildcardmatch &&
2831            ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
2832           data->wildcard->state = CURLWC_DONE;
2833         }
2834 #endif
2835         multistate(data, MSTATE_DONE);
2836       }
2837       rc = CURLM_CALL_MULTI_PERFORM;
2838       break;
2839 
2840     case MSTATE_RATELIMITING: /* limit-rate exceeded in either direction */
2841       rc = state_ratelimiting(data, nowp, &result);
2842       break;
2843 
2844     case MSTATE_PERFORMING:
2845       rc = state_performing(data, nowp, &stream_error, &result);
2846       break;
2847 
2848     case MSTATE_DONE:
2849       /* this state is highly transient, so run another loop after this */
2850       rc = CURLM_CALL_MULTI_PERFORM;
2851 
2852       if(data->conn) {
2853         CURLcode res;
2854 
2855         /* post-transfer command */
2856         res = multi_done(data, result, FALSE);
2857 
2858         /* allow a previously set error code take precedence */
2859         if(!result)
2860           result = res;
2861       }
2862 
2863 #ifndef CURL_DISABLE_FTP
2864       if(data->state.wildcardmatch) {
2865         if(data->wildcard->state != CURLWC_DONE) {
2866           /* if a wildcard is set and we are not ending -> lets start again
2867              with MSTATE_INIT */
2868           multistate(data, MSTATE_INIT);
2869           break;
2870         }
2871       }
2872 #endif
2873       /* after we have DONE what we are supposed to do, go COMPLETED, and
2874          it does not matter what the multi_done() returned! */
2875       multistate(data, MSTATE_COMPLETED);
2876       break;
2877 
2878     case MSTATE_COMPLETED:
2879       break;
2880 
2881     case MSTATE_PENDING:
2882     case MSTATE_MSGSENT:
2883       /* handles in these states should NOT be in this list */
2884       DEBUGASSERT(0);
2885       break;
2886 
2887     default:
2888       return CURLM_INTERNAL_ERROR;
2889     }
2890 
2891     if(data->mstate >= MSTATE_CONNECT &&
2892        data->mstate < MSTATE_DO &&
2893        rc != CURLM_CALL_MULTI_PERFORM &&
2894        !multi_ischanged(multi, FALSE)) {
2895       /* We now handle stream timeouts if and only if this will be the last
2896        * loop iteration. We only check this on the last iteration to ensure
2897        * that if we know we have additional work to do immediately
2898        * (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before
2899        * declaring the connection timed out as we may almost have a completed
2900        * connection. */
2901       multi_handle_timeout(data, nowp, &stream_error, &result);
2902     }
2903 
2904 statemachine_end:
2905 
2906     if(data->mstate < MSTATE_COMPLETED) {
2907       if(result) {
2908         /*
2909          * If an error was returned, and we are not in completed state now,
2910          * then we go to completed and consider this transfer aborted.
2911          */
2912 
2913         /* NOTE: no attempt to disconnect connections must be made
2914            in the case blocks above - cleanup happens only here */
2915 
2916         /* Check if we can move pending requests to send pipe */
2917         process_pending_handles(multi); /* connection */
2918 
2919         if(data->conn) {
2920           if(stream_error) {
2921             /* Do not attempt to send data over a connection that timed out */
2922             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2923             struct connectdata *conn = data->conn;
2924 
2925             /* This is where we make sure that the conn pointer is reset.
2926                We do not have to do this in every case block above where a
2927                failure is detected */
2928             Curl_detach_connection(data);
2929             Curl_cpool_disconnect(data, conn, dead_connection);
2930           }
2931         }
2932         else if(data->mstate == MSTATE_CONNECT) {
2933           /* Curl_connect() failed */
2934           multi_posttransfer(data);
2935           Curl_pgrsUpdate_nometer(data);
2936         }
2937 
2938         multistate(data, MSTATE_COMPLETED);
2939         rc = CURLM_CALL_MULTI_PERFORM;
2940       }
2941       /* if there is still a connection to use, call the progress function */
2942       else if(data->conn && Curl_pgrsUpdate(data)) {
2943         /* aborted due to progress callback return code must close the
2944            connection */
2945         result = CURLE_ABORTED_BY_CALLBACK;
2946         streamclose(data->conn, "Aborted by callback");
2947 
2948         /* if not yet in DONE state, go there, otherwise COMPLETED */
2949         multistate(data, (data->mstate < MSTATE_DONE) ?
2950                    MSTATE_DONE : MSTATE_COMPLETED);
2951         rc = CURLM_CALL_MULTI_PERFORM;
2952       }
2953     }
2954 
2955     if(MSTATE_COMPLETED == data->mstate) {
2956       if(data->set.fmultidone) {
2957         /* signal via callback instead */
2958         data->set.fmultidone(data, result);
2959       }
2960       else {
2961         /* now fill in the Curl_message with this info */
2962         msg = &data->msg;
2963 
2964         msg->extmsg.msg = CURLMSG_DONE;
2965         msg->extmsg.easy_handle = data;
2966         msg->extmsg.data.result = result;
2967 
2968         multi_addmsg(multi, msg);
2969         DEBUGASSERT(!data->conn);
2970       }
2971       multistate(data, MSTATE_MSGSENT);
2972 
2973       /* unlink from the process list */
2974       Curl_node_remove(&data->multi_queue);
2975       /* add this handle msgsent list */
2976       Curl_llist_append(&multi->msgsent, data, &data->multi_queue);
2977       return CURLM_OK;
2978     }
2979   } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2980 
2981   data->result = result;
2982   return rc;
2983 }
2984 
2985 
2986 CURLMcode curl_multi_perform(CURLM *m, int *running_handles)
2987 {
2988   CURLMcode returncode = CURLM_OK;
2989   struct Curl_tree *t = NULL;
2990   struct curltime now = Curl_now();
2991   struct Curl_llist_node *e;
2992   struct Curl_llist_node *n = NULL;
2993   struct Curl_multi *multi = m;
2994   SIGPIPE_VARIABLE(pipe_st);
2995 
2996   if(!GOOD_MULTI_HANDLE(multi))
2997     return CURLM_BAD_HANDLE;
2998 
2999   if(multi->in_callback)
3000     return CURLM_RECURSIVE_API_CALL;
3001 
3002   sigpipe_init(&pipe_st);
3003   for(e = Curl_llist_head(&multi->process); e; e = n) {
3004     struct Curl_easy *data = Curl_node_elem(e);
3005     CURLMcode result;
3006     /* Do the loop and only alter the signal ignore state if the next handle
3007        has a different NO_SIGNAL state than the previous */
3008 
3009     /* the current node might be unlinked in multi_runsingle(), get the next
3010        pointer now */
3011     n = Curl_node_next(e);
3012 
3013     if(data != multi->cpool.idata) {
3014       /* connection pool handle is processed below */
3015       sigpipe_apply(data, &pipe_st);
3016       result = multi_runsingle(multi, &now, data);
3017       if(result)
3018         returncode = result;
3019     }
3020   }
3021 
3022   sigpipe_apply(multi->cpool.idata, &pipe_st);
3023   Curl_cpool_multi_perform(multi);
3024 
3025   sigpipe_restore(&pipe_st);
3026 
3027   /*
3028    * Simply remove all expired timers from the splay since handles are dealt
3029    * with unconditionally by this function and curl_multi_timeout() requires
3030    * that already passed/handled expire times are removed from the splay.
3031    *
3032    * It is important that the 'now' value is set at the entry of this function
3033    * and not for the current time as it may have ticked a little while since
3034    * then and then we risk this loop to remove timers that actually have not
3035    * been handled!
3036    */
3037   do {
3038     multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3039     if(t) {
3040       /* the removed may have another timeout in queue */
3041       struct Curl_easy *data = Curl_splayget(t);
3042       if(data->mstate == MSTATE_PENDING) {
3043         bool stream_unused;
3044         CURLcode result_unused;
3045         if(multi_handle_timeout(data, &now, &stream_unused, &result_unused)) {
3046           infof(data, "PENDING handle timeout");
3047           move_pending_to_connect(multi, data);
3048         }
3049       }
3050       (void)add_next_timeout(now, multi, Curl_splayget(t));
3051     }
3052   } while(t);
3053 
3054   if(running_handles)
3055     *running_handles = (int)multi->num_alive;
3056 
3057   if(CURLM_OK >= returncode)
3058     returncode = Curl_update_timer(multi);
3059 
3060   return returncode;
3061 }
3062 
3063 /* unlink_all_msgsent_handles() moves all nodes back from the msgsent list to
3064    the process list */
3065 static void unlink_all_msgsent_handles(struct Curl_multi *multi)
3066 {
3067   struct Curl_llist_node *e;
3068   for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) {
3069     struct Curl_easy *data = Curl_node_elem(e);
3070     if(data) {
3071       DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
3072       Curl_node_remove(&data->multi_queue);
3073       /* put it into the process list */
3074       Curl_llist_append(&multi->process, data, &data->multi_queue);
3075     }
3076   }
3077 }
3078 
3079 CURLMcode curl_multi_cleanup(CURLM *m)
3080 {
3081   struct Curl_multi *multi = m;
3082   if(GOOD_MULTI_HANDLE(multi)) {
3083     struct Curl_llist_node *e;
3084     struct Curl_llist_node *n;
3085     if(multi->in_callback)
3086       return CURLM_RECURSIVE_API_CALL;
3087 
3088     /* move the pending and msgsent entries back to process
3089        so that there is just one list to iterate over */
3090     unlink_all_msgsent_handles(multi);
3091     process_pending_handles(multi);
3092 
3093     /* First remove all remaining easy handles */
3094     for(e = Curl_llist_head(&multi->process); e; e = n) {
3095       struct Curl_easy *data = Curl_node_elem(e);
3096 
3097       if(!GOOD_EASY_HANDLE(data))
3098         return CURLM_BAD_HANDLE;
3099 
3100       n = Curl_node_next(e);
3101       if(!data->state.done && data->conn)
3102         /* if DONE was never called for this handle */
3103         (void)multi_done(data, CURLE_OK, TRUE);
3104       if(data->dns.hostcachetype == HCACHE_MULTI) {
3105         /* clear out the usage of the shared DNS cache */
3106         Curl_hostcache_clean(data, data->dns.hostcache);
3107         data->dns.hostcache = NULL;
3108         data->dns.hostcachetype = HCACHE_NONE;
3109       }
3110 
3111       data->multi = NULL; /* clear the association */
3112 
3113 #ifdef USE_LIBPSL
3114       if(data->psl == &multi->psl)
3115         data->psl = NULL;
3116 #endif
3117     }
3118 
3119     Curl_cpool_destroy(&multi->cpool);
3120 
3121     multi->magic = 0; /* not good anymore */
3122 
3123     sockhash_destroy(&multi->sockhash);
3124     Curl_hash_destroy(&multi->proto_hash);
3125     Curl_hash_destroy(&multi->hostcache);
3126     Curl_psl_destroy(&multi->psl);
3127 
3128 #ifdef USE_WINSOCK
3129     WSACloseEvent(multi->wsa_event);
3130 #else
3131 #ifdef ENABLE_WAKEUP
3132     wakeup_close(multi->wakeup_pair[0]);
3133 #ifndef USE_EVENTFD
3134     wakeup_close(multi->wakeup_pair[1]);
3135 #endif
3136 #endif
3137 #endif
3138 
3139     multi_xfer_bufs_free(multi);
3140     free(multi);
3141 
3142     return CURLM_OK;
3143   }
3144   return CURLM_BAD_HANDLE;
3145 }
3146 
3147 /*
3148  * curl_multi_info_read()
3149  *
3150  * This function is the primary way for a multi/multi_socket application to
3151  * figure out if a transfer has ended. We MUST make this function as fast as
3152  * possible as it will be polled frequently and we MUST NOT scan any lists in
3153  * here to figure out things. We must scale fine to thousands of handles and
3154  * beyond. The current design is fully O(1).
3155  */
3156 
3157 CURLMsg *curl_multi_info_read(CURLM *m, int *msgs_in_queue)
3158 {
3159   struct Curl_message *msg;
3160   struct Curl_multi *multi = m;
3161 
3162   *msgs_in_queue = 0; /* default to none */
3163 
3164   if(GOOD_MULTI_HANDLE(multi) &&
3165      !multi->in_callback &&
3166      Curl_llist_count(&multi->msglist)) {
3167     /* there is one or more messages in the list */
3168     struct Curl_llist_node *e;
3169 
3170     /* extract the head of the list to return */
3171     e = Curl_llist_head(&multi->msglist);
3172 
3173     msg = Curl_node_elem(e);
3174 
3175     /* remove the extracted entry */
3176     Curl_node_remove(e);
3177 
3178     *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
3179 
3180     return &msg->extmsg;
3181   }
3182   return NULL;
3183 }
3184 
3185 /*
3186  * singlesocket() checks what sockets we deal with and their "action state"
3187  * and if we have a different state in any of those sockets from last time we
3188  * call the callback accordingly.
3189  */
3190 static CURLMcode singlesocket(struct Curl_multi *multi,
3191                               struct Curl_easy *data)
3192 {
3193   struct easy_pollset cur_poll;
3194   CURLMcode mresult;
3195 
3196   /* Fill in the 'current' struct with the state as it is now: what sockets to
3197      supervise and for what actions */
3198   multi_getsock(data, &cur_poll);
3199   mresult = Curl_multi_pollset_ev(multi, data, &cur_poll, &data->last_poll);
3200 
3201   if(!mresult) /* Remember for next time */
3202     memcpy(&data->last_poll, &cur_poll, sizeof(cur_poll));
3203   return mresult;
3204 }
3205 
3206 CURLMcode Curl_multi_pollset_ev(struct Curl_multi *multi,
3207                                 struct Curl_easy *data,
3208                                 struct easy_pollset *ps,
3209                                 struct easy_pollset *last_ps)
3210 {
3211   unsigned int i;
3212   struct Curl_sh_entry *entry;
3213   curl_socket_t s;
3214   int rc;
3215 
3216   /* We have 0 .. N sockets already and we get to know about the 0 .. M
3217      sockets we should have from now on. Detect the differences, remove no
3218      longer supervised ones and add new ones */
3219 
3220   /* walk over the sockets we got right now */
3221   for(i = 0; i < ps->num; i++) {
3222     unsigned char cur_action = ps->actions[i];
3223     unsigned char last_action = 0;
3224     int comboaction;
3225 
3226     s = ps->sockets[i];
3227 
3228     /* get it from the hash */
3229     entry = sh_getentry(&multi->sockhash, s);
3230     if(entry) {
3231       /* check if new for this transfer */
3232       unsigned int j;
3233       for(j = 0; j < last_ps->num; j++) {
3234         if(s == last_ps->sockets[j]) {
3235           last_action = last_ps->actions[j];
3236           break;
3237         }
3238       }
3239     }
3240     else {
3241       /* this is a socket we did not have before, add it to the hash! */
3242       entry = sh_addentry(&multi->sockhash, s);
3243       if(!entry)
3244         /* fatal */
3245         return CURLM_OUT_OF_MEMORY;
3246     }
3247     if(last_action && (last_action != cur_action)) {
3248       /* Socket was used already, but different action now */
3249       if(last_action & CURL_POLL_IN) {
3250         DEBUGASSERT(entry->readers);
3251         entry->readers--;
3252       }
3253       if(last_action & CURL_POLL_OUT) {
3254         DEBUGASSERT(entry->writers);
3255         entry->writers--;
3256       }
3257       if(cur_action & CURL_POLL_IN) {
3258         entry->readers++;
3259       }
3260       if(cur_action & CURL_POLL_OUT)
3261         entry->writers++;
3262     }
3263     else if(!last_action &&
3264             !Curl_hash_pick(&entry->transfers, (char *)&data, /* hash key */
3265                             sizeof(struct Curl_easy *))) {
3266       DEBUGASSERT(entry->users < 100000); /* detect weird values */
3267       /* a new transfer using this socket */
3268       entry->users++;
3269       if(cur_action & CURL_POLL_IN)
3270         entry->readers++;
3271       if(cur_action & CURL_POLL_OUT)
3272         entry->writers++;
3273       /* add 'data' to the transfer hash on this socket! */
3274       if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
3275                         sizeof(struct Curl_easy *), data)) {
3276         Curl_hash_destroy(&entry->transfers);
3277         return CURLM_OUT_OF_MEMORY;
3278       }
3279     }
3280 
3281     comboaction = (entry->writers ? CURL_POLL_OUT : 0) |
3282                    (entry->readers ? CURL_POLL_IN : 0);
3283 
3284     /* socket existed before and has the same action set as before */
3285     if(last_action && ((int)entry->action == comboaction))
3286       /* same, continue */
3287       continue;
3288 
3289     if(multi->socket_cb) {
3290       set_in_callback(multi, TRUE);
3291       rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
3292                             entry->socketp);
3293 
3294       set_in_callback(multi, FALSE);
3295       if(rc == -1) {
3296         multi->dead = TRUE;
3297         return CURLM_ABORTED_BY_CALLBACK;
3298       }
3299     }
3300 
3301     /* store the current action state */
3302     entry->action = (unsigned int)comboaction;
3303   }
3304 
3305   /* Check for last_poll.sockets that no longer appear in ps->sockets.
3306    * Need to remove the easy handle from the multi->sockhash->transfers and
3307    * remove multi->sockhash entry when this was the last transfer */
3308   for(i = 0; i < last_ps->num; i++) {
3309     unsigned int j;
3310     bool stillused = FALSE;
3311     s = last_ps->sockets[i];
3312     for(j = 0; j < ps->num; j++) {
3313       if(s == ps->sockets[j]) {
3314         /* this is still supervised */
3315         stillused = TRUE;
3316         break;
3317       }
3318     }
3319     if(stillused)
3320       continue;
3321 
3322     entry = sh_getentry(&multi->sockhash, s);
3323     /* if this is NULL here, the socket has been closed and notified so
3324        already by Curl_multi_closed() */
3325     if(entry) {
3326       unsigned char oldactions = last_ps->actions[i];
3327       /* this socket has been removed. Decrease user count */
3328       DEBUGASSERT(entry->users);
3329       entry->users--;
3330       if(oldactions & CURL_POLL_OUT)
3331         entry->writers--;
3332       if(oldactions & CURL_POLL_IN)
3333         entry->readers--;
3334       if(!entry->users) {
3335         bool dead = FALSE;
3336         if(multi->socket_cb) {
3337           set_in_callback(multi, TRUE);
3338           rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3339                                 multi->socket_userp, entry->socketp);
3340           set_in_callback(multi, FALSE);
3341           if(rc == -1)
3342             dead = TRUE;
3343         }
3344         sh_delentry(entry, &multi->sockhash, s);
3345         if(dead) {
3346           multi->dead = TRUE;
3347           return CURLM_ABORTED_BY_CALLBACK;
3348         }
3349       }
3350       else {
3351         /* still users, but remove this handle as a user of this socket */
3352         if(Curl_hash_delete(&entry->transfers, (char *)&data,
3353                             sizeof(struct Curl_easy *))) {
3354           DEBUGASSERT(NULL);
3355         }
3356       }
3357     }
3358   } /* for loop over num */
3359 
3360   return CURLM_OK;
3361 }
3362 
3363 CURLcode Curl_updatesocket(struct Curl_easy *data)
3364 {
3365   if(singlesocket(data->multi, data))
3366     return CURLE_ABORTED_BY_CALLBACK;
3367   return CURLE_OK;
3368 }
3369 
3370 
3371 /*
3372  * Curl_multi_closed()
3373  *
3374  * Used by the connect code to tell the multi_socket code that one of the
3375  * sockets we were using is about to be closed. This function will then
3376  * remove it from the sockethash for this handle to make the multi_socket API
3377  * behave properly, especially for the case when libcurl will create another
3378  * socket again and it gets the same file descriptor number.
3379  */
3380 
3381 void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
3382 {
3383   if(data) {
3384     /* if there is still an easy handle associated with this connection */
3385     struct Curl_multi *multi = data->multi;
3386     DEBUGF(infof(data, "Curl_multi_closed, fd=%" FMT_SOCKET_T
3387                  " multi is %p", s, (void *)multi));
3388     if(multi) {
3389       /* this is set if this connection is part of a handle that is added to
3390          a multi handle, and only then this is necessary */
3391       struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3392 
3393       DEBUGF(infof(data, "Curl_multi_closed, fd=%" FMT_SOCKET_T
3394                    " entry is %p", s, (void *)entry));
3395       if(entry) {
3396         int rc = 0;
3397         if(multi->socket_cb) {
3398           set_in_callback(multi, TRUE);
3399           rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3400                                 multi->socket_userp, entry->socketp);
3401           set_in_callback(multi, FALSE);
3402         }
3403 
3404         /* now remove it from the socket hash */
3405         sh_delentry(entry, &multi->sockhash, s);
3406         if(rc == -1)
3407           /* This just marks the multi handle as "dead" without returning an
3408              error code primarily because this function is used from many
3409              places where propagating an error back is tricky. */
3410           multi->dead = TRUE;
3411       }
3412     }
3413   }
3414 }
3415 
3416 /*
3417  * add_next_timeout()
3418  *
3419  * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
3420  * when it has just been removed from the splay tree because the timeout has
3421  * expired. This function is then to advance in the list to pick the next
3422  * timeout to use (skip the already expired ones) and add this node back to
3423  * the splay tree again.
3424  *
3425  * The splay tree only has each sessionhandle as a single node and the nearest
3426  * timeout is used to sort it on.
3427  */
3428 static CURLMcode add_next_timeout(struct curltime now,
3429                                   struct Curl_multi *multi,
3430                                   struct Curl_easy *d)
3431 {
3432   struct curltime *tv = &d->state.expiretime;
3433   struct Curl_llist *list = &d->state.timeoutlist;
3434   struct Curl_llist_node *e;
3435 
3436   /* move over the timeout list for this specific handle and remove all
3437      timeouts that are now passed tense and store the next pending
3438      timeout in *tv */
3439   for(e = Curl_llist_head(list); e;) {
3440     struct Curl_llist_node *n = Curl_node_next(e);
3441     struct time_node *node = Curl_node_elem(e);
3442     timediff_t diff = Curl_timediff_us(node->time, now);
3443     if(diff <= 0)
3444       /* remove outdated entry */
3445       Curl_node_remove(e);
3446     else
3447       /* the list is sorted so get out on the first mismatch */
3448       break;
3449     e = n;
3450   }
3451   e = Curl_llist_head(list);
3452   if(!e) {
3453     /* clear the expire times within the handles that we remove from the
3454        splay tree */
3455     tv->tv_sec = 0;
3456     tv->tv_usec = 0;
3457   }
3458   else {
3459     struct time_node *node = Curl_node_elem(e);
3460     /* copy the first entry to 'tv' */
3461     memcpy(tv, &node->time, sizeof(*tv));
3462 
3463     /* Insert this node again into the splay. Keep the timer in the list in
3464        case we need to recompute future timers. */
3465     multi->timetree = Curl_splayinsert(*tv, multi->timetree,
3466                                        &d->state.timenode);
3467   }
3468   return CURLM_OK;
3469 }
3470 
3471 struct multi_run_ctx {
3472   struct Curl_multi *multi;
3473   struct curltime now;
3474   size_t run_xfers;
3475   SIGPIPE_MEMBER(pipe_st);
3476   bool run_cpool;
3477 };
3478 
3479 static CURLMcode multi_run_expired(struct multi_run_ctx *mrc)
3480 {
3481   struct Curl_multi *multi = mrc->multi;
3482   struct Curl_easy *data = NULL;
3483   struct Curl_tree *t = NULL;
3484   CURLMcode result = CURLM_OK;
3485 
3486   /*
3487    * The loop following here will go on as long as there are expire-times left
3488    * to process (compared to mrc->now) in the splay and 'data' will be
3489    * re-assigned for every expired handle we deal with.
3490    */
3491   while(1) {
3492     /* Check if there is one (more) expired timer to deal with! This function
3493        extracts a matching node if there is one */
3494     multi->timetree = Curl_splaygetbest(mrc->now, multi->timetree, &t);
3495     if(!t)
3496       goto out;
3497 
3498     data = Curl_splayget(t); /* assign this for next loop */
3499     if(!data)
3500       continue;
3501 
3502     (void)add_next_timeout(mrc->now, multi, data);
3503     if(data == multi->cpool.idata) {
3504       mrc->run_cpool = TRUE;
3505       continue;
3506     }
3507 
3508     mrc->run_xfers++;
3509     sigpipe_apply(data, &mrc->pipe_st);
3510     result = multi_runsingle(multi, &mrc->now, data);
3511 
3512     if(CURLM_OK >= result) {
3513       /* get the socket(s) and check if the state has been changed since
3514          last */
3515       result = singlesocket(multi, data);
3516       if(result)
3517         goto out;
3518     }
3519   }
3520 
3521 out:
3522   return result;
3523 }
3524 static CURLMcode multi_socket(struct Curl_multi *multi,
3525                               bool checkall,
3526                               curl_socket_t s,
3527                               int ev_bitmask,
3528                               int *running_handles)
3529 {
3530   CURLMcode result = CURLM_OK;
3531   struct Curl_easy *data = NULL;
3532   struct multi_run_ctx mrc;
3533 
3534   (void)ev_bitmask;
3535   memset(&mrc, 0, sizeof(mrc));
3536   mrc.multi = multi;
3537   mrc.now = Curl_now();
3538   sigpipe_init(&mrc.pipe_st);
3539 
3540   if(checkall) {
3541     struct Curl_llist_node *e;
3542     /* *perform() deals with running_handles on its own */
3543     result = curl_multi_perform(multi, running_handles);
3544 
3545     /* walk through each easy handle and do the socket state change magic
3546        and callbacks */
3547     if(result != CURLM_BAD_HANDLE) {
3548       for(e = Curl_llist_head(&multi->process); e && !result;
3549           e = Curl_node_next(e)) {
3550         result = singlesocket(multi, Curl_node_elem(e));
3551       }
3552     }
3553     mrc.run_cpool = TRUE;
3554     goto out;
3555   }
3556 
3557   if(s != CURL_SOCKET_TIMEOUT) {
3558     struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3559 
3560     if(!entry) {
3561       /* Unmatched socket, we cannot act on it but we ignore this fact. In
3562          real-world tests it has been proved that libevent can in fact give
3563          the application actions even though the socket was just previously
3564          asked to get removed, so thus we better survive stray socket actions
3565          and just move on. */
3566       /* The socket might come from a connection that is being shut down
3567        * by the multi's connection pool. */
3568       Curl_cpool_multi_socket(multi, s, ev_bitmask);
3569     }
3570     else {
3571       struct Curl_hash_iterator iter;
3572       struct Curl_hash_element *he;
3573 
3574       /* the socket can be shared by many transfers, iterate */
3575       Curl_hash_start_iterate(&entry->transfers, &iter);
3576       for(he = Curl_hash_next_element(&iter); he;
3577           he = Curl_hash_next_element(&iter)) {
3578         data = (struct Curl_easy *)he->ptr;
3579         DEBUGASSERT(data);
3580         DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
3581 
3582         if(data == multi->cpool.idata)
3583           mrc.run_cpool = TRUE;
3584         else {
3585           /* Expire with out current now, so we will get it below when
3586            * asking the splaytree for expired transfers. */
3587           expire_ex(data, &mrc.now, 0, EXPIRE_RUN_NOW);
3588         }
3589       }
3590     }
3591   }
3592 
3593   result = multi_run_expired(&mrc);
3594   if(result)
3595     goto out;
3596 
3597   if(mrc.run_xfers) {
3598     /* Running transfers takes time. With a new timestamp, we might catch
3599      * other expires which are due now. Instead of telling the application
3600      * to set a 0 timeout and call us again, we run them here.
3601      * Do that only once or it might be unfair to transfers on other
3602      * sockets. */
3603     mrc.now = Curl_now();
3604     result = multi_run_expired(&mrc);
3605   }
3606 
3607 out:
3608   if(mrc.run_cpool) {
3609     sigpipe_apply(multi->cpool.idata, &mrc.pipe_st);
3610     Curl_cpool_multi_perform(multi);
3611   }
3612   sigpipe_restore(&mrc.pipe_st);
3613 
3614   if(running_handles)
3615     *running_handles = (int)multi->num_alive;
3616 
3617   if(CURLM_OK >= result)
3618     result = Curl_update_timer(multi);
3619   return result;
3620 }
3621 
3622 #undef curl_multi_setopt
3623 CURLMcode curl_multi_setopt(CURLM *m,
3624                             CURLMoption option, ...)
3625 {
3626   CURLMcode res = CURLM_OK;
3627   va_list param;
3628   unsigned long uarg;
3629   struct Curl_multi *multi = m;
3630 
3631   if(!GOOD_MULTI_HANDLE(multi))
3632     return CURLM_BAD_HANDLE;
3633 
3634   if(multi->in_callback)
3635     return CURLM_RECURSIVE_API_CALL;
3636 
3637   va_start(param, option);
3638 
3639   switch(option) {
3640   case CURLMOPT_SOCKETFUNCTION:
3641     multi->socket_cb = va_arg(param, curl_socket_callback);
3642     break;
3643   case CURLMOPT_SOCKETDATA:
3644     multi->socket_userp = va_arg(param, void *);
3645     break;
3646   case CURLMOPT_PUSHFUNCTION:
3647     multi->push_cb = va_arg(param, curl_push_callback);
3648     break;
3649   case CURLMOPT_PUSHDATA:
3650     multi->push_userp = va_arg(param, void *);
3651     break;
3652   case CURLMOPT_PIPELINING:
3653     multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0;
3654     break;
3655   case CURLMOPT_TIMERFUNCTION:
3656     multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3657     break;
3658   case CURLMOPT_TIMERDATA:
3659     multi->timer_userp = va_arg(param, void *);
3660     break;
3661   case CURLMOPT_MAXCONNECTS:
3662     uarg = va_arg(param, unsigned long);
3663     if(uarg <= UINT_MAX)
3664       multi->maxconnects = (unsigned int)uarg;
3665     break;
3666   case CURLMOPT_MAX_HOST_CONNECTIONS:
3667     multi->max_host_connections = va_arg(param, long);
3668     break;
3669   case CURLMOPT_MAX_TOTAL_CONNECTIONS:
3670     multi->max_total_connections = va_arg(param, long);
3671     /* for now, let this also decide the max number of connections
3672      * in shutdown handling */
3673     multi->max_shutdown_connections = va_arg(param, long);
3674     break;
3675     /* options formerly used for pipelining */
3676   case CURLMOPT_MAX_PIPELINE_LENGTH:
3677     break;
3678   case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
3679     break;
3680   case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
3681     break;
3682   case CURLMOPT_PIPELINING_SITE_BL:
3683     break;
3684   case CURLMOPT_PIPELINING_SERVER_BL:
3685     break;
3686   case CURLMOPT_MAX_CONCURRENT_STREAMS:
3687     {
3688       long streams = va_arg(param, long);
3689       if((streams < 1) || (streams > INT_MAX))
3690         streams = 100;
3691       multi->max_concurrent_streams = (unsigned int)streams;
3692     }
3693     break;
3694   default:
3695     res = CURLM_UNKNOWN_OPTION;
3696     break;
3697   }
3698   va_end(param);
3699   return res;
3700 }
3701 
3702 /* we define curl_multi_socket() in the public multi.h header */
3703 #undef curl_multi_socket
3704 
3705 CURLMcode curl_multi_socket(CURLM *m, curl_socket_t s, int *running_handles)
3706 {
3707   struct Curl_multi *multi = m;
3708   if(multi->in_callback)
3709     return CURLM_RECURSIVE_API_CALL;
3710   return multi_socket(multi, FALSE, s, 0, running_handles);
3711 }
3712 
3713 CURLMcode curl_multi_socket_action(CURLM *m, curl_socket_t s,
3714                                    int ev_bitmask, int *running_handles)
3715 {
3716   struct Curl_multi *multi = m;
3717   if(multi->in_callback)
3718     return CURLM_RECURSIVE_API_CALL;
3719   return multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3720 }
3721 
3722 CURLMcode curl_multi_socket_all(CURLM *m, int *running_handles)
3723 {
3724   struct Curl_multi *multi = m;
3725   if(multi->in_callback)
3726     return CURLM_RECURSIVE_API_CALL;
3727   return multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3728 }
3729 
3730 static CURLMcode multi_timeout(struct Curl_multi *multi,
3731                                struct curltime *expire_time,
3732                                long *timeout_ms)
3733 {
3734   static const struct curltime tv_zero = {0, 0};
3735 
3736   if(multi->dead) {
3737     *timeout_ms = 0;
3738     return CURLM_OK;
3739   }
3740 
3741   if(multi->timetree) {
3742     /* we have a tree of expire times */
3743     struct curltime now = Curl_now();
3744 
3745     /* splay the lowest to the bottom */
3746     multi->timetree = Curl_splay(tv_zero, multi->timetree);
3747     /* this will not return NULL from a non-emtpy tree, but some compilers
3748      * are not convinced of that. Analyzers are hard. */
3749     *expire_time = multi->timetree ? multi->timetree->key : tv_zero;
3750 
3751     /* 'multi->timetree' will be non-NULL here but the compilers sometimes
3752        yell at us if we assume so */
3753     if(multi->timetree &&
3754        Curl_timediff_us(multi->timetree->key, now) > 0) {
3755       /* some time left before expiration */
3756       timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now);
3757       /* this should be safe even on 32-bit archs, as we do not use that
3758          overly long timeouts */
3759       *timeout_ms = (long)diff;
3760     }
3761     else {
3762       /* 0 means immediately */
3763       *timeout_ms = 0;
3764     }
3765   }
3766   else {
3767     *expire_time = tv_zero;
3768     *timeout_ms = -1;
3769   }
3770 
3771   return CURLM_OK;
3772 }
3773 
3774 CURLMcode curl_multi_timeout(CURLM *m,
3775                              long *timeout_ms)
3776 {
3777   struct curltime expire_time;
3778   struct Curl_multi *multi = m;
3779 
3780   /* First, make some basic checks that the CURLM handle is a good handle */
3781   if(!GOOD_MULTI_HANDLE(multi))
3782     return CURLM_BAD_HANDLE;
3783 
3784   if(multi->in_callback)
3785     return CURLM_RECURSIVE_API_CALL;
3786 
3787   return multi_timeout(multi, &expire_time, timeout_ms);
3788 }
3789 
3790 #define DEBUG_UPDATE_TIMER    0
3791 
3792 /*
3793  * Tell the application it should update its timers, if it subscribes to the
3794  * update timer callback.
3795  */
3796 CURLMcode Curl_update_timer(struct Curl_multi *multi)
3797 {
3798   struct curltime expire_ts;
3799   long timeout_ms;
3800   int rc;
3801   bool set_value = FALSE;
3802 
3803   if(!multi->timer_cb || multi->dead)
3804     return CURLM_OK;
3805   if(multi_timeout(multi, &expire_ts, &timeout_ms)) {
3806     return CURLM_OK;
3807   }
3808 
3809   if(timeout_ms < 0 && multi->last_timeout_ms < 0) {
3810 #if DEBUG_UPDATE_TIMER
3811     fprintf(stderr, "Curl_update_timer(), still no timeout, no change\n");
3812 #endif
3813   }
3814   else if(timeout_ms < 0) {
3815     /* there is no timeout now but there was one previously */
3816 #if DEBUG_UPDATE_TIMER
3817     fprintf(stderr, "Curl_update_timer(), remove timeout, "
3818         " last_timeout=%ldms\n", multi->last_timeout_ms);
3819 #endif
3820     timeout_ms = -1; /* normalize */
3821     set_value = TRUE;
3822   }
3823   else if(multi->last_timeout_ms < 0) {
3824 #if DEBUG_UPDATE_TIMER
3825     fprintf(stderr, "Curl_update_timer(), had no timeout, set now\n");
3826 #endif
3827     set_value = TRUE;
3828   }
3829   else if(Curl_timediff_us(multi->last_expire_ts, expire_ts)) {
3830     /* We had a timeout before and have one now, the absolute timestamp
3831      * differs. The relative timeout_ms may be the same, but the starting
3832      * point differs. Let the application restart its timer. */
3833 #if DEBUG_UPDATE_TIMER
3834     fprintf(stderr, "Curl_update_timer(), expire timestamp changed\n");
3835 #endif
3836     set_value = TRUE;
3837   }
3838   else {
3839     /* We have same expire time as previously. Our relative 'timeout_ms'
3840      * may be different now, but the application has the timer running
3841      * and we do not to tell it to start this again. */
3842 #if DEBUG_UPDATE_TIMER
3843     fprintf(stderr, "Curl_update_timer(), same expire timestamp, no change\n");
3844 #endif
3845   }
3846 
3847   if(set_value) {
3848 #if DEBUG_UPDATE_TIMER
3849     fprintf(stderr, "Curl_update_timer(), set timeout %ldms\n", timeout_ms);
3850 #endif
3851     multi->last_expire_ts = expire_ts;
3852     multi->last_timeout_ms = timeout_ms;
3853     set_in_callback(multi, TRUE);
3854     rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3855     set_in_callback(multi, FALSE);
3856     if(rc == -1) {
3857       multi->dead = TRUE;
3858       return CURLM_ABORTED_BY_CALLBACK;
3859     }
3860   }
3861   return CURLM_OK;
3862 }
3863 
3864 /*
3865  * multi_deltimeout()
3866  *
3867  * Remove a given timestamp from the list of timeouts.
3868  */
3869 static void
3870 multi_deltimeout(struct Curl_easy *data, expire_id eid)
3871 {
3872   struct Curl_llist_node *e;
3873   struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3874   /* find and remove the specific node from the list */
3875   for(e = Curl_llist_head(timeoutlist); e; e = Curl_node_next(e)) {
3876     struct time_node *n = Curl_node_elem(e);
3877     if(n->eid == eid) {
3878       Curl_node_remove(e);
3879       return;
3880     }
3881   }
3882 }
3883 
3884 /*
3885  * multi_addtimeout()
3886  *
3887  * Add a timestamp to the list of timeouts. Keep the list sorted so that head
3888  * of list is always the timeout nearest in time.
3889  *
3890  */
3891 static CURLMcode
3892 multi_addtimeout(struct Curl_easy *data,
3893                  struct curltime *stamp,
3894                  expire_id eid)
3895 {
3896   struct Curl_llist_node *e;
3897   struct time_node *node;
3898   struct Curl_llist_node *prev = NULL;
3899   size_t n;
3900   struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3901 
3902   node = &data->state.expires[eid];
3903 
3904   /* copy the timestamp and id */
3905   memcpy(&node->time, stamp, sizeof(*stamp));
3906   node->eid = eid; /* also marks it as in use */
3907 
3908   n = Curl_llist_count(timeoutlist);
3909   if(n) {
3910     /* find the correct spot in the list */
3911     for(e = Curl_llist_head(timeoutlist); e; e = Curl_node_next(e)) {
3912       struct time_node *check = Curl_node_elem(e);
3913       timediff_t diff = Curl_timediff(check->time, node->time);
3914       if(diff > 0)
3915         break;
3916       prev = e;
3917     }
3918 
3919   }
3920   /* else
3921      this is the first timeout on the list */
3922 
3923   Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
3924   return CURLM_OK;
3925 }
3926 
3927 static void expire_ex(struct Curl_easy *data,
3928                       const struct curltime *nowp,
3929                       timediff_t milli, expire_id id)
3930 {
3931   struct Curl_multi *multi = data->multi;
3932   struct curltime *curr_expire = &data->state.expiretime;
3933   struct curltime set;
3934 
3935   /* this is only interesting while there is still an associated multi struct
3936      remaining! */
3937   if(!multi)
3938     return;
3939 
3940   DEBUGASSERT(id < EXPIRE_LAST);
3941 
3942   set = *nowp;
3943   set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bits conversion */
3944   set.tv_usec += (int)(milli%1000)*1000;
3945 
3946   if(set.tv_usec >= 1000000) {
3947     set.tv_sec++;
3948     set.tv_usec -= 1000000;
3949   }
3950 
3951   /* Remove any timer with the same id just in case. */
3952   multi_deltimeout(data, id);
3953 
3954   /* Add it to the timer list. It must stay in the list until it has expired
3955      in case we need to recompute the minimum timer later. */
3956   multi_addtimeout(data, &set, id);
3957 
3958   if(curr_expire->tv_sec || curr_expire->tv_usec) {
3959     /* This means that the struct is added as a node in the splay tree.
3960        Compare if the new time is earlier, and only remove-old/add-new if it
3961        is. */
3962     timediff_t diff = Curl_timediff(set, *curr_expire);
3963     int rc;
3964 
3965     if(diff > 0) {
3966       /* The current splay tree entry is sooner than this new expiry time.
3967          We do not need to update our splay tree entry. */
3968       return;
3969     }
3970 
3971     /* Since this is an updated time, we must remove the previous entry from
3972        the splay tree first and then re-add the new value */
3973     rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3974                           &multi->timetree);
3975     if(rc)
3976       infof(data, "Internal error removing splay node = %d", rc);
3977   }
3978 
3979   /* Indicate that we are in the splay tree and insert the new timer expiry
3980      value since it is our local minimum. */
3981   *curr_expire = set;
3982   Curl_splayset(&data->state.timenode, data);
3983   multi->timetree = Curl_splayinsert(*curr_expire, multi->timetree,
3984                                      &data->state.timenode);
3985 }
3986 
3987 /*
3988  * Curl_expire()
3989  *
3990  * given a number of milliseconds from now to use to set the 'act before
3991  * this'-time for the transfer, to be extracted by curl_multi_timeout()
3992  *
3993  * The timeout will be added to a queue of timeouts if it defines a moment in
3994  * time that is later than the current head of queue.
3995  *
3996  * Expire replaces a former timeout using the same id if already set.
3997  */
3998 void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
3999 {
4000   struct curltime now = Curl_now();
4001   expire_ex(data, &now, milli, id);
4002 }
4003 
4004 /*
4005  * Curl_expire_done()
4006  *
4007  * Removes the expire timer. Marks it as done.
4008  *
4009  */
4010 void Curl_expire_done(struct Curl_easy *data, expire_id id)
4011 {
4012   /* remove the timer, if there */
4013   multi_deltimeout(data, id);
4014 }
4015 
4016 /*
4017  * Curl_expire_clear()
4018  *
4019  * Clear ALL timeout values for this handle.
4020  */
4021 bool Curl_expire_clear(struct Curl_easy *data)
4022 {
4023   struct Curl_multi *multi = data->multi;
4024   struct curltime *nowp = &data->state.expiretime;
4025 
4026   /* this is only interesting while there is still an associated multi struct
4027      remaining! */
4028   if(!multi)
4029     return FALSE;
4030 
4031   if(nowp->tv_sec || nowp->tv_usec) {
4032     /* Since this is an cleared time, we must remove the previous entry from
4033        the splay tree */
4034     struct Curl_llist *list = &data->state.timeoutlist;
4035     int rc;
4036 
4037     rc = Curl_splayremove(multi->timetree, &data->state.timenode,
4038                           &multi->timetree);
4039     if(rc)
4040       infof(data, "Internal error clearing splay node = %d", rc);
4041 
4042     /* clear the timeout list too */
4043     Curl_llist_destroy(list, NULL);
4044 
4045 #ifdef DEBUGBUILD
4046     infof(data, "Expire cleared");
4047 #endif
4048     nowp->tv_sec = 0;
4049     nowp->tv_usec = 0;
4050     return TRUE;
4051   }
4052   return FALSE;
4053 }
4054 
4055 CURLMcode curl_multi_assign(CURLM *m, curl_socket_t s,
4056                             void *hashp)
4057 {
4058   struct Curl_sh_entry *there = NULL;
4059   struct Curl_multi *multi = m;
4060   if(!GOOD_MULTI_HANDLE(multi))
4061     return CURLM_BAD_HANDLE;
4062 
4063   there = sh_getentry(&multi->sockhash, s);
4064 
4065   if(!there)
4066     return CURLM_BAD_SOCKET;
4067 
4068   there->socketp = hashp;
4069 
4070   return CURLM_OK;
4071 }
4072 
4073 static void move_pending_to_connect(struct Curl_multi *multi,
4074                                     struct Curl_easy *data)
4075 {
4076   DEBUGASSERT(data->mstate == MSTATE_PENDING);
4077 
4078   /* Remove this node from the pending list */
4079   Curl_node_remove(&data->multi_queue);
4080 
4081   /* put it into the process list */
4082   Curl_llist_append(&multi->process, data, &data->multi_queue);
4083 
4084   multistate(data, MSTATE_CONNECT);
4085 
4086   /* Make sure that the handle will be processed soonish. */
4087   Curl_expire(data, 0, EXPIRE_RUN_NOW);
4088 }
4089 
4090 /* process_pending_handles() moves a handle from PENDING back into the process
4091    list and change state to CONNECT.
4092 
4093    We do not move all transfers because that can be a significant amount.
4094    Since this is tried every now and then doing too many too often becomes a
4095    performance problem.
4096 
4097    When there is a change for connection limits like max host connections etc,
4098    this likely only allows one new transfer. When there is a pipewait change,
4099    it can potentially allow hundreds of new transfers.
4100 
4101    We could consider an improvement where we store the queue reason and allow
4102    more pipewait rechecks than others.
4103 */
4104 static void process_pending_handles(struct Curl_multi *multi)
4105 {
4106   struct Curl_llist_node *e = Curl_llist_head(&multi->pending);
4107   if(e) {
4108     struct Curl_easy *data = Curl_node_elem(e);
4109     move_pending_to_connect(multi, data);
4110   }
4111 }
4112 
4113 void Curl_set_in_callback(struct Curl_easy *data, bool value)
4114 {
4115   if(data && data->multi)
4116     data->multi->in_callback = value;
4117 }
4118 
4119 bool Curl_is_in_callback(struct Curl_easy *data)
4120 {
4121   return (data && data->multi && data->multi->in_callback);
4122 }
4123 
4124 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
4125 {
4126   DEBUGASSERT(multi);
4127   return multi->max_concurrent_streams;
4128 }
4129 
4130 CURL **curl_multi_get_handles(CURLM *m)
4131 {
4132   struct Curl_multi *multi = m;
4133   CURL **a = malloc(sizeof(struct Curl_easy *) * (multi->num_easy + 1));
4134   if(a) {
4135     unsigned int i = 0;
4136     struct Curl_llist_node *e;
4137     for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
4138       struct Curl_easy *data = Curl_node_elem(e);
4139       DEBUGASSERT(i < multi->num_easy);
4140       if(!data->state.internal)
4141         a[i++] = data;
4142     }
4143     a[i] = NULL; /* last entry is a NULL */
4144   }
4145   return a;
4146 }
4147 
4148 CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data,
4149                                     char **pbuf, size_t *pbuflen)
4150 {
4151   DEBUGASSERT(data);
4152   DEBUGASSERT(data->multi);
4153   *pbuf = NULL;
4154   *pbuflen = 0;
4155   if(!data->multi) {
4156     failf(data, "transfer has no multi handle");
4157     return CURLE_FAILED_INIT;
4158   }
4159   if(!data->set.buffer_size) {
4160     failf(data, "transfer buffer size is 0");
4161     return CURLE_FAILED_INIT;
4162   }
4163   if(data->multi->xfer_buf_borrowed) {
4164     failf(data, "attempt to borrow xfer_buf when already borrowed");
4165     return CURLE_AGAIN;
4166   }
4167 
4168   if(data->multi->xfer_buf &&
4169      data->set.buffer_size > data->multi->xfer_buf_len) {
4170     /* not large enough, get a new one */
4171     free(data->multi->xfer_buf);
4172     data->multi->xfer_buf = NULL;
4173     data->multi->xfer_buf_len = 0;
4174   }
4175 
4176   if(!data->multi->xfer_buf) {
4177     data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
4178     if(!data->multi->xfer_buf) {
4179       failf(data, "could not allocate xfer_buf of %zu bytes",
4180             (size_t)data->set.buffer_size);
4181       return CURLE_OUT_OF_MEMORY;
4182     }
4183     data->multi->xfer_buf_len = data->set.buffer_size;
4184   }
4185 
4186   data->multi->xfer_buf_borrowed = TRUE;
4187   *pbuf = data->multi->xfer_buf;
4188   *pbuflen = data->multi->xfer_buf_len;
4189   return CURLE_OK;
4190 }
4191 
4192 void Curl_multi_xfer_buf_release(struct Curl_easy *data, char *buf)
4193 {
4194   (void)buf;
4195   DEBUGASSERT(data);
4196   DEBUGASSERT(data->multi);
4197   DEBUGASSERT(!buf || data->multi->xfer_buf == buf);
4198   data->multi->xfer_buf_borrowed = FALSE;
4199 }
4200 
4201 CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data,
4202                                       char **pbuf, size_t *pbuflen)
4203 {
4204   DEBUGASSERT(data);
4205   DEBUGASSERT(data->multi);
4206   *pbuf = NULL;
4207   *pbuflen = 0;
4208   if(!data->multi) {
4209     failf(data, "transfer has no multi handle");
4210     return CURLE_FAILED_INIT;
4211   }
4212   if(!data->set.upload_buffer_size) {
4213     failf(data, "transfer upload buffer size is 0");
4214     return CURLE_FAILED_INIT;
4215   }
4216   if(data->multi->xfer_ulbuf_borrowed) {
4217     failf(data, "attempt to borrow xfer_ulbuf when already borrowed");
4218     return CURLE_AGAIN;
4219   }
4220 
4221   if(data->multi->xfer_ulbuf &&
4222      data->set.upload_buffer_size > data->multi->xfer_ulbuf_len) {
4223     /* not large enough, get a new one */
4224     free(data->multi->xfer_ulbuf);
4225     data->multi->xfer_ulbuf = NULL;
4226     data->multi->xfer_ulbuf_len = 0;
4227   }
4228 
4229   if(!data->multi->xfer_ulbuf) {
4230     data->multi->xfer_ulbuf = malloc((size_t)data->set.upload_buffer_size);
4231     if(!data->multi->xfer_ulbuf) {
4232       failf(data, "could not allocate xfer_ulbuf of %zu bytes",
4233             (size_t)data->set.upload_buffer_size);
4234       return CURLE_OUT_OF_MEMORY;
4235     }
4236     data->multi->xfer_ulbuf_len = data->set.upload_buffer_size;
4237   }
4238 
4239   data->multi->xfer_ulbuf_borrowed = TRUE;
4240   *pbuf = data->multi->xfer_ulbuf;
4241   *pbuflen = data->multi->xfer_ulbuf_len;
4242   return CURLE_OK;
4243 }
4244 
4245 void Curl_multi_xfer_ulbuf_release(struct Curl_easy *data, char *buf)
4246 {
4247   (void)buf;
4248   DEBUGASSERT(data);
4249   DEBUGASSERT(data->multi);
4250   DEBUGASSERT(!buf || data->multi->xfer_ulbuf == buf);
4251   data->multi->xfer_ulbuf_borrowed = FALSE;
4252 }
4253 
4254 CURLcode Curl_multi_xfer_sockbuf_borrow(struct Curl_easy *data,
4255                                         size_t blen, char **pbuf)
4256 {
4257   DEBUGASSERT(data);
4258   DEBUGASSERT(data->multi);
4259   *pbuf = NULL;
4260   if(!data->multi) {
4261     failf(data, "transfer has no multi handle");
4262     return CURLE_FAILED_INIT;
4263   }
4264   if(data->multi->xfer_sockbuf_borrowed) {
4265     failf(data, "attempt to borrow xfer_sockbuf when already borrowed");
4266     return CURLE_AGAIN;
4267   }
4268 
4269   if(data->multi->xfer_sockbuf && blen > data->multi->xfer_sockbuf_len) {
4270     /* not large enough, get a new one */
4271     free(data->multi->xfer_sockbuf);
4272     data->multi->xfer_sockbuf = NULL;
4273     data->multi->xfer_sockbuf_len = 0;
4274   }
4275 
4276   if(!data->multi->xfer_sockbuf) {
4277     data->multi->xfer_sockbuf = malloc(blen);
4278     if(!data->multi->xfer_sockbuf) {
4279       failf(data, "could not allocate xfer_sockbuf of %zu bytes", blen);
4280       return CURLE_OUT_OF_MEMORY;
4281     }
4282     data->multi->xfer_sockbuf_len = blen;
4283   }
4284 
4285   data->multi->xfer_sockbuf_borrowed = TRUE;
4286   *pbuf = data->multi->xfer_sockbuf;
4287   return CURLE_OK;
4288 }
4289 
4290 void Curl_multi_xfer_sockbuf_release(struct Curl_easy *data, char *buf)
4291 {
4292   (void)buf;
4293   DEBUGASSERT(data);
4294   DEBUGASSERT(data->multi);
4295   DEBUGASSERT(!buf || data->multi->xfer_sockbuf == buf);
4296   data->multi->xfer_sockbuf_borrowed = FALSE;
4297 }
4298 
4299 static void multi_xfer_bufs_free(struct Curl_multi *multi)
4300 {
4301   DEBUGASSERT(multi);
4302   Curl_safefree(multi->xfer_buf);
4303   multi->xfer_buf_len = 0;
4304   multi->xfer_buf_borrowed = FALSE;
4305   Curl_safefree(multi->xfer_ulbuf);
4306   multi->xfer_ulbuf_len = 0;
4307   multi->xfer_ulbuf_borrowed = FALSE;
4308   Curl_safefree(multi->xfer_sockbuf);
4309   multi->xfer_sockbuf_len = 0;
4310   multi->xfer_sockbuf_borrowed = FALSE;
4311 }
4312 
4313 struct Curl_easy *Curl_multi_get_handle(struct Curl_multi *multi,
4314                                         curl_off_t mid)
4315 {
4316 
4317   if(mid >= 0) {
4318     struct Curl_easy *data;
4319     struct Curl_llist_node *e;
4320 
4321     for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
4322       data = Curl_node_elem(e);
4323       if(data->mid == mid)
4324         return data;
4325     }
4326     /* may be in msgsent queue */
4327     for(e = Curl_llist_head(&multi->msgsent); e; e = Curl_node_next(e)) {
4328       data = Curl_node_elem(e);
4329       if(data->mid == mid)
4330         return data;
4331     }
4332     /* may be in pending queue */
4333     for(e = Curl_llist_head(&multi->pending); e; e = Curl_node_next(e)) {
4334       data = Curl_node_elem(e);
4335       if(data->mid == mid)
4336         return data;
4337     }
4338   }
4339   return NULL;
4340 }
4341