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