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