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