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