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