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