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