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