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