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