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