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