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