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