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