1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.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 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25 #include "curl_setup.h"
26
27 #include <curl/curl.h>
28
29 #include "urldata.h"
30 #include "transfer.h"
31 #include "url.h"
32 #include "cfilters.h"
33 #include "connect.h"
34 #include "progress.h"
35 #include "easyif.h"
36 #include "share.h"
37 #include "psl.h"
38 #include "multiif.h"
39 #include "sendf.h"
40 #include "timeval.h"
41 #include "http.h"
42 #include "select.h"
43 #include "warnless.h"
44 #include "speedcheck.h"
45 #include "conncache.h"
46 #include "multihandle.h"
47 #include "sigpipe.h"
48 #include "vtls/vtls.h"
49 #include "http_proxy.h"
50 #include "http2.h"
51 #include "socketpair.h"
52 #include "socks.h"
53 /* The last 3 #include files should be in this order */
54 #include "curl_printf.h"
55 #include "curl_memory.h"
56 #include "memdebug.h"
57
58 /*
59 CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
60 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
61 CURL handle takes 45-50 K memory, therefore this 3K are not significant.
62 */
63 #ifndef CURL_SOCKET_HASH_TABLE_SIZE
64 #define CURL_SOCKET_HASH_TABLE_SIZE 911
65 #endif
66
67 #ifndef CURL_CONNECTION_HASH_SIZE
68 #define CURL_CONNECTION_HASH_SIZE 97
69 #endif
70
71 #ifndef CURL_DNS_HASH_SIZE
72 #define CURL_DNS_HASH_SIZE 71
73 #endif
74
75 #define CURL_MULTI_HANDLE 0x000bab1e
76
77 #ifdef DEBUGBUILD
78 /* On a debug build, we want to fail hard on multi handles that
79 * are not NULL, but no longer have the MAGIC touch. This gives
80 * us early warning on things only discovered by valgrind otherwise. */
81 #define GOOD_MULTI_HANDLE(x) \
82 (((x) && (x)->magic == CURL_MULTI_HANDLE)? TRUE: \
83 (DEBUGASSERT(!(x)), FALSE))
84 #else
85 #define GOOD_MULTI_HANDLE(x) \
86 ((x) && (x)->magic == CURL_MULTI_HANDLE)
87 #endif
88
89 static void move_pending_to_connect(struct Curl_multi *multi,
90 struct Curl_easy *data);
91 static CURLMcode singlesocket(struct Curl_multi *multi,
92 struct Curl_easy *data);
93 static CURLMcode add_next_timeout(struct curltime now,
94 struct Curl_multi *multi,
95 struct Curl_easy *d);
96 static CURLMcode multi_timeout(struct Curl_multi *multi,
97 long *timeout_ms);
98 static void process_pending_handles(struct Curl_multi *multi);
99 static void multi_xfer_bufs_free(struct Curl_multi *multi);
100
101 #ifdef DEBUGBUILD
102 static const char * const multi_statename[]={
103 "INIT",
104 "PENDING",
105 "SETUP",
106 "CONNECT",
107 "RESOLVING",
108 "CONNECTING",
109 "TUNNELING",
110 "PROTOCONNECT",
111 "PROTOCONNECTING",
112 "DO",
113 "DOING",
114 "DOING_MORE",
115 "DID",
116 "PERFORMING",
117 "RATELIMITING",
118 "DONE",
119 "COMPLETED",
120 "MSGSENT",
121 };
122 #endif
123
124 /* function pointer called once when switching TO a state */
125 typedef void (*init_multistate_func)(struct Curl_easy *data);
126
127 /* called in DID state, before PERFORMING state */
before_perform(struct Curl_easy * data)128 static void before_perform(struct Curl_easy *data)
129 {
130 data->req.chunk = FALSE;
131 Curl_pgrsTime(data, TIMER_PRETRANSFER);
132 }
133
init_completed(struct Curl_easy * data)134 static void init_completed(struct Curl_easy *data)
135 {
136 /* this is a completed transfer */
137
138 /* Important: reset the conn pointer so that we don't point to memory
139 that could be freed anytime */
140 Curl_detach_connection(data);
141 Curl_expire_clear(data); /* stop all timers */
142 }
143
144 /* always use this function to change state, to make debugging easier */
mstate(struct Curl_easy * data,CURLMstate state,int lineno)145 static void mstate(struct Curl_easy *data, CURLMstate state
146 #ifdef DEBUGBUILD
147 , int lineno
148 #endif
149 )
150 {
151 CURLMstate oldstate = data->mstate;
152 static const init_multistate_func finit[MSTATE_LAST] = {
153 NULL, /* INIT */
154 NULL, /* PENDING */
155 NULL, /* SETUP */
156 Curl_init_CONNECT, /* CONNECT */
157 NULL, /* RESOLVING */
158 NULL, /* CONNECTING */
159 NULL, /* TUNNELING */
160 NULL, /* PROTOCONNECT */
161 NULL, /* PROTOCONNECTING */
162 NULL, /* DO */
163 NULL, /* DOING */
164 NULL, /* DOING_MORE */
165 before_perform, /* DID */
166 NULL, /* PERFORMING */
167 NULL, /* RATELIMITING */
168 NULL, /* DONE */
169 init_completed, /* COMPLETED */
170 NULL /* MSGSENT */
171 };
172
173 #if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
174 (void) lineno;
175 #endif
176
177 if(oldstate == state)
178 /* don't bother when the new state is the same as the old state */
179 return;
180
181 data->mstate = state;
182
183 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
184 if(data->mstate >= MSTATE_PENDING &&
185 data->mstate < MSTATE_COMPLETED) {
186 infof(data,
187 "STATE: %s => %s handle %p; line %d",
188 multi_statename[oldstate], multi_statename[data->mstate],
189 (void *)data, lineno);
190 }
191 #endif
192
193 if(state == MSTATE_COMPLETED) {
194 /* changing to COMPLETED means there's one less easy handle 'alive' */
195 DEBUGASSERT(data->multi->num_alive > 0);
196 data->multi->num_alive--;
197 if(!data->multi->num_alive) {
198 /* free the transfer buffer when we have no more active transfers */
199 multi_xfer_bufs_free(data->multi);
200 }
201 }
202
203 /* if this state has an init-function, run it */
204 if(finit[state])
205 finit[state](data);
206 }
207
208 #ifndef DEBUGBUILD
209 #define multistate(x,y) mstate(x,y)
210 #else
211 #define multistate(x,y) mstate(x,y, __LINE__)
212 #endif
213
214 /*
215 * We add one of these structs to the sockhash for each socket
216 */
217
218 struct Curl_sh_entry {
219 struct Curl_hash transfers; /* hash of transfers using this socket */
220 unsigned int action; /* what combined action READ/WRITE this socket waits
221 for */
222 unsigned int users; /* number of transfers using this */
223 void *socketp; /* settable by users with curl_multi_assign() */
224 unsigned int readers; /* this many transfers want to read */
225 unsigned int writers; /* this many transfers want to write */
226 };
227
228 /* look up a given socket in the socket hash, skip invalid sockets */
sh_getentry(struct Curl_hash * sh,curl_socket_t s)229 static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh,
230 curl_socket_t s)
231 {
232 if(s != CURL_SOCKET_BAD) {
233 /* only look for proper sockets */
234 return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
235 }
236 return NULL;
237 }
238
239 #define TRHASH_SIZE 13
trhash(void * key,size_t key_length,size_t slots_num)240 static size_t trhash(void *key, size_t key_length, size_t slots_num)
241 {
242 size_t keyval = (size_t)*(struct Curl_easy **)key;
243 (void) key_length;
244
245 return (keyval % slots_num);
246 }
247
trhash_compare(void * k1,size_t k1_len,void * k2,size_t k2_len)248 static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
249 {
250 (void)k1_len;
251 (void)k2_len;
252
253 return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2;
254 }
255
trhash_dtor(void * nada)256 static void trhash_dtor(void *nada)
257 {
258 (void)nada;
259 }
260
261 /*
262 * The sockhash has its own separate subhash in each entry that need to be
263 * safely destroyed first.
264 */
sockhash_destroy(struct Curl_hash * h)265 static void sockhash_destroy(struct Curl_hash *h)
266 {
267 struct Curl_hash_iterator iter;
268 struct Curl_hash_element *he;
269
270 DEBUGASSERT(h);
271 Curl_hash_start_iterate(h, &iter);
272 he = Curl_hash_next_element(&iter);
273 while(he) {
274 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)he->ptr;
275 Curl_hash_destroy(&sh->transfers);
276 he = Curl_hash_next_element(&iter);
277 }
278 Curl_hash_destroy(h);
279 }
280
281
282 /* make sure this socket is present in the hash for this handle */
sh_addentry(struct Curl_hash * sh,curl_socket_t s)283 static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
284 curl_socket_t s)
285 {
286 struct Curl_sh_entry *there = sh_getentry(sh, s);
287 struct Curl_sh_entry *check;
288
289 if(there) {
290 /* it is present, return fine */
291 return there;
292 }
293
294 /* not present, add it */
295 check = calloc(1, sizeof(struct Curl_sh_entry));
296 if(!check)
297 return NULL; /* major failure */
298
299 Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, trhash_compare,
300 trhash_dtor);
301
302 /* make/add new hash entry */
303 if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
304 Curl_hash_destroy(&check->transfers);
305 free(check);
306 return NULL; /* major failure */
307 }
308
309 return check; /* things are good in sockhash land */
310 }
311
312
313 /* delete the given socket + handle from the hash */
sh_delentry(struct Curl_sh_entry * entry,struct Curl_hash * sh,curl_socket_t s)314 static void sh_delentry(struct Curl_sh_entry *entry,
315 struct Curl_hash *sh, curl_socket_t s)
316 {
317 Curl_hash_destroy(&entry->transfers);
318
319 /* We remove the hash entry. This will end up in a call to
320 sh_freeentry(). */
321 Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
322 }
323
324 /*
325 * free a sockhash entry
326 */
sh_freeentry(void * freethis)327 static void sh_freeentry(void *freethis)
328 {
329 struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
330
331 free(p);
332 }
333
fd_key_compare(void * k1,size_t k1_len,void * k2,size_t k2_len)334 static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
335 {
336 (void) k1_len; (void) k2_len;
337
338 return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2));
339 }
340
hash_fd(void * key,size_t key_length,size_t slots_num)341 static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
342 {
343 curl_socket_t fd = *((curl_socket_t *) key);
344 (void) key_length;
345
346 return (fd % slots_num);
347 }
348
349 /*
350 * sh_init() creates a new socket hash and returns the handle for it.
351 *
352 * Quote from README.multi_socket:
353 *
354 * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
355 * is somewhat of a bottle neck. Its current implementation may be a bit too
356 * limiting. It simply has a fixed-size array, and on each entry in the array
357 * it has a linked list with entries. So the hash only checks which list to
358 * scan through. The code I had used so for used a list with merely 7 slots
359 * (as that is what the DNS hash uses) but with 7000 connections that would
360 * make an average of 1000 nodes in each list to run through. I upped that to
361 * 97 slots (I believe a prime is suitable) and noticed a significant speed
362 * increase. I need to reconsider the hash implementation or use a rather
363 * large default value like this. At 9000 connections I was still below 10us
364 * per call."
365 *
366 */
sh_init(struct Curl_hash * hash,size_t hashsize)367 static void sh_init(struct Curl_hash *hash, size_t hashsize)
368 {
369 Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
370 sh_freeentry);
371 }
372
373 /*
374 * multi_addmsg()
375 *
376 * Called when a transfer is completed. Adds the given msg pointer to
377 * the list kept in the multi handle.
378 */
multi_addmsg(struct Curl_multi * multi,struct Curl_message * msg)379 static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg)
380 {
381 Curl_llist_append(&multi->msglist, msg, &msg->list);
382 }
383
Curl_multi_handle(size_t hashsize,size_t chashsize,size_t dnssize)384 struct Curl_multi *Curl_multi_handle(size_t hashsize, /* socket hash */
385 size_t chashsize, /* connection hash */
386 size_t dnssize) /* dns hash */
387 {
388 struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
389
390 if(!multi)
391 return NULL;
392
393 multi->magic = CURL_MULTI_HANDLE;
394
395 Curl_init_dnscache(&multi->hostcache, dnssize);
396
397 sh_init(&multi->sockhash, hashsize);
398
399 if(Curl_conncache_init(&multi->conn_cache, chashsize))
400 goto error;
401
402 Curl_llist_init(&multi->msglist, NULL);
403 Curl_llist_init(&multi->pending, NULL);
404 Curl_llist_init(&multi->msgsent, NULL);
405
406 multi->multiplexing = TRUE;
407 multi->max_concurrent_streams = 100;
408
409 #ifdef USE_WINSOCK
410 multi->wsa_event = WSACreateEvent();
411 if(multi->wsa_event == WSA_INVALID_EVENT)
412 goto error;
413 #else
414 #ifdef ENABLE_WAKEUP
415 if(wakeup_create(multi->wakeup_pair) < 0) {
416 multi->wakeup_pair[0] = CURL_SOCKET_BAD;
417 multi->wakeup_pair[1] = CURL_SOCKET_BAD;
418 }
419 else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 ||
420 curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) {
421 wakeup_close(multi->wakeup_pair[0]);
422 wakeup_close(multi->wakeup_pair[1]);
423 multi->wakeup_pair[0] = CURL_SOCKET_BAD;
424 multi->wakeup_pair[1] = CURL_SOCKET_BAD;
425 }
426 #endif
427 #endif
428
429 return multi;
430
431 error:
432
433 sockhash_destroy(&multi->sockhash);
434 Curl_hash_destroy(&multi->hostcache);
435 Curl_conncache_destroy(&multi->conn_cache);
436 free(multi);
437 return NULL;
438 }
439
curl_multi_init(void)440 struct Curl_multi *curl_multi_init(void)
441 {
442 return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
443 CURL_CONNECTION_HASH_SIZE,
444 CURL_DNS_HASH_SIZE);
445 }
446
447 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
multi_warn_debug(struct Curl_multi * multi,struct Curl_easy * data)448 static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
449 {
450 if(!multi->warned) {
451 infof(data, "!!! WARNING !!!");
452 infof(data, "This is a debug build of libcurl, "
453 "do not use in production.");
454 multi->warned = true;
455 }
456 }
457 #else
458 #define multi_warn_debug(x,y) Curl_nop_stmt
459 #endif
460
461 /* returns TRUE if the easy handle is supposed to be present in the main link
462 list */
in_main_list(struct Curl_easy * data)463 static bool in_main_list(struct Curl_easy *data)
464 {
465 return ((data->mstate != MSTATE_PENDING) &&
466 (data->mstate != MSTATE_MSGSENT));
467 }
468
link_easy(struct Curl_multi * multi,struct Curl_easy * data)469 static void link_easy(struct Curl_multi *multi,
470 struct Curl_easy *data)
471 {
472 /* We add the new easy entry last in the list. */
473 data->next = NULL; /* end of the line */
474 if(multi->easyp) {
475 struct Curl_easy *last = multi->easylp;
476 last->next = data;
477 data->prev = last;
478 multi->easylp = data; /* the new last node */
479 }
480 else {
481 /* first node, make prev NULL! */
482 data->prev = NULL;
483 multi->easylp = multi->easyp = data; /* both first and last */
484 }
485 }
486
487 /* unlink the given easy handle from the linked list of easy handles */
unlink_easy(struct Curl_multi * multi,struct Curl_easy * data)488 static void unlink_easy(struct Curl_multi *multi,
489 struct Curl_easy *data)
490 {
491 /* make the previous node point to our next */
492 if(data->prev)
493 data->prev->next = data->next;
494 else
495 multi->easyp = data->next; /* point to first node */
496
497 /* make our next point to our previous node */
498 if(data->next)
499 data->next->prev = data->prev;
500 else
501 multi->easylp = data->prev; /* point to last node */
502
503 data->prev = data->next = NULL;
504 }
505
506
curl_multi_add_handle(struct Curl_multi * multi,struct Curl_easy * data)507 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
508 struct Curl_easy *data)
509 {
510 CURLMcode rc;
511 /* First, make some basic checks that the CURLM handle is a good handle */
512 if(!GOOD_MULTI_HANDLE(multi))
513 return CURLM_BAD_HANDLE;
514
515 /* Verify that we got a somewhat good easy handle too */
516 if(!GOOD_EASY_HANDLE(data))
517 return CURLM_BAD_EASY_HANDLE;
518
519 /* Prevent users from adding same easy handle more than once and prevent
520 adding to more than one multi stack */
521 if(data->multi)
522 return CURLM_ADDED_ALREADY;
523
524 if(multi->in_callback)
525 return CURLM_RECURSIVE_API_CALL;
526
527 if(multi->dead) {
528 /* a "dead" handle cannot get added transfers while any existing easy
529 handles are still alive - but if there are none alive anymore, it is
530 fine to start over and unmark the "deadness" of this handle */
531 if(multi->num_alive)
532 return CURLM_ABORTED_BY_CALLBACK;
533 multi->dead = FALSE;
534 }
535
536 if(data->multi_easy) {
537 /* if this easy handle was previously used for curl_easy_perform(), there
538 is a private multi handle here that we can kill */
539 curl_multi_cleanup(data->multi_easy);
540 data->multi_easy = NULL;
541 }
542
543 /* Initialize timeout list for this handle */
544 Curl_llist_init(&data->state.timeoutlist, NULL);
545
546 /*
547 * No failure allowed in this function beyond this point. And no
548 * modification of easy nor multi handle allowed before this except for
549 * potential multi's connection cache growing which won't be undone in this
550 * function no matter what.
551 */
552 if(data->set.errorbuffer)
553 data->set.errorbuffer[0] = 0;
554
555 data->state.os_errno = 0;
556
557 /* make the Curl_easy refer back to this multi handle - before Curl_expire()
558 is called. */
559 data->multi = multi;
560
561 /* Set the timeout for this handle to expire really soon so that it will
562 be taken care of even when this handle is added in the midst of operation
563 when only the curl_multi_socket() API is used. During that flow, only
564 sockets that time-out or have actions will be dealt with. Since this
565 handle has no action yet, we make sure it times out to get things to
566 happen. */
567 Curl_expire(data, 0, EXPIRE_RUN_NOW);
568
569 /* A somewhat crude work-around for a little glitch in Curl_update_timer()
570 that happens if the lastcall time is set to the same time when the handle
571 is removed as when the next handle is added, as then the check in
572 Curl_update_timer() that prevents calling the application multiple times
573 with the same timer info will not trigger and then the new handle's
574 timeout will not be notified to the app.
575
576 The work-around is thus simply to clear the 'lastcall' variable to force
577 Curl_update_timer() to always trigger a callback to the app when a new
578 easy handle is added */
579 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
580
581 rc = Curl_update_timer(multi);
582 if(rc)
583 return rc;
584
585 /* set the easy handle */
586 multistate(data, MSTATE_INIT);
587
588 /* for multi interface connections, we share DNS cache automatically if the
589 easy handle's one is currently not set. */
590 if(!data->dns.hostcache ||
591 (data->dns.hostcachetype == HCACHE_NONE)) {
592 data->dns.hostcache = &multi->hostcache;
593 data->dns.hostcachetype = HCACHE_MULTI;
594 }
595
596 /* Point to the shared or multi handle connection cache */
597 if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT)))
598 data->state.conn_cache = &data->share->conn_cache;
599 else
600 data->state.conn_cache = &multi->conn_cache;
601 data->state.lastconnect_id = -1;
602
603 #ifdef USE_LIBPSL
604 /* Do the same for PSL. */
605 if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
606 data->psl = &data->share->psl;
607 else
608 data->psl = &multi->psl;
609 #endif
610
611 link_easy(multi, data);
612
613 /* increase the node-counter */
614 multi->num_easy++;
615
616 /* increase the alive-counter */
617 multi->num_alive++;
618
619 CONNCACHE_LOCK(data);
620 /* The closure handle only ever has default timeouts set. To improve the
621 state somewhat we clone the timeouts from each added handle so that the
622 closure handle always has the same timeouts as the most recently added
623 easy handle. */
624 data->state.conn_cache->closure_handle->set.timeout = data->set.timeout;
625 data->state.conn_cache->closure_handle->set.server_response_timeout =
626 data->set.server_response_timeout;
627 data->state.conn_cache->closure_handle->set.no_signal =
628 data->set.no_signal;
629 data->id = data->state.conn_cache->next_easy_id++;
630 if(data->state.conn_cache->next_easy_id <= 0)
631 data->state.conn_cache->next_easy_id = 0;
632 CONNCACHE_UNLOCK(data);
633
634 multi_warn_debug(multi, data);
635
636 return CURLM_OK;
637 }
638
639 #if 0
640 /* Debug-function, used like this:
641 *
642 * Curl_hash_print(&multi->sockhash, debug_print_sock_hash);
643 *
644 * Enable the hash print function first by editing hash.c
645 */
646 static void debug_print_sock_hash(void *p)
647 {
648 struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
649
650 fprintf(stderr, " [readers %u][writers %u]",
651 sh->readers, sh->writers);
652 }
653 #endif
654
multi_done(struct Curl_easy * data,CURLcode status,bool premature)655 static CURLcode multi_done(struct Curl_easy *data,
656 CURLcode status, /* an error if this is called
657 after an error was detected */
658 bool premature)
659 {
660 CURLcode result, r2;
661 struct connectdata *conn = data->conn;
662
663 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
664 DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d",
665 multi_statename[data->mstate],
666 (int)status, (int)premature, data->state.done));
667 #else
668 DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d",
669 (int)status, (int)premature, data->state.done));
670 #endif
671
672 if(data->state.done)
673 /* Stop if multi_done() has already been called */
674 return CURLE_OK;
675
676 /* Stop the resolver and free its own resources (but not dns_entry yet). */
677 Curl_resolver_kill(data);
678
679 /* Cleanup possible redirect junk */
680 Curl_safefree(data->req.newurl);
681 Curl_safefree(data->req.location);
682
683 switch(status) {
684 case CURLE_ABORTED_BY_CALLBACK:
685 case CURLE_READ_ERROR:
686 case CURLE_WRITE_ERROR:
687 /* When we're aborted due to a callback return code it basically have to
688 be counted as premature as there is trouble ahead if we don't. We have
689 many callbacks and protocols work differently, we could potentially do
690 this more fine-grained in the future. */
691 premature = TRUE;
692 FALLTHROUGH();
693 default:
694 break;
695 }
696
697 /* this calls the protocol-specific function pointer previously set */
698 if(conn->handler->done)
699 result = conn->handler->done(data, status, premature);
700 else
701 result = status;
702
703 if(CURLE_ABORTED_BY_CALLBACK != result) {
704 /* avoid this if we already aborted by callback to avoid this calling
705 another callback */
706 int rc = Curl_pgrsDone(data);
707 if(!result && rc)
708 result = CURLE_ABORTED_BY_CALLBACK;
709 }
710
711 /* Make sure that transfer client writes are really done now. */
712 r2 = Curl_xfer_write_done(data, premature);
713 if(r2 && !result)
714 result = r2;
715
716 /* Inform connection filters that this transfer is done */
717 Curl_conn_ev_data_done(data, premature);
718
719 process_pending_handles(data->multi); /* connection / multiplex */
720
721 if(!result)
722 result = Curl_req_done(&data->req, data, premature);
723
724 CONNCACHE_LOCK(data);
725 Curl_detach_connection(data);
726 if(CONN_INUSE(conn)) {
727 /* Stop if still used. */
728 CONNCACHE_UNLOCK(data);
729 DEBUGF(infof(data, "Connection still in use %zu, "
730 "no more multi_done now!",
731 conn->easyq.size));
732 return CURLE_OK;
733 }
734
735 data->state.done = TRUE; /* called just now! */
736
737 if(conn->dns_entry) {
738 Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
739 conn->dns_entry = NULL;
740 }
741 Curl_hostcache_prune(data);
742
743 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
744 forced us to close this connection. This is ignored for requests taking
745 place in a NTLM/NEGOTIATE authentication handshake
746
747 if conn->bits.close is TRUE, it means that the connection should be
748 closed in spite of all our efforts to be nice, due to protocol
749 restrictions in our or the server's end
750
751 if premature is TRUE, it means this connection was said to be DONE before
752 the entire request operation is complete and thus we can't know in what
753 state it is for reusing, so we're forced to close it. In a perfect world
754 we can add code that keep track of if we really must close it here or not,
755 but currently we have no such detail knowledge.
756 */
757
758 data->state.recent_conn_id = conn->connection_id;
759 if((data->set.reuse_forbid
760 #if defined(USE_NTLM)
761 && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
762 conn->proxy_ntlm_state == NTLMSTATE_TYPE2)
763 #endif
764 #if defined(USE_SPNEGO)
765 && !(conn->http_negotiate_state == GSS_AUTHRECV ||
766 conn->proxy_negotiate_state == GSS_AUTHRECV)
767 #endif
768 ) || conn->bits.close
769 || (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) {
770 DEBUGF(infof(data, "multi_done, not reusing connection=%"
771 CURL_FORMAT_CURL_OFF_T ", forbid=%d"
772 ", close=%d, premature=%d, conn_multiplex=%d",
773 conn->connection_id,
774 data->set.reuse_forbid, conn->bits.close, premature,
775 Curl_conn_is_multiplex(conn, FIRSTSOCKET)));
776 connclose(conn, "disconnecting");
777 Curl_conncache_remove_conn(data, conn, FALSE);
778 CONNCACHE_UNLOCK(data);
779 Curl_disconnect(data, conn, premature);
780 }
781 else {
782 char buffer[256];
783 const char *host =
784 #ifndef CURL_DISABLE_PROXY
785 conn->bits.socksproxy ?
786 conn->socks_proxy.host.dispname :
787 conn->bits.httpproxy ? conn->http_proxy.host.dispname :
788 #endif
789 conn->bits.conn_to_host ? conn->conn_to_host.dispname :
790 conn->host.dispname;
791 /* create string before returning the connection */
792 curl_off_t connection_id = conn->connection_id;
793 msnprintf(buffer, sizeof(buffer),
794 "Connection #%" CURL_FORMAT_CURL_OFF_T " to host %s left intact",
795 connection_id, host);
796 /* the connection is no longer in use by this transfer */
797 CONNCACHE_UNLOCK(data);
798 if(Curl_conncache_return_conn(data, conn)) {
799 /* remember the most recently used connection */
800 data->state.lastconnect_id = connection_id;
801 data->state.recent_conn_id = connection_id;
802 infof(data, "%s", buffer);
803 }
804 else
805 data->state.lastconnect_id = -1;
806 }
807
808 return result;
809 }
810
close_connect_only(struct Curl_easy * data,struct connectdata * conn,void * param)811 static int close_connect_only(struct Curl_easy *data,
812 struct connectdata *conn, void *param)
813 {
814 (void)param;
815 if(data->state.lastconnect_id != conn->connection_id)
816 return 0;
817
818 if(!conn->connect_only)
819 return 1;
820
821 connclose(conn, "Removing connect-only easy handle");
822
823 return 1;
824 }
825
curl_multi_remove_handle(struct Curl_multi * multi,struct Curl_easy * data)826 CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
827 struct Curl_easy *data)
828 {
829 struct Curl_easy *easy = data;
830 bool premature;
831 struct Curl_llist_element *e;
832 CURLMcode rc;
833
834 /* First, make some basic checks that the CURLM handle is a good handle */
835 if(!GOOD_MULTI_HANDLE(multi))
836 return CURLM_BAD_HANDLE;
837
838 /* Verify that we got a somewhat good easy handle too */
839 if(!GOOD_EASY_HANDLE(data))
840 return CURLM_BAD_EASY_HANDLE;
841
842 /* Prevent users from trying to remove same easy handle more than once */
843 if(!data->multi)
844 return CURLM_OK; /* it is already removed so let's say it is fine! */
845
846 /* Prevent users from trying to remove an easy handle from the wrong multi */
847 if(data->multi != multi)
848 return CURLM_BAD_EASY_HANDLE;
849
850 if(multi->in_callback)
851 return CURLM_RECURSIVE_API_CALL;
852
853 premature = (data->mstate < MSTATE_COMPLETED) ? TRUE : FALSE;
854
855 /* If the 'state' is not INIT or COMPLETED, we might need to do something
856 nice to put the easy_handle in a good known state when this returns. */
857 if(premature) {
858 /* this handle is "alive" so we need to count down the total number of
859 alive connections when this is removed */
860 multi->num_alive--;
861 }
862
863 if(data->conn &&
864 data->mstate > MSTATE_DO &&
865 data->mstate < MSTATE_COMPLETED) {
866 /* Set connection owner so that the DONE function closes it. We can
867 safely do this here since connection is killed. */
868 streamclose(data->conn, "Removed with partial response");
869 }
870
871 if(data->conn) {
872 /* multi_done() clears the association between the easy handle and the
873 connection.
874
875 Note that this ignores the return code simply because there's
876 nothing really useful to do with it anyway! */
877 (void)multi_done(data, data->result, premature);
878 }
879
880 /* The timer must be shut down before data->multi is set to NULL, else the
881 timenode will remain in the splay tree after curl_easy_cleanup is
882 called. Do it after multi_done() in case that sets another time! */
883 Curl_expire_clear(data);
884
885 if(data->connect_queue.ptr) {
886 /* the handle is in the pending or msgsent lists, so go ahead and remove
887 it */
888 if(data->mstate == MSTATE_PENDING)
889 Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
890 else
891 Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL);
892 }
893 if(in_main_list(data))
894 unlink_easy(multi, data);
895
896 if(data->dns.hostcachetype == HCACHE_MULTI) {
897 /* stop using the multi handle's DNS cache, *after* the possible
898 multi_done() call above */
899 data->dns.hostcache = NULL;
900 data->dns.hostcachetype = HCACHE_NONE;
901 }
902
903 Curl_wildcard_dtor(&data->wildcard);
904
905 /* change state without using multistate(), only to make singlesocket() do
906 what we want */
907 data->mstate = MSTATE_COMPLETED;
908
909 /* This ignores the return code even in case of problems because there's
910 nothing more to do about that, here */
911 (void)singlesocket(multi, easy); /* to let the application know what sockets
912 that vanish with this handle */
913
914 /* Remove the association between the connection and the handle */
915 Curl_detach_connection(data);
916
917 if(data->set.connect_only && !data->multi_easy) {
918 /* This removes a handle that was part the multi interface that used
919 CONNECT_ONLY, that connection is now left alive but since this handle
920 has bits.close set nothing can use that transfer anymore and it is
921 forbidden from reuse. And this easy handle cannot find the connection
922 anymore once removed from the multi handle
923
924 Better close the connection here, at once.
925 */
926 struct connectdata *c;
927 curl_socket_t s;
928 s = Curl_getconnectinfo(data, &c);
929 if((s != CURL_SOCKET_BAD) && c) {
930 Curl_conncache_remove_conn(data, c, TRUE);
931 Curl_disconnect(data, c, TRUE);
932 }
933 }
934
935 if(data->state.lastconnect_id != -1) {
936 /* Mark any connect-only connection for closure */
937 Curl_conncache_foreach(data, data->state.conn_cache,
938 NULL, close_connect_only);
939 }
940
941 #ifdef USE_LIBPSL
942 /* Remove the PSL association. */
943 if(data->psl == &multi->psl)
944 data->psl = NULL;
945 #endif
946
947 /* as this was using a shared connection cache we clear the pointer to that
948 since we're not part of that multi handle anymore */
949 data->state.conn_cache = NULL;
950
951 data->multi = NULL; /* clear the association to this multi handle */
952
953 /* make sure there's no pending message in the queue sent from this easy
954 handle */
955 for(e = multi->msglist.head; e; e = e->next) {
956 struct Curl_message *msg = e->ptr;
957
958 if(msg->extmsg.easy_handle == easy) {
959 Curl_llist_remove(&multi->msglist, e, NULL);
960 /* there can only be one from this specific handle */
961 break;
962 }
963 }
964
965 /* NOTE NOTE NOTE
966 We do not touch the easy handle here! */
967 multi->num_easy--; /* one less to care about now */
968
969 process_pending_handles(multi);
970
971 rc = Curl_update_timer(multi);
972 if(rc)
973 return rc;
974 return CURLM_OK;
975 }
976
977 /* Return TRUE if the application asked for multiplexing */
Curl_multiplex_wanted(const struct Curl_multi * multi)978 bool Curl_multiplex_wanted(const struct Curl_multi *multi)
979 {
980 return (multi && (multi->multiplexing));
981 }
982
983 /*
984 * Curl_detach_connection() removes the given transfer from the connection.
985 *
986 * This is the only function that should clear data->conn. This will
987 * occasionally be called with the data->conn pointer already cleared.
988 */
Curl_detach_connection(struct Curl_easy * data)989 void Curl_detach_connection(struct Curl_easy *data)
990 {
991 struct connectdata *conn = data->conn;
992 if(conn) {
993 Curl_conn_ev_data_detach(conn, data);
994 Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
995 }
996 data->conn = NULL;
997 }
998
999 /*
1000 * Curl_attach_connection() attaches this transfer to this connection.
1001 *
1002 * This is the only function that should assign data->conn
1003 */
Curl_attach_connection(struct Curl_easy * data,struct connectdata * conn)1004 void Curl_attach_connection(struct Curl_easy *data,
1005 struct connectdata *conn)
1006 {
1007 DEBUGASSERT(!data->conn);
1008 DEBUGASSERT(conn);
1009 data->conn = conn;
1010 Curl_llist_append(&conn->easyq, data, &data->conn_queue);
1011 if(conn->handler && conn->handler->attach)
1012 conn->handler->attach(data, conn);
1013 Curl_conn_ev_data_attach(conn, data);
1014 }
1015
connecting_getsock(struct Curl_easy * data,curl_socket_t * socks)1016 static int connecting_getsock(struct Curl_easy *data, curl_socket_t *socks)
1017 {
1018 struct connectdata *conn = data->conn;
1019 (void)socks;
1020 /* Not using `conn->sockfd` as `Curl_xfer_setup()` initializes
1021 * that *after* the connect. */
1022 if(conn && conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD) {
1023 /* Default is to wait to something from the server */
1024 socks[0] = conn->sock[FIRSTSOCKET];
1025 return GETSOCK_READSOCK(0);
1026 }
1027 return GETSOCK_BLANK;
1028 }
1029
protocol_getsock(struct Curl_easy * data,curl_socket_t * socks)1030 static int protocol_getsock(struct Curl_easy *data, curl_socket_t *socks)
1031 {
1032 struct connectdata *conn = data->conn;
1033 if(conn && conn->handler->proto_getsock)
1034 return conn->handler->proto_getsock(data, conn, socks);
1035 else if(conn && conn->sockfd != CURL_SOCKET_BAD) {
1036 /* Default is to wait to something from the server */
1037 socks[0] = conn->sockfd;
1038 return GETSOCK_READSOCK(0);
1039 }
1040 return GETSOCK_BLANK;
1041 }
1042
domore_getsock(struct Curl_easy * data,curl_socket_t * socks)1043 static int domore_getsock(struct Curl_easy *data, curl_socket_t *socks)
1044 {
1045 struct connectdata *conn = data->conn;
1046 if(conn && conn->handler->domore_getsock)
1047 return conn->handler->domore_getsock(data, conn, socks);
1048 else if(conn && conn->sockfd != CURL_SOCKET_BAD) {
1049 /* Default is that we want to send something to the server */
1050 socks[0] = conn->sockfd;
1051 return GETSOCK_WRITESOCK(0);
1052 }
1053 return GETSOCK_BLANK;
1054 }
1055
doing_getsock(struct Curl_easy * data,curl_socket_t * socks)1056 static int doing_getsock(struct Curl_easy *data, curl_socket_t *socks)
1057 {
1058 struct connectdata *conn = data->conn;
1059 if(conn && conn->handler->doing_getsock)
1060 return conn->handler->doing_getsock(data, conn, socks);
1061 else if(conn && conn->sockfd != CURL_SOCKET_BAD) {
1062 /* Default is that we want to send something to the server */
1063 socks[0] = conn->sockfd;
1064 return GETSOCK_WRITESOCK(0);
1065 }
1066 return GETSOCK_BLANK;
1067 }
1068
perform_getsock(struct Curl_easy * data,curl_socket_t * sock)1069 static int perform_getsock(struct Curl_easy *data, curl_socket_t *sock)
1070 {
1071 struct connectdata *conn = data->conn;
1072
1073 if(!conn)
1074 return GETSOCK_BLANK;
1075 else if(conn->handler->perform_getsock)
1076 return conn->handler->perform_getsock(data, conn, sock);
1077 else {
1078 /* Default is to obey the data->req.keepon flags for send/recv */
1079 int bitmap = GETSOCK_BLANK;
1080 unsigned sockindex = 0;
1081 if(CURL_WANT_RECV(data)) {
1082 DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
1083 bitmap |= GETSOCK_READSOCK(sockindex);
1084 sock[sockindex] = conn->sockfd;
1085 }
1086
1087 if(CURL_WANT_SEND(data)) {
1088 if((conn->sockfd != conn->writesockfd) ||
1089 bitmap == GETSOCK_BLANK) {
1090 /* only if they are not the same socket and we have a readable
1091 one, we increase index */
1092 if(bitmap != GETSOCK_BLANK)
1093 sockindex++; /* increase index if we need two entries */
1094
1095 DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
1096 sock[sockindex] = conn->writesockfd;
1097 }
1098 bitmap |= GETSOCK_WRITESOCK(sockindex);
1099 }
1100 return bitmap;
1101 }
1102 }
1103
1104 /* Initializes `poll_set` with the current socket poll actions needed
1105 * for transfer `data`. */
multi_getsock(struct Curl_easy * data,struct easy_pollset * ps)1106 static void multi_getsock(struct Curl_easy *data,
1107 struct easy_pollset *ps)
1108 {
1109 /* The no connection case can happen when this is called from
1110 curl_multi_remove_handle() => singlesocket() => multi_getsock().
1111 */
1112 Curl_pollset_reset(data, ps);
1113 if(!data->conn)
1114 return;
1115
1116 switch(data->mstate) {
1117 case MSTATE_INIT:
1118 case MSTATE_PENDING:
1119 case MSTATE_SETUP:
1120 case MSTATE_CONNECT:
1121 /* nothing to poll for yet */
1122 break;
1123
1124 case MSTATE_RESOLVING:
1125 Curl_pollset_add_socks(data, ps, Curl_resolv_getsock);
1126 /* connection filters are not involved in this phase */
1127 break;
1128
1129 case MSTATE_CONNECTING:
1130 case MSTATE_TUNNELING:
1131 Curl_pollset_add_socks(data, ps, connecting_getsock);
1132 Curl_conn_adjust_pollset(data, ps);
1133 break;
1134
1135 case MSTATE_PROTOCONNECT:
1136 case MSTATE_PROTOCONNECTING:
1137 Curl_pollset_add_socks(data, ps, protocol_getsock);
1138 Curl_conn_adjust_pollset(data, ps);
1139 break;
1140
1141 case MSTATE_DO:
1142 case MSTATE_DOING:
1143 Curl_pollset_add_socks(data, ps, doing_getsock);
1144 Curl_conn_adjust_pollset(data, ps);
1145 break;
1146
1147 case MSTATE_DOING_MORE:
1148 Curl_pollset_add_socks(data, ps, domore_getsock);
1149 Curl_conn_adjust_pollset(data, ps);
1150 break;
1151
1152 case MSTATE_DID: /* same as PERFORMING in regard to polling */
1153 case MSTATE_PERFORMING:
1154 Curl_pollset_add_socks(data, ps, perform_getsock);
1155 Curl_conn_adjust_pollset(data, ps);
1156 break;
1157
1158 case MSTATE_RATELIMITING:
1159 /* we need to let time pass, ignore socket(s) */
1160 break;
1161
1162 case MSTATE_DONE:
1163 case MSTATE_COMPLETED:
1164 case MSTATE_MSGSENT:
1165 /* nothing more to poll for */
1166 break;
1167
1168 default:
1169 failf(data, "multi_getsock: unexpected multi state %d", data->mstate);
1170 DEBUGASSERT(0);
1171 break;
1172 }
1173 }
1174
curl_multi_fdset(struct Curl_multi * multi,fd_set * read_fd_set,fd_set * write_fd_set,fd_set * exc_fd_set,int * max_fd)1175 CURLMcode curl_multi_fdset(struct Curl_multi *multi,
1176 fd_set *read_fd_set, fd_set *write_fd_set,
1177 fd_set *exc_fd_set, int *max_fd)
1178 {
1179 /* Scan through all the easy handles to get the file descriptors set.
1180 Some easy handles may not have connected to the remote host yet,
1181 and then we must make sure that is done. */
1182 struct Curl_easy *data;
1183 int this_max_fd = -1;
1184 struct easy_pollset ps;
1185 unsigned int i;
1186 (void)exc_fd_set; /* not used */
1187
1188 if(!GOOD_MULTI_HANDLE(multi))
1189 return CURLM_BAD_HANDLE;
1190
1191 if(multi->in_callback)
1192 return CURLM_RECURSIVE_API_CALL;
1193
1194 memset(&ps, 0, sizeof(ps));
1195 for(data = multi->easyp; data; data = data->next) {
1196 multi_getsock(data, &ps);
1197
1198 for(i = 0; i < ps.num; i++) {
1199 if(!FDSET_SOCK(ps.sockets[i]))
1200 /* pretend it doesn't exist */
1201 continue;
1202 if(ps.actions[i] & CURL_POLL_IN)
1203 FD_SET(ps.sockets[i], read_fd_set);
1204 if(ps.actions[i] & CURL_POLL_OUT)
1205 FD_SET(ps.sockets[i], write_fd_set);
1206 if((int)ps.sockets[i] > this_max_fd)
1207 this_max_fd = (int)ps.sockets[i];
1208 }
1209 }
1210
1211 *max_fd = this_max_fd;
1212
1213 return CURLM_OK;
1214 }
1215
curl_multi_waitfds(struct Curl_multi * multi,struct curl_waitfd * ufds,unsigned int size,unsigned int * fd_count)1216 CURLMcode curl_multi_waitfds(struct Curl_multi *multi,
1217 struct curl_waitfd *ufds,
1218 unsigned int size,
1219 unsigned int *fd_count)
1220 {
1221 struct Curl_easy *data;
1222 unsigned int nfds = 0;
1223 struct easy_pollset ps;
1224 unsigned int i;
1225 CURLMcode result = CURLM_OK;
1226 struct curl_waitfd *ufd;
1227 unsigned int j;
1228
1229 if(!ufds)
1230 return CURLM_BAD_FUNCTION_ARGUMENT;
1231
1232 if(!GOOD_MULTI_HANDLE(multi))
1233 return CURLM_BAD_HANDLE;
1234
1235 if(multi->in_callback)
1236 return CURLM_RECURSIVE_API_CALL;
1237
1238 memset(&ps, 0, sizeof(ps));
1239 for(data = multi->easyp; data; data = data->next) {
1240 multi_getsock(data, &ps);
1241
1242 for(i = 0; i < ps.num; i++) {
1243 if(nfds < size) {
1244 curl_socket_t fd = ps.sockets[i];
1245 int fd_idx = -1;
1246
1247 /* Simple linear search to skip an already added descriptor */
1248 for(j = 0; j < nfds; j++) {
1249 if(ufds[j].fd == fd) {
1250 fd_idx = (int)j;
1251 break;
1252 }
1253 }
1254
1255 if(fd_idx < 0) {
1256 ufd = &ufds[nfds++];
1257 ufd->fd = ps.sockets[i];
1258 ufd->events = 0;
1259 }
1260 else
1261 ufd = &ufds[fd_idx];
1262
1263 if(ps.actions[i] & CURL_POLL_IN)
1264 ufd->events |= CURL_WAIT_POLLIN;
1265 if(ps.actions[i] & CURL_POLL_OUT)
1266 ufd->events |= CURL_WAIT_POLLOUT;
1267 }
1268 else
1269 return CURLM_OUT_OF_MEMORY;
1270 }
1271 }
1272
1273 if(fd_count)
1274 *fd_count = nfds;
1275 return result;
1276 }
1277
1278 #ifdef USE_WINSOCK
1279 /* Reset FD_WRITE for TCP sockets. Nothing is actually sent. UDP sockets can't
1280 * be reset this way because an empty datagram would be sent. #9203
1281 *
1282 * "On Windows the internal state of FD_WRITE as returned from
1283 * WSAEnumNetworkEvents is only reset after successful send()."
1284 */
reset_socket_fdwrite(curl_socket_t s)1285 static void reset_socket_fdwrite(curl_socket_t s)
1286 {
1287 int t;
1288 int l = (int)sizeof(t);
1289 if(!getsockopt(s, SOL_SOCKET, SO_TYPE, (char *)&t, &l) && t == SOCK_STREAM)
1290 send(s, NULL, 0, 0);
1291 }
1292 #endif
1293
ufds_increase(struct pollfd ** pfds,unsigned int * pfds_len,unsigned int inc,bool * is_malloced)1294 static CURLMcode ufds_increase(struct pollfd **pfds, unsigned int *pfds_len,
1295 unsigned int inc, bool *is_malloced)
1296 {
1297 struct pollfd *new_fds, *old_fds = *pfds;
1298 unsigned int new_len = *pfds_len + inc;
1299
1300 new_fds = calloc(new_len, sizeof(struct pollfd));
1301 if(!new_fds) {
1302 if(*is_malloced)
1303 free(old_fds);
1304 *pfds = NULL;
1305 *pfds_len = 0;
1306 return CURLM_OUT_OF_MEMORY;
1307 }
1308 memcpy(new_fds, old_fds, (*pfds_len) * sizeof(struct pollfd));
1309 if(*is_malloced)
1310 free(old_fds);
1311 *pfds = new_fds;
1312 *pfds_len = new_len;
1313 *is_malloced = TRUE;
1314 return CURLM_OK;
1315 }
1316
1317 #define NUM_POLLS_ON_STACK 10
1318
multi_wait(struct Curl_multi * multi,struct curl_waitfd extra_fds[],unsigned int extra_nfds,int timeout_ms,int * ret,bool extrawait,bool use_wakeup)1319 static CURLMcode multi_wait(struct Curl_multi *multi,
1320 struct curl_waitfd extra_fds[],
1321 unsigned int extra_nfds,
1322 int timeout_ms,
1323 int *ret,
1324 bool extrawait, /* when no socket, wait */
1325 bool use_wakeup)
1326 {
1327 struct Curl_easy *data;
1328 struct easy_pollset ps;
1329 size_t i;
1330 long timeout_internal;
1331 int retcode = 0;
1332 struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
1333 struct pollfd *ufds = &a_few_on_stack[0];
1334 unsigned int ufds_len = NUM_POLLS_ON_STACK;
1335 unsigned int nfds = 0, curl_nfds = 0; /* how many ufds are in use */
1336 bool ufds_malloc = FALSE;
1337 #ifdef USE_WINSOCK
1338 WSANETWORKEVENTS wsa_events;
1339 DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
1340 #endif
1341 #ifndef ENABLE_WAKEUP
1342 (void)use_wakeup;
1343 #endif
1344
1345 if(!GOOD_MULTI_HANDLE(multi))
1346 return CURLM_BAD_HANDLE;
1347
1348 if(multi->in_callback)
1349 return CURLM_RECURSIVE_API_CALL;
1350
1351 if(timeout_ms < 0)
1352 return CURLM_BAD_FUNCTION_ARGUMENT;
1353
1354 /* If the internally desired timeout is actually shorter than requested from
1355 the outside, then use the shorter time! But only if the internal timer
1356 is actually larger than -1! */
1357 (void)multi_timeout(multi, &timeout_internal);
1358 if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
1359 timeout_ms = (int)timeout_internal;
1360
1361 memset(ufds, 0, ufds_len * sizeof(struct pollfd));
1362 memset(&ps, 0, sizeof(ps));
1363
1364 /* Add the curl handles to our pollfds first */
1365 for(data = multi->easyp; data; data = data->next) {
1366 multi_getsock(data, &ps);
1367
1368 for(i = 0; i < ps.num; i++) {
1369 short events = 0;
1370 #ifdef USE_WINSOCK
1371 long mask = 0;
1372 #endif
1373 if(ps.actions[i] & CURL_POLL_IN) {
1374 #ifdef USE_WINSOCK
1375 mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
1376 #endif
1377 events |= POLLIN;
1378 }
1379 if(ps.actions[i] & CURL_POLL_OUT) {
1380 #ifdef USE_WINSOCK
1381 mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
1382 reset_socket_fdwrite(ps.sockets[i]);
1383 #endif
1384 events |= POLLOUT;
1385 }
1386 if(events) {
1387 if(nfds && ps.sockets[i] == ufds[nfds-1].fd) {
1388 ufds[nfds-1].events |= events;
1389 }
1390 else {
1391 if(nfds >= ufds_len) {
1392 if(ufds_increase(&ufds, &ufds_len, 100, &ufds_malloc))
1393 return CURLM_OUT_OF_MEMORY;
1394 }
1395 DEBUGASSERT(nfds < ufds_len);
1396 ufds[nfds].fd = ps.sockets[i];
1397 ufds[nfds].events = events;
1398 ++nfds;
1399 }
1400 }
1401 #ifdef USE_WINSOCK
1402 if(mask) {
1403 if(WSAEventSelect(ps.sockets[i], multi->wsa_event, mask) != 0) {
1404 if(ufds_malloc)
1405 free(ufds);
1406 return CURLM_INTERNAL_ERROR;
1407 }
1408 }
1409 #endif
1410 }
1411 }
1412
1413 curl_nfds = nfds; /* what curl internally used in ufds */
1414
1415 /* Add external file descriptions from poll-like struct curl_waitfd */
1416 for(i = 0; i < extra_nfds; i++) {
1417 #ifdef USE_WINSOCK
1418 long mask = 0;
1419 if(extra_fds[i].events & CURL_WAIT_POLLIN)
1420 mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
1421 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1422 mask |= FD_OOB;
1423 if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
1424 mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
1425 reset_socket_fdwrite(extra_fds[i].fd);
1426 }
1427 if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) {
1428 if(ufds_malloc)
1429 free(ufds);
1430 return CURLM_INTERNAL_ERROR;
1431 }
1432 #endif
1433 if(nfds >= ufds_len) {
1434 if(ufds_increase(&ufds, &ufds_len, 100, &ufds_malloc))
1435 return CURLM_OUT_OF_MEMORY;
1436 }
1437 DEBUGASSERT(nfds < ufds_len);
1438 ufds[nfds].fd = extra_fds[i].fd;
1439 ufds[nfds].events = 0;
1440 if(extra_fds[i].events & CURL_WAIT_POLLIN)
1441 ufds[nfds].events |= POLLIN;
1442 if(extra_fds[i].events & CURL_WAIT_POLLPRI)
1443 ufds[nfds].events |= POLLPRI;
1444 if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1445 ufds[nfds].events |= POLLOUT;
1446 ++nfds;
1447 }
1448
1449 #ifdef ENABLE_WAKEUP
1450 #ifndef USE_WINSOCK
1451 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1452 if(nfds >= ufds_len) {
1453 if(ufds_increase(&ufds, &ufds_len, 100, &ufds_malloc))
1454 return CURLM_OUT_OF_MEMORY;
1455 }
1456 DEBUGASSERT(nfds < ufds_len);
1457 ufds[nfds].fd = multi->wakeup_pair[0];
1458 ufds[nfds].events = POLLIN;
1459 ++nfds;
1460 }
1461 #endif
1462 #endif
1463
1464 #if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK)
1465 if(nfds || use_wakeup) {
1466 #else
1467 if(nfds) {
1468 #endif
1469 int pollrc;
1470 #ifdef USE_WINSOCK
1471 if(nfds)
1472 pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */
1473 else
1474 pollrc = 0;
1475 #else
1476 pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
1477 #endif
1478 if(pollrc < 0)
1479 return CURLM_UNRECOVERABLE_POLL;
1480
1481 if(pollrc > 0) {
1482 retcode = pollrc;
1483 #ifdef USE_WINSOCK
1484 }
1485 else { /* now wait... if not ready during the pre-check (pollrc == 0) */
1486 WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
1487 }
1488 /* With WinSock, we have to run the following section unconditionally
1489 to call WSAEventSelect(fd, event, 0) on all the sockets */
1490 {
1491 #endif
1492 /* copy revents results from the poll to the curl_multi_wait poll
1493 struct, the bit values of the actual underlying poll() implementation
1494 may not be the same as the ones in the public libcurl API! */
1495 for(i = 0; i < extra_nfds; i++) {
1496 unsigned r = ufds[curl_nfds + i].revents;
1497 unsigned short mask = 0;
1498 #ifdef USE_WINSOCK
1499 curl_socket_t s = extra_fds[i].fd;
1500 wsa_events.lNetworkEvents = 0;
1501 if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) {
1502 if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE))
1503 mask |= CURL_WAIT_POLLIN;
1504 if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE))
1505 mask |= CURL_WAIT_POLLOUT;
1506 if(wsa_events.lNetworkEvents & FD_OOB)
1507 mask |= CURL_WAIT_POLLPRI;
1508 if(ret && !pollrc && wsa_events.lNetworkEvents)
1509 retcode++;
1510 }
1511 WSAEventSelect(s, multi->wsa_event, 0);
1512 if(!pollrc) {
1513 extra_fds[i].revents = mask;
1514 continue;
1515 }
1516 #endif
1517 if(r & POLLIN)
1518 mask |= CURL_WAIT_POLLIN;
1519 if(r & POLLOUT)
1520 mask |= CURL_WAIT_POLLOUT;
1521 if(r & POLLPRI)
1522 mask |= CURL_WAIT_POLLPRI;
1523 extra_fds[i].revents = mask;
1524 }
1525
1526 #ifdef USE_WINSOCK
1527 /* Count up all our own sockets that had activity,
1528 and remove them from the event. */
1529 if(curl_nfds) {
1530
1531 for(data = multi->easyp; data; data = data->next) {
1532 multi_getsock(data, &ps);
1533
1534 for(i = 0; i < ps.num; i++) {
1535 wsa_events.lNetworkEvents = 0;
1536 if(WSAEnumNetworkEvents(ps.sockets[i], NULL,
1537 &wsa_events) == 0) {
1538 if(ret && !pollrc && wsa_events.lNetworkEvents)
1539 retcode++;
1540 }
1541 WSAEventSelect(ps.sockets[i], multi->wsa_event, 0);
1542 }
1543 }
1544 }
1545
1546 WSAResetEvent(multi->wsa_event);
1547 #else
1548 #ifdef ENABLE_WAKEUP
1549 if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
1550 if(ufds[curl_nfds + extra_nfds].revents & POLLIN) {
1551 char buf[64];
1552 ssize_t nread;
1553 while(1) {
1554 /* the reading socket is non-blocking, try to read
1555 data from it until it receives an error (except EINTR).
1556 In normal cases it will get EAGAIN or EWOULDBLOCK
1557 when there is no more data, breaking the loop. */
1558 nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf));
1559 if(nread <= 0) {
1560 if(nread < 0 && EINTR == SOCKERRNO)
1561 continue;
1562 break;
1563 }
1564 }
1565 /* do not count the wakeup socket into the returned value */
1566 retcode--;
1567 }
1568 }
1569 #endif
1570 #endif
1571 }
1572 }
1573
1574 if(ufds_malloc)
1575 free(ufds);
1576 if(ret)
1577 *ret = retcode;
1578 #if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK)
1579 if(extrawait && !nfds && !use_wakeup) {
1580 #else
1581 if(extrawait && !nfds) {
1582 #endif
1583 long sleep_ms = 0;
1584
1585 /* Avoid busy-looping when there's nothing particular to wait for */
1586 if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
1587 if(sleep_ms > timeout_ms)
1588 sleep_ms = timeout_ms;
1589 /* when there are no easy handles in the multi, this holds a -1
1590 timeout */
1591 else if(sleep_ms < 0)
1592 sleep_ms = timeout_ms;
1593 Curl_wait_ms(sleep_ms);
1594 }
1595 }
1596
1597 return CURLM_OK;
1598 }
1599
1600 CURLMcode curl_multi_wait(struct Curl_multi *multi,
1601 struct curl_waitfd extra_fds[],
1602 unsigned int extra_nfds,
1603 int timeout_ms,
1604 int *ret)
1605 {
1606 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
1607 FALSE);
1608 }
1609
1610 CURLMcode curl_multi_poll(struct Curl_multi *multi,
1611 struct curl_waitfd extra_fds[],
1612 unsigned int extra_nfds,
1613 int timeout_ms,
1614 int *ret)
1615 {
1616 return multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
1617 TRUE);
1618 }
1619
1620 CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
1621 {
1622 /* this function is usually called from another thread,
1623 it has to be careful only to access parts of the
1624 Curl_multi struct that are constant */
1625
1626 /* GOOD_MULTI_HANDLE can be safely called */
1627 if(!GOOD_MULTI_HANDLE(multi))
1628 return CURLM_BAD_HANDLE;
1629
1630 #ifdef ENABLE_WAKEUP
1631 #ifdef USE_WINSOCK
1632 if(WSASetEvent(multi->wsa_event))
1633 return CURLM_OK;
1634 #else
1635 /* the wakeup_pair variable is only written during init and cleanup,
1636 making it safe to access from another thread after the init part
1637 and before cleanup */
1638 if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
1639 char buf[1];
1640 buf[0] = 1;
1641 while(1) {
1642 /* swrite() is not thread-safe in general, because concurrent calls
1643 can have their messages interleaved, but in this case the content
1644 of the messages does not matter, which makes it ok to call.
1645
1646 The write socket is set to non-blocking, this way this function
1647 cannot block, making it safe to call even from the same thread
1648 that will call curl_multi_wait(). If swrite() returns that it
1649 would block, it's considered successful because it means that
1650 previous calls to this function will wake up the poll(). */
1651 if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
1652 int err = SOCKERRNO;
1653 int return_success;
1654 #ifdef USE_WINSOCK
1655 return_success = WSAEWOULDBLOCK == err;
1656 #else
1657 if(EINTR == err)
1658 continue;
1659 return_success = EWOULDBLOCK == err || EAGAIN == err;
1660 #endif
1661 if(!return_success)
1662 return CURLM_WAKEUP_FAILURE;
1663 }
1664 return CURLM_OK;
1665 }
1666 }
1667 #endif
1668 #endif
1669 return CURLM_WAKEUP_FAILURE;
1670 }
1671
1672 /*
1673 * multi_ischanged() is called
1674 *
1675 * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
1676 * => CONNECT action.
1677 *
1678 * Set 'clear' to TRUE to have it also clear the state variable.
1679 */
1680 static bool multi_ischanged(struct Curl_multi *multi, bool clear)
1681 {
1682 bool retval = multi->recheckstate;
1683 if(clear)
1684 multi->recheckstate = FALSE;
1685 return retval;
1686 }
1687
1688 /*
1689 * Curl_multi_connchanged() is called to tell that there is a connection in
1690 * this multi handle that has changed state (multiplexing become possible, the
1691 * number of allowed streams changed or similar), and a subsequent use of this
1692 * multi handle should move CONNECT_PEND handles back to CONNECT to have them
1693 * retry.
1694 */
1695 void Curl_multi_connchanged(struct Curl_multi *multi)
1696 {
1697 multi->recheckstate = TRUE;
1698 }
1699
1700 CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
1701 struct Curl_easy *data,
1702 struct connectdata *conn)
1703 {
1704 CURLMcode rc;
1705
1706 if(multi->in_callback)
1707 return CURLM_RECURSIVE_API_CALL;
1708
1709 rc = curl_multi_add_handle(multi, data);
1710 if(!rc) {
1711 struct SingleRequest *k = &data->req;
1712
1713 /* pass in NULL for 'conn' here since we don't want to init the
1714 connection, only this transfer */
1715 Curl_init_do(data, NULL);
1716
1717 /* take this handle to the perform state right away */
1718 multistate(data, MSTATE_PERFORMING);
1719 Curl_attach_connection(data, conn);
1720 k->keepon |= KEEP_RECV; /* setup to receive! */
1721 }
1722 return rc;
1723 }
1724
1725 static CURLcode multi_do(struct Curl_easy *data, bool *done)
1726 {
1727 CURLcode result = CURLE_OK;
1728 struct connectdata *conn = data->conn;
1729
1730 DEBUGASSERT(conn);
1731 DEBUGASSERT(conn->handler);
1732
1733 if(conn->handler->do_it)
1734 result = conn->handler->do_it(data, done);
1735
1736 return result;
1737 }
1738
1739 /*
1740 * multi_do_more() is called during the DO_MORE multi state. It is basically a
1741 * second stage DO state which (wrongly) was introduced to support FTP's
1742 * second connection.
1743 *
1744 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
1745 * DOING state there's more work to do!
1746 */
1747
1748 static CURLcode multi_do_more(struct Curl_easy *data, int *complete)
1749 {
1750 CURLcode result = CURLE_OK;
1751 struct connectdata *conn = data->conn;
1752
1753 *complete = 0;
1754
1755 if(conn->handler->do_more)
1756 result = conn->handler->do_more(data, complete);
1757
1758 return result;
1759 }
1760
1761 /*
1762 * Check whether a timeout occurred, and handle it if it did
1763 */
1764 static bool multi_handle_timeout(struct Curl_easy *data,
1765 struct curltime *now,
1766 bool *stream_error,
1767 CURLcode *result,
1768 bool connect_timeout)
1769 {
1770 timediff_t timeout_ms = Curl_timeleft(data, now, connect_timeout);
1771 if(timeout_ms < 0) {
1772 /* Handle timed out */
1773 struct curltime since;
1774 if(connect_timeout)
1775 since = data->progress.t_startsingle;
1776 else
1777 since = data->progress.t_startop;
1778 if(data->mstate == MSTATE_RESOLVING)
1779 failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
1780 " milliseconds", Curl_timediff(*now, since));
1781 else if(data->mstate == MSTATE_CONNECTING)
1782 failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
1783 " milliseconds", Curl_timediff(*now, since));
1784 else {
1785 struct SingleRequest *k = &data->req;
1786 if(k->size != -1) {
1787 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
1788 " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
1789 CURL_FORMAT_CURL_OFF_T " bytes received",
1790 Curl_timediff(*now, since), k->bytecount, k->size);
1791 }
1792 else {
1793 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
1794 " milliseconds with %" CURL_FORMAT_CURL_OFF_T
1795 " bytes received", Curl_timediff(*now, since), k->bytecount);
1796 }
1797 }
1798 *result = CURLE_OPERATION_TIMEDOUT;
1799 if(data->conn) {
1800 /* Force connection closed if the connection has indeed been used */
1801 if(data->mstate > MSTATE_DO) {
1802 streamclose(data->conn, "Disconnect due to timeout");
1803 *stream_error = TRUE;
1804 }
1805 (void)multi_done(data, *result, TRUE);
1806 }
1807 return TRUE;
1808 }
1809
1810 return FALSE;
1811 }
1812
1813 /*
1814 * We are doing protocol-specific connecting and this is being called over and
1815 * over from the multi interface until the connection phase is done on
1816 * protocol layer.
1817 */
1818
1819 static CURLcode protocol_connecting(struct Curl_easy *data, bool *done)
1820 {
1821 CURLcode result = CURLE_OK;
1822 struct connectdata *conn = data->conn;
1823
1824 if(conn && conn->handler->connecting) {
1825 *done = FALSE;
1826 result = conn->handler->connecting(data, done);
1827 }
1828 else
1829 *done = TRUE;
1830
1831 return result;
1832 }
1833
1834 /*
1835 * We are DOING this is being called over and over from the multi interface
1836 * until the DOING phase is done on protocol layer.
1837 */
1838
1839 static CURLcode protocol_doing(struct Curl_easy *data, bool *done)
1840 {
1841 CURLcode result = CURLE_OK;
1842 struct connectdata *conn = data->conn;
1843
1844 if(conn && conn->handler->doing) {
1845 *done = FALSE;
1846 result = conn->handler->doing(data, done);
1847 }
1848 else
1849 *done = TRUE;
1850
1851 return result;
1852 }
1853
1854 /*
1855 * We have discovered that the TCP connection has been successful, we can now
1856 * proceed with some action.
1857 *
1858 */
1859 static CURLcode protocol_connect(struct Curl_easy *data,
1860 bool *protocol_done)
1861 {
1862 CURLcode result = CURLE_OK;
1863 struct connectdata *conn = data->conn;
1864 DEBUGASSERT(conn);
1865 DEBUGASSERT(protocol_done);
1866
1867 *protocol_done = FALSE;
1868
1869 if(Curl_conn_is_connected(conn, FIRSTSOCKET)
1870 && conn->bits.protoconnstart) {
1871 /* We already are connected, get back. This may happen when the connect
1872 worked fine in the first call, like when we connect to a local server
1873 or proxy. Note that we don't know if the protocol is actually done.
1874
1875 Unless this protocol doesn't have any protocol-connect callback, as
1876 then we know we're done. */
1877 if(!conn->handler->connecting)
1878 *protocol_done = TRUE;
1879
1880 return CURLE_OK;
1881 }
1882
1883 if(!conn->bits.protoconnstart) {
1884 if(conn->handler->connect_it) {
1885 /* is there a protocol-specific connect() procedure? */
1886
1887 /* Call the protocol-specific connect function */
1888 result = conn->handler->connect_it(data, protocol_done);
1889 }
1890 else
1891 *protocol_done = TRUE;
1892
1893 /* it has started, possibly even completed but that knowledge isn't stored
1894 in this bit! */
1895 if(!result)
1896 conn->bits.protoconnstart = TRUE;
1897 }
1898
1899 return result; /* pass back status */
1900 }
1901
1902 static void set_in_callback(struct Curl_multi *multi, bool value)
1903 {
1904 multi->in_callback = value;
1905 }
1906
1907 static CURLMcode multi_runsingle(struct Curl_multi *multi,
1908 struct curltime *nowp,
1909 struct Curl_easy *data)
1910 {
1911 struct Curl_message *msg = NULL;
1912 bool connected;
1913 bool async;
1914 bool protocol_connected = FALSE;
1915 bool dophase_done = FALSE;
1916 CURLMcode rc;
1917 CURLcode result = CURLE_OK;
1918 timediff_t recv_timeout_ms;
1919 timediff_t send_timeout_ms;
1920 int control;
1921
1922 if(!GOOD_EASY_HANDLE(data))
1923 return CURLM_BAD_EASY_HANDLE;
1924
1925 if(multi->dead) {
1926 /* a multi-level callback returned error before, meaning every individual
1927 transfer now has failed */
1928 result = CURLE_ABORTED_BY_CALLBACK;
1929 Curl_posttransfer(data);
1930 multi_done(data, result, FALSE);
1931 multistate(data, MSTATE_COMPLETED);
1932 }
1933
1934 multi_warn_debug(multi, data);
1935
1936 do {
1937 /* A "stream" here is a logical stream if the protocol can handle that
1938 (HTTP/2), or the full connection for older protocols */
1939 bool stream_error = FALSE;
1940 rc = CURLM_OK;
1941
1942 if(multi_ischanged(multi, TRUE)) {
1943 DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue"));
1944 process_pending_handles(multi); /* multiplexed */
1945 }
1946
1947 if(data->mstate > MSTATE_CONNECT &&
1948 data->mstate < MSTATE_COMPLETED) {
1949 /* Make sure we set the connection's current owner */
1950 DEBUGASSERT(data->conn);
1951 if(!data->conn)
1952 return CURLM_INTERNAL_ERROR;
1953 }
1954
1955 /* Wait for the connect state as only then is the start time stored, but
1956 we must not check already completed handles */
1957 if((data->mstate >= MSTATE_CONNECT) && (data->mstate < MSTATE_COMPLETED) &&
1958 multi_handle_timeout(data, nowp, &stream_error, &result, FALSE))
1959 /* Skip the statemachine and go directly to error handling section. */
1960 goto statemachine_end;
1961
1962 switch(data->mstate) {
1963 case MSTATE_INIT:
1964 /* Transitional state. init this transfer. A handle never comes
1965 back to this state. */
1966 result = Curl_pretransfer(data);
1967 if(result)
1968 break;
1969
1970 /* after init, go SETUP */
1971 multistate(data, MSTATE_SETUP);
1972 (void)Curl_pgrsTime(data, TIMER_STARTOP);
1973 FALLTHROUGH();
1974
1975 case MSTATE_SETUP:
1976 /* Transitional state. Setup things for a new transfer. The handle
1977 can come back to this state on a redirect. */
1978 *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
1979 if(data->set.timeout)
1980 Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
1981 if(data->set.connecttimeout)
1982 /* Since a connection might go to pending and back to CONNECT several
1983 times before it actually takes off, we need to set the timeout once
1984 in SETUP before we enter CONNECT the first time. */
1985 Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
1986
1987 multistate(data, MSTATE_CONNECT);
1988 FALLTHROUGH();
1989
1990 case MSTATE_CONNECT:
1991 /* Connect. We want to get a connection identifier filled in. This state
1992 can be entered from SETUP and from PENDING. */
1993 result = Curl_connect(data, &async, &connected);
1994 if(CURLE_NO_CONNECTION_AVAILABLE == result) {
1995 /* There was no connection available. We will go to the pending
1996 state and wait for an available connection. */
1997 multistate(data, MSTATE_PENDING);
1998
1999 /* add this handle to the list of connect-pending handles */
2000 Curl_llist_append(&multi->pending, data, &data->connect_queue);
2001 /* unlink from the main list */
2002 unlink_easy(multi, data);
2003 result = CURLE_OK;
2004 break;
2005 }
2006 else
2007 process_pending_handles(data->multi);
2008
2009 if(!result) {
2010 *nowp = Curl_pgrsTime(data, TIMER_POSTQUEUE);
2011 if(async)
2012 /* We're now waiting for an asynchronous name lookup */
2013 multistate(data, MSTATE_RESOLVING);
2014 else {
2015 /* after the connect has been sent off, go WAITCONNECT unless the
2016 protocol connect is already done and we can go directly to
2017 WAITDO or DO! */
2018 rc = CURLM_CALL_MULTI_PERFORM;
2019
2020 if(connected)
2021 multistate(data, MSTATE_PROTOCONNECT);
2022 else {
2023 multistate(data, MSTATE_CONNECTING);
2024 }
2025 }
2026 }
2027 break;
2028
2029 case MSTATE_RESOLVING:
2030 /* awaiting an asynch name resolve to complete */
2031 {
2032 struct Curl_dns_entry *dns = NULL;
2033 struct connectdata *conn = data->conn;
2034 const char *hostname;
2035
2036 DEBUGASSERT(conn);
2037 #ifndef CURL_DISABLE_PROXY
2038 if(conn->bits.httpproxy)
2039 hostname = conn->http_proxy.host.name;
2040 else
2041 #endif
2042 if(conn->bits.conn_to_host)
2043 hostname = conn->conn_to_host.name;
2044 else
2045 hostname = conn->host.name;
2046
2047 /* check if we have the name resolved by now */
2048 dns = Curl_fetch_addr(data, hostname, conn->primary.remote_port);
2049
2050 if(dns) {
2051 #ifdef CURLRES_ASYNCH
2052 data->state.async.dns = dns;
2053 data->state.async.done = TRUE;
2054 #endif
2055 result = CURLE_OK;
2056 infof(data, "Hostname '%s' was found in DNS cache", hostname);
2057 }
2058
2059 if(!dns)
2060 result = Curl_resolv_check(data, &dns);
2061
2062 /* Update sockets here, because the socket(s) may have been
2063 closed and the application thus needs to be told, even if it
2064 is likely that the same socket(s) will again be used further
2065 down. If the name has not yet been resolved, it is likely
2066 that new sockets have been opened in an attempt to contact
2067 another resolver. */
2068 rc = singlesocket(multi, data);
2069 if(rc)
2070 return rc;
2071
2072 if(dns) {
2073 /* Perform the next step in the connection phase, and then move on
2074 to the WAITCONNECT state */
2075 result = Curl_once_resolved(data, &connected);
2076
2077 if(result)
2078 /* if Curl_once_resolved() returns failure, the connection struct
2079 is already freed and gone */
2080 data->conn = NULL; /* no more connection */
2081 else {
2082 /* call again please so that we get the next socket setup */
2083 rc = CURLM_CALL_MULTI_PERFORM;
2084 if(connected)
2085 multistate(data, MSTATE_PROTOCONNECT);
2086 else {
2087 multistate(data, MSTATE_CONNECTING);
2088 }
2089 }
2090 }
2091
2092 if(result) {
2093 /* failure detected */
2094 stream_error = TRUE;
2095 break;
2096 }
2097 }
2098 break;
2099
2100 #ifndef CURL_DISABLE_HTTP
2101 case MSTATE_TUNNELING:
2102 /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
2103 DEBUGASSERT(data->conn);
2104 result = Curl_http_connect(data, &protocol_connected);
2105 #ifndef CURL_DISABLE_PROXY
2106 if(data->conn->bits.proxy_connect_closed) {
2107 rc = CURLM_CALL_MULTI_PERFORM;
2108 /* connect back to proxy again */
2109 result = CURLE_OK;
2110 multi_done(data, CURLE_OK, FALSE);
2111 multistate(data, MSTATE_CONNECT);
2112 }
2113 else
2114 #endif
2115 if(!result) {
2116 rc = CURLM_CALL_MULTI_PERFORM;
2117 /* initiate protocol connect phase */
2118 multistate(data, MSTATE_PROTOCONNECT);
2119 }
2120 else
2121 stream_error = TRUE;
2122 break;
2123 #endif
2124
2125 case MSTATE_CONNECTING:
2126 /* awaiting a completion of an asynch TCP connect */
2127 DEBUGASSERT(data->conn);
2128 result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
2129 if(connected && !result) {
2130 rc = CURLM_CALL_MULTI_PERFORM;
2131 multistate(data, MSTATE_PROTOCONNECT);
2132 }
2133 else if(result) {
2134 /* failure detected */
2135 Curl_posttransfer(data);
2136 multi_done(data, result, TRUE);
2137 stream_error = TRUE;
2138 break;
2139 }
2140 break;
2141
2142 case MSTATE_PROTOCONNECT:
2143 if(!result && data->conn->bits.reuse) {
2144 /* ftp seems to hang when protoconnect on reused connection
2145 * since we handle PROTOCONNECT in general inside the filers, it
2146 * seems wrong to restart this on a reused connection. */
2147 multistate(data, MSTATE_DO);
2148 rc = CURLM_CALL_MULTI_PERFORM;
2149 break;
2150 }
2151 if(!result)
2152 result = protocol_connect(data, &protocol_connected);
2153 if(!result && !protocol_connected) {
2154 /* switch to waiting state */
2155 multistate(data, MSTATE_PROTOCONNECTING);
2156 rc = CURLM_CALL_MULTI_PERFORM;
2157 }
2158 else if(!result) {
2159 /* protocol connect has completed, go WAITDO or DO */
2160 multistate(data, MSTATE_DO);
2161 rc = CURLM_CALL_MULTI_PERFORM;
2162 }
2163 else {
2164 /* failure detected */
2165 Curl_posttransfer(data);
2166 multi_done(data, result, TRUE);
2167 stream_error = TRUE;
2168 }
2169 break;
2170
2171 case MSTATE_PROTOCONNECTING:
2172 /* protocol-specific connect phase */
2173 result = protocol_connecting(data, &protocol_connected);
2174 if(!result && protocol_connected) {
2175 /* after the connect has completed, go WAITDO or DO */
2176 multistate(data, MSTATE_DO);
2177 rc = CURLM_CALL_MULTI_PERFORM;
2178 }
2179 else if(result) {
2180 /* failure detected */
2181 Curl_posttransfer(data);
2182 multi_done(data, result, TRUE);
2183 stream_error = TRUE;
2184 }
2185 break;
2186
2187 case MSTATE_DO:
2188 if(data->set.fprereq) {
2189 int prereq_rc;
2190
2191 /* call the prerequest callback function */
2192 Curl_set_in_callback(data, true);
2193 prereq_rc = data->set.fprereq(data->set.prereq_userp,
2194 data->info.primary.remote_ip,
2195 data->info.primary.local_ip,
2196 data->info.primary.remote_port,
2197 data->info.primary.local_port);
2198 Curl_set_in_callback(data, false);
2199 if(prereq_rc != CURL_PREREQFUNC_OK) {
2200 failf(data, "operation aborted by pre-request callback");
2201 /* failure in pre-request callback - don't do any other processing */
2202 result = CURLE_ABORTED_BY_CALLBACK;
2203 Curl_posttransfer(data);
2204 multi_done(data, result, FALSE);
2205 stream_error = TRUE;
2206 break;
2207 }
2208 }
2209
2210 if(data->set.connect_only == 1) {
2211 /* keep connection open for application to use the socket */
2212 connkeep(data->conn, "CONNECT_ONLY");
2213 multistate(data, MSTATE_DONE);
2214 result = CURLE_OK;
2215 rc = CURLM_CALL_MULTI_PERFORM;
2216 }
2217 else {
2218 /* Perform the protocol's DO action */
2219 result = multi_do(data, &dophase_done);
2220
2221 /* When multi_do() returns failure, data->conn might be NULL! */
2222
2223 if(!result) {
2224 if(!dophase_done) {
2225 #ifndef CURL_DISABLE_FTP
2226 /* some steps needed for wildcard matching */
2227 if(data->state.wildcardmatch) {
2228 struct WildcardData *wc = data->wildcard;
2229 if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
2230 /* skip some states if it is important */
2231 multi_done(data, CURLE_OK, FALSE);
2232
2233 /* if there's no connection left, skip the DONE state */
2234 multistate(data, data->conn ?
2235 MSTATE_DONE : MSTATE_COMPLETED);
2236 rc = CURLM_CALL_MULTI_PERFORM;
2237 break;
2238 }
2239 }
2240 #endif
2241 /* DO was not completed in one function call, we must continue
2242 DOING... */
2243 multistate(data, MSTATE_DOING);
2244 rc = CURLM_CALL_MULTI_PERFORM;
2245 }
2246
2247 /* after DO, go DO_DONE... or DO_MORE */
2248 else if(data->conn->bits.do_more) {
2249 /* we're supposed to do more, but we need to sit down, relax
2250 and wait a little while first */
2251 multistate(data, MSTATE_DOING_MORE);
2252 rc = CURLM_CALL_MULTI_PERFORM;
2253 }
2254 else {
2255 /* we're done with the DO, now DID */
2256 multistate(data, MSTATE_DID);
2257 rc = CURLM_CALL_MULTI_PERFORM;
2258 }
2259 }
2260 else if((CURLE_SEND_ERROR == result) &&
2261 data->conn->bits.reuse) {
2262 /*
2263 * In this situation, a connection that we were trying to use
2264 * may have unexpectedly died. If possible, send the connection
2265 * back to the CONNECT phase so we can try again.
2266 */
2267 char *newurl = NULL;
2268 followtype follow = FOLLOW_NONE;
2269 CURLcode drc;
2270
2271 drc = Curl_retry_request(data, &newurl);
2272 if(drc) {
2273 /* a failure here pretty much implies an out of memory */
2274 result = drc;
2275 stream_error = TRUE;
2276 }
2277
2278 Curl_posttransfer(data);
2279 drc = multi_done(data, result, FALSE);
2280
2281 /* When set to retry the connection, we must go back to the CONNECT
2282 * state */
2283 if(newurl) {
2284 if(!drc || (drc == CURLE_SEND_ERROR)) {
2285 follow = FOLLOW_RETRY;
2286 drc = Curl_follow(data, newurl, follow);
2287 if(!drc) {
2288 multistate(data, MSTATE_SETUP);
2289 rc = CURLM_CALL_MULTI_PERFORM;
2290 result = CURLE_OK;
2291 }
2292 else {
2293 /* Follow failed */
2294 result = drc;
2295 }
2296 }
2297 else {
2298 /* done didn't return OK or SEND_ERROR */
2299 result = drc;
2300 }
2301 }
2302 else {
2303 /* Have error handler disconnect conn if we can't retry */
2304 stream_error = TRUE;
2305 }
2306 free(newurl);
2307 }
2308 else {
2309 /* failure detected */
2310 Curl_posttransfer(data);
2311 if(data->conn)
2312 multi_done(data, result, FALSE);
2313 stream_error = TRUE;
2314 }
2315 }
2316 break;
2317
2318 case MSTATE_DOING:
2319 /* we continue DOING until the DO phase is complete */
2320 DEBUGASSERT(data->conn);
2321 result = protocol_doing(data, &dophase_done);
2322 if(!result) {
2323 if(dophase_done) {
2324 /* after DO, go DO_DONE or DO_MORE */
2325 multistate(data, data->conn->bits.do_more?
2326 MSTATE_DOING_MORE : MSTATE_DID);
2327 rc = CURLM_CALL_MULTI_PERFORM;
2328 } /* dophase_done */
2329 }
2330 else {
2331 /* failure detected */
2332 Curl_posttransfer(data);
2333 multi_done(data, result, FALSE);
2334 stream_error = TRUE;
2335 }
2336 break;
2337
2338 case MSTATE_DOING_MORE:
2339 /*
2340 * When we are connected, DOING MORE and then go DID
2341 */
2342 DEBUGASSERT(data->conn);
2343 result = multi_do_more(data, &control);
2344
2345 if(!result) {
2346 if(control) {
2347 /* if positive, advance to DO_DONE
2348 if negative, go back to DOING */
2349 multistate(data, control == 1?
2350 MSTATE_DID : MSTATE_DOING);
2351 rc = CURLM_CALL_MULTI_PERFORM;
2352 }
2353 /* else
2354 stay in DO_MORE */
2355 }
2356 else {
2357 /* failure detected */
2358 Curl_posttransfer(data);
2359 multi_done(data, result, FALSE);
2360 stream_error = TRUE;
2361 }
2362 break;
2363
2364 case MSTATE_DID:
2365 DEBUGASSERT(data->conn);
2366 if(data->conn->bits.multiplex)
2367 /* Check if we can move pending requests to send pipe */
2368 process_pending_handles(multi); /* multiplexed */
2369
2370 /* Only perform the transfer if there's a good socket to work with.
2371 Having both BAD is a signal to skip immediately to DONE */
2372 if((data->conn->sockfd != CURL_SOCKET_BAD) ||
2373 (data->conn->writesockfd != CURL_SOCKET_BAD))
2374 multistate(data, MSTATE_PERFORMING);
2375 else {
2376 #ifndef CURL_DISABLE_FTP
2377 if(data->state.wildcardmatch &&
2378 ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
2379 data->wildcard->state = CURLWC_DONE;
2380 }
2381 #endif
2382 multistate(data, MSTATE_DONE);
2383 }
2384 rc = CURLM_CALL_MULTI_PERFORM;
2385 break;
2386
2387 case MSTATE_RATELIMITING: /* limit-rate exceeded in either direction */
2388 DEBUGASSERT(data->conn);
2389 /* if both rates are within spec, resume transfer */
2390 if(Curl_pgrsUpdate(data))
2391 result = CURLE_ABORTED_BY_CALLBACK;
2392 else
2393 result = Curl_speedcheck(data, *nowp);
2394
2395 if(result) {
2396 if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2397 result != CURLE_HTTP2_STREAM)
2398 streamclose(data->conn, "Transfer returned error");
2399
2400 Curl_posttransfer(data);
2401 multi_done(data, result, TRUE);
2402 }
2403 else {
2404 send_timeout_ms = 0;
2405 if(data->set.max_send_speed)
2406 send_timeout_ms =
2407 Curl_pgrsLimitWaitTime(data->progress.uploaded,
2408 data->progress.ul_limit_size,
2409 data->set.max_send_speed,
2410 data->progress.ul_limit_start,
2411 *nowp);
2412
2413 recv_timeout_ms = 0;
2414 if(data->set.max_recv_speed)
2415 recv_timeout_ms =
2416 Curl_pgrsLimitWaitTime(data->progress.downloaded,
2417 data->progress.dl_limit_size,
2418 data->set.max_recv_speed,
2419 data->progress.dl_limit_start,
2420 *nowp);
2421
2422 if(!send_timeout_ms && !recv_timeout_ms) {
2423 multistate(data, MSTATE_PERFORMING);
2424 Curl_ratelimit(data, *nowp);
2425 }
2426 else if(send_timeout_ms >= recv_timeout_ms)
2427 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2428 else
2429 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2430 }
2431 break;
2432
2433 case MSTATE_PERFORMING:
2434 {
2435 char *newurl = NULL;
2436 bool retry = FALSE;
2437 /* check if over send speed */
2438 send_timeout_ms = 0;
2439 if(data->set.max_send_speed)
2440 send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
2441 data->progress.ul_limit_size,
2442 data->set.max_send_speed,
2443 data->progress.ul_limit_start,
2444 *nowp);
2445
2446 /* check if over recv speed */
2447 recv_timeout_ms = 0;
2448 if(data->set.max_recv_speed)
2449 recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
2450 data->progress.dl_limit_size,
2451 data->set.max_recv_speed,
2452 data->progress.dl_limit_start,
2453 *nowp);
2454
2455 if(send_timeout_ms || recv_timeout_ms) {
2456 Curl_ratelimit(data, *nowp);
2457 multistate(data, MSTATE_RATELIMITING);
2458 if(send_timeout_ms >= recv_timeout_ms)
2459 Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
2460 else
2461 Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
2462 break;
2463 }
2464
2465 /* read/write data if it is ready to do so */
2466 result = Curl_readwrite(data);
2467
2468 if(data->req.done || (result == CURLE_RECV_ERROR)) {
2469 /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
2470 * condition and the server closed the reused connection exactly when
2471 * we wanted to use it, so figure out if that is indeed the case.
2472 */
2473 CURLcode ret = Curl_retry_request(data, &newurl);
2474 if(!ret)
2475 retry = (newurl)?TRUE:FALSE;
2476 else if(!result)
2477 result = ret;
2478
2479 if(retry) {
2480 /* if we are to retry, set the result to OK and consider the
2481 request as done */
2482 result = CURLE_OK;
2483 data->req.done = TRUE;
2484 }
2485 }
2486 else if((CURLE_HTTP2_STREAM == result) &&
2487 Curl_h2_http_1_1_error(data)) {
2488 CURLcode ret = Curl_retry_request(data, &newurl);
2489
2490 if(!ret) {
2491 infof(data, "Downgrades to HTTP/1.1");
2492 streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
2493 data->state.httpwant = CURL_HTTP_VERSION_1_1;
2494 /* clear the error message bit too as we ignore the one we got */
2495 data->state.errorbuf = FALSE;
2496 if(!newurl)
2497 /* typically for HTTP_1_1_REQUIRED error on first flight */
2498 newurl = strdup(data->state.url);
2499 /* if we are to retry, set the result to OK and consider the request
2500 as done */
2501 retry = TRUE;
2502 result = CURLE_OK;
2503 data->req.done = TRUE;
2504 }
2505 else
2506 result = ret;
2507 }
2508
2509 if(result) {
2510 /*
2511 * The transfer phase returned error, we mark the connection to get
2512 * closed to prevent being reused. This is because we can't possibly
2513 * know if the connection is in a good shape or not now. Unless it is
2514 * a protocol which uses two "channels" like FTP, as then the error
2515 * happened in the data connection.
2516 */
2517
2518 if(!(data->conn->handler->flags & PROTOPT_DUAL) &&
2519 result != CURLE_HTTP2_STREAM)
2520 streamclose(data->conn, "Transfer returned error");
2521
2522 Curl_posttransfer(data);
2523 multi_done(data, result, TRUE);
2524 }
2525 else if(data->req.done && !Curl_cwriter_is_paused(data)) {
2526
2527 /* call this even if the readwrite function returned error */
2528 Curl_posttransfer(data);
2529
2530 /* When we follow redirects or is set to retry the connection, we must
2531 to go back to the CONNECT state */
2532 if(data->req.newurl || retry) {
2533 followtype follow = FOLLOW_NONE;
2534 if(!retry) {
2535 /* if the URL is a follow-location and not just a retried request
2536 then figure out the URL here */
2537 free(newurl);
2538 newurl = data->req.newurl;
2539 data->req.newurl = NULL;
2540 follow = FOLLOW_REDIR;
2541 }
2542 else
2543 follow = FOLLOW_RETRY;
2544 (void)multi_done(data, CURLE_OK, FALSE);
2545 /* multi_done() might return CURLE_GOT_NOTHING */
2546 result = Curl_follow(data, newurl, follow);
2547 if(!result) {
2548 multistate(data, MSTATE_SETUP);
2549 rc = CURLM_CALL_MULTI_PERFORM;
2550 }
2551 }
2552 else {
2553 /* after the transfer is done, go DONE */
2554
2555 /* but first check to see if we got a location info even though we're
2556 not following redirects */
2557 if(data->req.location) {
2558 free(newurl);
2559 newurl = data->req.location;
2560 data->req.location = NULL;
2561 result = Curl_follow(data, newurl, FOLLOW_FAKE);
2562 if(result) {
2563 stream_error = TRUE;
2564 result = multi_done(data, result, TRUE);
2565 }
2566 }
2567
2568 if(!result) {
2569 multistate(data, MSTATE_DONE);
2570 rc = CURLM_CALL_MULTI_PERFORM;
2571 }
2572 }
2573 }
2574 else if(data->state.select_bits) {
2575 /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer
2576 won't get stuck on this transfer at the expense of other concurrent
2577 transfers */
2578 Curl_expire(data, 0, EXPIRE_RUN_NOW);
2579 }
2580 free(newurl);
2581 break;
2582 }
2583
2584 case MSTATE_DONE:
2585 /* this state is highly transient, so run another loop after this */
2586 rc = CURLM_CALL_MULTI_PERFORM;
2587
2588 if(data->conn) {
2589 CURLcode res;
2590
2591 if(data->conn->bits.multiplex)
2592 /* Check if we can move pending requests to connection */
2593 process_pending_handles(multi); /* multiplexing */
2594
2595 /* post-transfer command */
2596 res = multi_done(data, result, FALSE);
2597
2598 /* allow a previously set error code take precedence */
2599 if(!result)
2600 result = res;
2601 }
2602
2603 #ifndef CURL_DISABLE_FTP
2604 if(data->state.wildcardmatch) {
2605 if(data->wildcard->state != CURLWC_DONE) {
2606 /* if a wildcard is set and we are not ending -> lets start again
2607 with MSTATE_INIT */
2608 multistate(data, MSTATE_INIT);
2609 break;
2610 }
2611 }
2612 #endif
2613 /* after we have DONE what we're supposed to do, go COMPLETED, and
2614 it doesn't matter what the multi_done() returned! */
2615 multistate(data, MSTATE_COMPLETED);
2616 break;
2617
2618 case MSTATE_COMPLETED:
2619 break;
2620
2621 case MSTATE_PENDING:
2622 case MSTATE_MSGSENT:
2623 /* handles in these states should NOT be in this list */
2624 DEBUGASSERT(0);
2625 break;
2626
2627 default:
2628 return CURLM_INTERNAL_ERROR;
2629 }
2630
2631 if(data->mstate >= MSTATE_CONNECT &&
2632 data->mstate < MSTATE_DO &&
2633 rc != CURLM_CALL_MULTI_PERFORM &&
2634 !multi_ischanged(multi, false)) {
2635 /* We now handle stream timeouts if and only if this will be the last
2636 * loop iteration. We only check this on the last iteration to ensure
2637 * that if we know we have additional work to do immediately
2638 * (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before
2639 * declaring the connection timed out as we may almost have a completed
2640 * connection. */
2641 multi_handle_timeout(data, nowp, &stream_error, &result, FALSE);
2642 }
2643
2644 statemachine_end:
2645
2646 if(data->mstate < MSTATE_COMPLETED) {
2647 if(result) {
2648 /*
2649 * If an error was returned, and we aren't in completed state now,
2650 * then we go to completed and consider this transfer aborted.
2651 */
2652
2653 /* NOTE: no attempt to disconnect connections must be made
2654 in the case blocks above - cleanup happens only here */
2655
2656 /* Check if we can move pending requests to send pipe */
2657 process_pending_handles(multi); /* connection */
2658
2659 if(data->conn) {
2660 if(stream_error) {
2661 /* Don't attempt to send data over a connection that timed out */
2662 bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
2663 struct connectdata *conn = data->conn;
2664
2665 /* This is where we make sure that the conn pointer is reset.
2666 We don't have to do this in every case block above where a
2667 failure is detected */
2668 Curl_detach_connection(data);
2669
2670 /* remove connection from cache */
2671 Curl_conncache_remove_conn(data, conn, TRUE);
2672
2673 /* disconnect properly */
2674 Curl_disconnect(data, conn, dead_connection);
2675 }
2676 }
2677 else if(data->mstate == MSTATE_CONNECT) {
2678 /* Curl_connect() failed */
2679 (void)Curl_posttransfer(data);
2680 }
2681
2682 multistate(data, MSTATE_COMPLETED);
2683 rc = CURLM_CALL_MULTI_PERFORM;
2684 }
2685 /* if there's still a connection to use, call the progress function */
2686 else if(data->conn && Curl_pgrsUpdate(data)) {
2687 /* aborted due to progress callback return code must close the
2688 connection */
2689 result = CURLE_ABORTED_BY_CALLBACK;
2690 streamclose(data->conn, "Aborted by callback");
2691
2692 /* if not yet in DONE state, go there, otherwise COMPLETED */
2693 multistate(data, (data->mstate < MSTATE_DONE)?
2694 MSTATE_DONE: MSTATE_COMPLETED);
2695 rc = CURLM_CALL_MULTI_PERFORM;
2696 }
2697 }
2698
2699 if(MSTATE_COMPLETED == data->mstate) {
2700 if(data->set.fmultidone) {
2701 /* signal via callback instead */
2702 data->set.fmultidone(data, result);
2703 }
2704 else {
2705 /* now fill in the Curl_message with this info */
2706 msg = &data->msg;
2707
2708 msg->extmsg.msg = CURLMSG_DONE;
2709 msg->extmsg.easy_handle = data;
2710 msg->extmsg.data.result = result;
2711
2712 multi_addmsg(multi, msg);
2713 DEBUGASSERT(!data->conn);
2714 }
2715 multistate(data, MSTATE_MSGSENT);
2716
2717 /* add this handle to the list of msgsent handles */
2718 Curl_llist_append(&multi->msgsent, data, &data->connect_queue);
2719 /* unlink from the main list */
2720 unlink_easy(multi, data);
2721 return CURLM_OK;
2722 }
2723 } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
2724
2725 data->result = result;
2726 return rc;
2727 }
2728
2729
2730 CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
2731 {
2732 struct Curl_easy *data;
2733 CURLMcode returncode = CURLM_OK;
2734 struct Curl_tree *t;
2735 struct curltime now = Curl_now();
2736
2737 if(!GOOD_MULTI_HANDLE(multi))
2738 return CURLM_BAD_HANDLE;
2739
2740 if(multi->in_callback)
2741 return CURLM_RECURSIVE_API_CALL;
2742
2743 data = multi->easyp;
2744 if(data) {
2745 CURLMcode result;
2746 bool nosig = data->set.no_signal;
2747 SIGPIPE_VARIABLE(pipe_st);
2748 sigpipe_ignore(data, &pipe_st);
2749 /* Do the loop and only alter the signal ignore state if the next handle
2750 has a different NO_SIGNAL state than the previous */
2751 do {
2752 /* the current node might be unlinked in multi_runsingle(), get the next
2753 pointer now */
2754 struct Curl_easy *datanext = data->next;
2755 if(data->set.no_signal != nosig) {
2756 sigpipe_restore(&pipe_st);
2757 sigpipe_ignore(data, &pipe_st);
2758 nosig = data->set.no_signal;
2759 }
2760 result = multi_runsingle(multi, &now, data);
2761 if(result)
2762 returncode = result;
2763 data = datanext; /* operate on next handle */
2764 } while(data);
2765 sigpipe_restore(&pipe_st);
2766 }
2767
2768 /*
2769 * Simply remove all expired timers from the splay since handles are dealt
2770 * with unconditionally by this function and curl_multi_timeout() requires
2771 * that already passed/handled expire times are removed from the splay.
2772 *
2773 * It is important that the 'now' value is set at the entry of this function
2774 * and not for the current time as it may have ticked a little while since
2775 * then and then we risk this loop to remove timers that actually have not
2776 * been handled!
2777 */
2778 do {
2779 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
2780 if(t) {
2781 /* the removed may have another timeout in queue */
2782 data = t->payload;
2783 if(data->mstate == MSTATE_PENDING) {
2784 bool stream_unused;
2785 CURLcode result_unused;
2786 if(multi_handle_timeout(data, &now, &stream_unused, &result_unused,
2787 FALSE)) {
2788 infof(data, "PENDING handle timeout");
2789 move_pending_to_connect(multi, data);
2790 }
2791 }
2792 (void)add_next_timeout(now, multi, t->payload);
2793 }
2794 } while(t);
2795
2796 *running_handles = multi->num_alive;
2797
2798 if(CURLM_OK >= returncode)
2799 returncode = Curl_update_timer(multi);
2800
2801 return returncode;
2802 }
2803
2804 /* unlink_all_msgsent_handles() detaches all those easy handles from this
2805 multi handle */
2806 static void unlink_all_msgsent_handles(struct Curl_multi *multi)
2807 {
2808 struct Curl_llist_element *e = multi->msgsent.head;
2809 if(e) {
2810 struct Curl_easy *data = e->ptr;
2811 DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
2812 data->multi = NULL;
2813 }
2814 }
2815
2816 CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
2817 {
2818 struct Curl_easy *data;
2819 struct Curl_easy *nextdata;
2820
2821 if(GOOD_MULTI_HANDLE(multi)) {
2822 if(multi->in_callback)
2823 return CURLM_RECURSIVE_API_CALL;
2824
2825 multi->magic = 0; /* not good anymore */
2826
2827 unlink_all_msgsent_handles(multi);
2828 process_pending_handles(multi);
2829 /* First remove all remaining easy handles */
2830 data = multi->easyp;
2831 while(data) {
2832 nextdata = data->next;
2833 if(!data->state.done && data->conn)
2834 /* if DONE was never called for this handle */
2835 (void)multi_done(data, CURLE_OK, TRUE);
2836 if(data->dns.hostcachetype == HCACHE_MULTI) {
2837 /* clear out the usage of the shared DNS cache */
2838 Curl_hostcache_clean(data, data->dns.hostcache);
2839 data->dns.hostcache = NULL;
2840 data->dns.hostcachetype = HCACHE_NONE;
2841 }
2842
2843 /* Clear the pointer to the connection cache */
2844 data->state.conn_cache = NULL;
2845 data->multi = NULL; /* clear the association */
2846
2847 #ifdef USE_LIBPSL
2848 if(data->psl == &multi->psl)
2849 data->psl = NULL;
2850 #endif
2851
2852 data = nextdata;
2853 }
2854
2855 /* Close all the connections in the connection cache */
2856 Curl_conncache_close_all_connections(&multi->conn_cache);
2857
2858 sockhash_destroy(&multi->sockhash);
2859 Curl_conncache_destroy(&multi->conn_cache);
2860 Curl_hash_destroy(&multi->hostcache);
2861 Curl_psl_destroy(&multi->psl);
2862
2863 #ifdef USE_WINSOCK
2864 WSACloseEvent(multi->wsa_event);
2865 #else
2866 #ifdef ENABLE_WAKEUP
2867 wakeup_close(multi->wakeup_pair[0]);
2868 wakeup_close(multi->wakeup_pair[1]);
2869 #endif
2870 #endif
2871
2872 #ifdef USE_SSL
2873 Curl_free_multi_ssl_backend_data(multi->ssl_backend_data);
2874 #endif
2875
2876 multi_xfer_bufs_free(multi);
2877 free(multi);
2878
2879 return CURLM_OK;
2880 }
2881 return CURLM_BAD_HANDLE;
2882 }
2883
2884 /*
2885 * curl_multi_info_read()
2886 *
2887 * This function is the primary way for a multi/multi_socket application to
2888 * figure out if a transfer has ended. We MUST make this function as fast as
2889 * possible as it will be polled frequently and we MUST NOT scan any lists in
2890 * here to figure out things. We must scale fine to thousands of handles and
2891 * beyond. The current design is fully O(1).
2892 */
2893
2894 CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
2895 {
2896 struct Curl_message *msg;
2897
2898 *msgs_in_queue = 0; /* default to none */
2899
2900 if(GOOD_MULTI_HANDLE(multi) &&
2901 !multi->in_callback &&
2902 Curl_llist_count(&multi->msglist)) {
2903 /* there is one or more messages in the list */
2904 struct Curl_llist_element *e;
2905
2906 /* extract the head of the list to return */
2907 e = multi->msglist.head;
2908
2909 msg = e->ptr;
2910
2911 /* remove the extracted entry */
2912 Curl_llist_remove(&multi->msglist, e, NULL);
2913
2914 *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
2915
2916 return &msg->extmsg;
2917 }
2918 return NULL;
2919 }
2920
2921 /*
2922 * singlesocket() checks what sockets we deal with and their "action state"
2923 * and if we have a different state in any of those sockets from last time we
2924 * call the callback accordingly.
2925 */
2926 static CURLMcode singlesocket(struct Curl_multi *multi,
2927 struct Curl_easy *data)
2928 {
2929 struct easy_pollset cur_poll;
2930 unsigned int i;
2931 struct Curl_sh_entry *entry;
2932 curl_socket_t s;
2933 int rc;
2934
2935 /* Fill in the 'current' struct with the state as it is now: what sockets to
2936 supervise and for what actions */
2937 multi_getsock(data, &cur_poll);
2938
2939 /* We have 0 .. N sockets already and we get to know about the 0 .. M
2940 sockets we should have from now on. Detect the differences, remove no
2941 longer supervised ones and add new ones */
2942
2943 /* walk over the sockets we got right now */
2944 for(i = 0; i < cur_poll.num; i++) {
2945 unsigned char cur_action = cur_poll.actions[i];
2946 unsigned char last_action = 0;
2947 int comboaction;
2948
2949 s = cur_poll.sockets[i];
2950
2951 /* get it from the hash */
2952 entry = sh_getentry(&multi->sockhash, s);
2953 if(entry) {
2954 /* check if new for this transfer */
2955 unsigned int j;
2956 for(j = 0; j< data->last_poll.num; j++) {
2957 if(s == data->last_poll.sockets[j]) {
2958 last_action = data->last_poll.actions[j];
2959 break;
2960 }
2961 }
2962 }
2963 else {
2964 /* this is a socket we didn't have before, add it to the hash! */
2965 entry = sh_addentry(&multi->sockhash, s);
2966 if(!entry)
2967 /* fatal */
2968 return CURLM_OUT_OF_MEMORY;
2969 }
2970 if(last_action && (last_action != cur_action)) {
2971 /* Socket was used already, but different action now */
2972 if(last_action & CURL_POLL_IN)
2973 entry->readers--;
2974 if(last_action & CURL_POLL_OUT)
2975 entry->writers--;
2976 if(cur_action & CURL_POLL_IN)
2977 entry->readers++;
2978 if(cur_action & CURL_POLL_OUT)
2979 entry->writers++;
2980 }
2981 else if(!last_action) {
2982 /* a new transfer using this socket */
2983 entry->users++;
2984 if(cur_action & CURL_POLL_IN)
2985 entry->readers++;
2986 if(cur_action & CURL_POLL_OUT)
2987 entry->writers++;
2988
2989 /* add 'data' to the transfer hash on this socket! */
2990 if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
2991 sizeof(struct Curl_easy *), data)) {
2992 Curl_hash_destroy(&entry->transfers);
2993 return CURLM_OUT_OF_MEMORY;
2994 }
2995 }
2996
2997 comboaction = (entry->writers ? CURL_POLL_OUT : 0) |
2998 (entry->readers ? CURL_POLL_IN : 0);
2999
3000 /* socket existed before and has the same action set as before */
3001 if(last_action && ((int)entry->action == comboaction))
3002 /* same, continue */
3003 continue;
3004
3005 if(multi->socket_cb) {
3006 set_in_callback(multi, TRUE);
3007 rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
3008 entry->socketp);
3009
3010 set_in_callback(multi, FALSE);
3011 if(rc == -1) {
3012 multi->dead = TRUE;
3013 return CURLM_ABORTED_BY_CALLBACK;
3014 }
3015 }
3016
3017 entry->action = comboaction; /* store the current action state */
3018 }
3019
3020 /* Check for last_poll.sockets that no longer appear in cur_poll.sockets.
3021 * Need to remove the easy handle from the multi->sockhash->transfers and
3022 * remove multi->sockhash entry when this was the last transfer */
3023 for(i = 0; i< data->last_poll.num; i++) {
3024 unsigned int j;
3025 bool stillused = FALSE;
3026 s = data->last_poll.sockets[i];
3027 for(j = 0; j < cur_poll.num; j++) {
3028 if(s == cur_poll.sockets[j]) {
3029 /* this is still supervised */
3030 stillused = TRUE;
3031 break;
3032 }
3033 }
3034 if(stillused)
3035 continue;
3036
3037 entry = sh_getentry(&multi->sockhash, s);
3038 /* if this is NULL here, the socket has been closed and notified so
3039 already by Curl_multi_closed() */
3040 if(entry) {
3041 unsigned char oldactions = data->last_poll.actions[i];
3042 /* this socket has been removed. Decrease user count */
3043 entry->users--;
3044 if(oldactions & CURL_POLL_OUT)
3045 entry->writers--;
3046 if(oldactions & CURL_POLL_IN)
3047 entry->readers--;
3048 if(!entry->users) {
3049 if(multi->socket_cb) {
3050 set_in_callback(multi, TRUE);
3051 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3052 multi->socket_userp, entry->socketp);
3053 set_in_callback(multi, FALSE);
3054 if(rc == -1) {
3055 multi->dead = TRUE;
3056 return CURLM_ABORTED_BY_CALLBACK;
3057 }
3058 }
3059 sh_delentry(entry, &multi->sockhash, s);
3060 }
3061 else {
3062 /* still users, but remove this handle as a user of this socket */
3063 if(Curl_hash_delete(&entry->transfers, (char *)&data,
3064 sizeof(struct Curl_easy *))) {
3065 DEBUGASSERT(NULL);
3066 }
3067 }
3068 }
3069 } /* for loop over num */
3070
3071 /* Remember for next time */
3072 memcpy(&data->last_poll, &cur_poll, sizeof(data->last_poll));
3073 return CURLM_OK;
3074 }
3075
3076 CURLcode Curl_updatesocket(struct Curl_easy *data)
3077 {
3078 if(singlesocket(data->multi, data))
3079 return CURLE_ABORTED_BY_CALLBACK;
3080 return CURLE_OK;
3081 }
3082
3083
3084 /*
3085 * Curl_multi_closed()
3086 *
3087 * Used by the connect code to tell the multi_socket code that one of the
3088 * sockets we were using is about to be closed. This function will then
3089 * remove it from the sockethash for this handle to make the multi_socket API
3090 * behave properly, especially for the case when libcurl will create another
3091 * socket again and it gets the same file descriptor number.
3092 */
3093
3094 void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
3095 {
3096 if(data) {
3097 /* if there's still an easy handle associated with this connection */
3098 struct Curl_multi *multi = data->multi;
3099 if(multi) {
3100 /* this is set if this connection is part of a handle that is added to
3101 a multi handle, and only then this is necessary */
3102 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3103
3104 if(entry) {
3105 int rc = 0;
3106 if(multi->socket_cb) {
3107 set_in_callback(multi, TRUE);
3108 rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
3109 multi->socket_userp, entry->socketp);
3110 set_in_callback(multi, FALSE);
3111 }
3112
3113 /* now remove it from the socket hash */
3114 sh_delentry(entry, &multi->sockhash, s);
3115 if(rc == -1)
3116 /* This just marks the multi handle as "dead" without returning an
3117 error code primarily because this function is used from many
3118 places where propagating an error back is tricky. */
3119 multi->dead = TRUE;
3120 }
3121 }
3122 }
3123 }
3124
3125 /*
3126 * add_next_timeout()
3127 *
3128 * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
3129 * when it has just been removed from the splay tree because the timeout has
3130 * expired. This function is then to advance in the list to pick the next
3131 * timeout to use (skip the already expired ones) and add this node back to
3132 * the splay tree again.
3133 *
3134 * The splay tree only has each sessionhandle as a single node and the nearest
3135 * timeout is used to sort it on.
3136 */
3137 static CURLMcode add_next_timeout(struct curltime now,
3138 struct Curl_multi *multi,
3139 struct Curl_easy *d)
3140 {
3141 struct curltime *tv = &d->state.expiretime;
3142 struct Curl_llist *list = &d->state.timeoutlist;
3143 struct Curl_llist_element *e;
3144 struct time_node *node = NULL;
3145
3146 /* move over the timeout list for this specific handle and remove all
3147 timeouts that are now passed tense and store the next pending
3148 timeout in *tv */
3149 for(e = list->head; e;) {
3150 struct Curl_llist_element *n = e->next;
3151 timediff_t diff;
3152 node = (struct time_node *)e->ptr;
3153 diff = Curl_timediff_us(node->time, now);
3154 if(diff <= 0)
3155 /* remove outdated entry */
3156 Curl_llist_remove(list, e, NULL);
3157 else
3158 /* the list is sorted so get out on the first mismatch */
3159 break;
3160 e = n;
3161 }
3162 e = list->head;
3163 if(!e) {
3164 /* clear the expire times within the handles that we remove from the
3165 splay tree */
3166 tv->tv_sec = 0;
3167 tv->tv_usec = 0;
3168 }
3169 else {
3170 /* copy the first entry to 'tv' */
3171 memcpy(tv, &node->time, sizeof(*tv));
3172
3173 /* Insert this node again into the splay. Keep the timer in the list in
3174 case we need to recompute future timers. */
3175 multi->timetree = Curl_splayinsert(*tv, multi->timetree,
3176 &d->state.timenode);
3177 }
3178 return CURLM_OK;
3179 }
3180
3181 static CURLMcode multi_socket(struct Curl_multi *multi,
3182 bool checkall,
3183 curl_socket_t s,
3184 int ev_bitmask,
3185 int *running_handles)
3186 {
3187 CURLMcode result = CURLM_OK;
3188 struct Curl_easy *data = NULL;
3189 struct Curl_tree *t;
3190 struct curltime now = Curl_now();
3191 bool first = FALSE;
3192 bool nosig = FALSE;
3193 SIGPIPE_VARIABLE(pipe_st);
3194
3195 if(checkall) {
3196 /* *perform() deals with running_handles on its own */
3197 result = curl_multi_perform(multi, running_handles);
3198
3199 /* walk through each easy handle and do the socket state change magic
3200 and callbacks */
3201 if(result != CURLM_BAD_HANDLE) {
3202 data = multi->easyp;
3203 while(data && !result) {
3204 result = singlesocket(multi, data);
3205 data = data->next;
3206 }
3207 }
3208
3209 /* or should we fall-through and do the timer-based stuff? */
3210 return result;
3211 }
3212 if(s != CURL_SOCKET_TIMEOUT) {
3213 struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
3214
3215 if(!entry)
3216 /* Unmatched socket, we can't act on it but we ignore this fact. In
3217 real-world tests it has been proved that libevent can in fact give
3218 the application actions even though the socket was just previously
3219 asked to get removed, so thus we better survive stray socket actions
3220 and just move on. */
3221 ;
3222 else {
3223 struct Curl_hash_iterator iter;
3224 struct Curl_hash_element *he;
3225
3226 /* the socket can be shared by many transfers, iterate */
3227 Curl_hash_start_iterate(&entry->transfers, &iter);
3228 for(he = Curl_hash_next_element(&iter); he;
3229 he = Curl_hash_next_element(&iter)) {
3230 data = (struct Curl_easy *)he->ptr;
3231 DEBUGASSERT(data);
3232 DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
3233
3234 if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
3235 /* set socket event bitmask if they're not locked */
3236 data->state.select_bits |= (unsigned char)ev_bitmask;
3237
3238 Curl_expire(data, 0, EXPIRE_RUN_NOW);
3239 }
3240
3241 /* Now we fall-through and do the timer-based stuff, since we don't want
3242 to force the user to have to deal with timeouts as long as at least
3243 one connection in fact has traffic. */
3244
3245 data = NULL; /* set data to NULL again to avoid calling
3246 multi_runsingle() in case there's no need to */
3247 now = Curl_now(); /* get a newer time since the multi_runsingle() loop
3248 may have taken some time */
3249 }
3250 }
3251 else {
3252 /* Asked to run due to time-out. Clear the 'lastcall' variable to force
3253 Curl_update_timer() to trigger a callback to the app again even if the
3254 same timeout is still the one to run after this call. That handles the
3255 case when the application asks libcurl to run the timeout
3256 prematurely. */
3257 memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
3258 }
3259
3260 /*
3261 * The loop following here will go on as long as there are expire-times left
3262 * to process in the splay and 'data' will be re-assigned for every expired
3263 * handle we deal with.
3264 */
3265 do {
3266 /* the first loop lap 'data' can be NULL */
3267 if(data) {
3268 if(!first) {
3269 first = TRUE;
3270 nosig = data->set.no_signal; /* initial state */
3271 sigpipe_ignore(data, &pipe_st);
3272 }
3273 else if(data->set.no_signal != nosig) {
3274 sigpipe_restore(&pipe_st);
3275 sigpipe_ignore(data, &pipe_st);
3276 nosig = data->set.no_signal; /* remember new state */
3277 }
3278 result = multi_runsingle(multi, &now, data);
3279
3280 if(CURLM_OK >= result) {
3281 /* get the socket(s) and check if the state has been changed since
3282 last */
3283 result = singlesocket(multi, data);
3284 if(result)
3285 break;
3286 }
3287 }
3288
3289 /* Check if there's one (more) expired timer to deal with! This function
3290 extracts a matching node if there is one */
3291
3292 multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
3293 if(t) {
3294 data = t->payload; /* assign this for next loop */
3295 (void)add_next_timeout(now, multi, t->payload);
3296 }
3297
3298 } while(t);
3299 if(first)
3300 sigpipe_restore(&pipe_st);
3301
3302 *running_handles = multi->num_alive;
3303 return result;
3304 }
3305
3306 #undef curl_multi_setopt
3307 CURLMcode curl_multi_setopt(struct Curl_multi *multi,
3308 CURLMoption option, ...)
3309 {
3310 CURLMcode res = CURLM_OK;
3311 va_list param;
3312 unsigned long uarg;
3313
3314 if(!GOOD_MULTI_HANDLE(multi))
3315 return CURLM_BAD_HANDLE;
3316
3317 if(multi->in_callback)
3318 return CURLM_RECURSIVE_API_CALL;
3319
3320 va_start(param, option);
3321
3322 switch(option) {
3323 case CURLMOPT_SOCKETFUNCTION:
3324 multi->socket_cb = va_arg(param, curl_socket_callback);
3325 break;
3326 case CURLMOPT_SOCKETDATA:
3327 multi->socket_userp = va_arg(param, void *);
3328 break;
3329 case CURLMOPT_PUSHFUNCTION:
3330 multi->push_cb = va_arg(param, curl_push_callback);
3331 break;
3332 case CURLMOPT_PUSHDATA:
3333 multi->push_userp = va_arg(param, void *);
3334 break;
3335 case CURLMOPT_PIPELINING:
3336 multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0;
3337 break;
3338 case CURLMOPT_TIMERFUNCTION:
3339 multi->timer_cb = va_arg(param, curl_multi_timer_callback);
3340 break;
3341 case CURLMOPT_TIMERDATA:
3342 multi->timer_userp = va_arg(param, void *);
3343 break;
3344 case CURLMOPT_MAXCONNECTS:
3345 uarg = va_arg(param, unsigned long);
3346 if(uarg <= UINT_MAX)
3347 multi->maxconnects = (unsigned int)uarg;
3348 break;
3349 case CURLMOPT_MAX_HOST_CONNECTIONS:
3350 multi->max_host_connections = va_arg(param, long);
3351 break;
3352 case CURLMOPT_MAX_TOTAL_CONNECTIONS:
3353 multi->max_total_connections = va_arg(param, long);
3354 break;
3355 /* options formerly used for pipelining */
3356 case CURLMOPT_MAX_PIPELINE_LENGTH:
3357 break;
3358 case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
3359 break;
3360 case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
3361 break;
3362 case CURLMOPT_PIPELINING_SITE_BL:
3363 break;
3364 case CURLMOPT_PIPELINING_SERVER_BL:
3365 break;
3366 case CURLMOPT_MAX_CONCURRENT_STREAMS:
3367 {
3368 long streams = va_arg(param, long);
3369 if((streams < 1) || (streams > INT_MAX))
3370 streams = 100;
3371 multi->max_concurrent_streams = (unsigned int)streams;
3372 }
3373 break;
3374 default:
3375 res = CURLM_UNKNOWN_OPTION;
3376 break;
3377 }
3378 va_end(param);
3379 return res;
3380 }
3381
3382 /* we define curl_multi_socket() in the public multi.h header */
3383 #undef curl_multi_socket
3384
3385 CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
3386 int *running_handles)
3387 {
3388 CURLMcode result;
3389 if(multi->in_callback)
3390 return CURLM_RECURSIVE_API_CALL;
3391 result = multi_socket(multi, FALSE, s, 0, running_handles);
3392 if(CURLM_OK >= result)
3393 result = Curl_update_timer(multi);
3394 return result;
3395 }
3396
3397 CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
3398 int ev_bitmask, int *running_handles)
3399 {
3400 CURLMcode result;
3401 if(multi->in_callback)
3402 return CURLM_RECURSIVE_API_CALL;
3403 result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
3404 if(CURLM_OK >= result)
3405 result = Curl_update_timer(multi);
3406 return result;
3407 }
3408
3409 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
3410 {
3411 CURLMcode result;
3412 if(multi->in_callback)
3413 return CURLM_RECURSIVE_API_CALL;
3414 result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
3415 if(CURLM_OK >= result)
3416 result = Curl_update_timer(multi);
3417 return result;
3418 }
3419
3420 static CURLMcode multi_timeout(struct Curl_multi *multi,
3421 long *timeout_ms)
3422 {
3423 static const struct curltime tv_zero = {0, 0};
3424
3425 if(multi->dead) {
3426 *timeout_ms = 0;
3427 return CURLM_OK;
3428 }
3429
3430 if(multi->timetree) {
3431 /* we have a tree of expire times */
3432 struct curltime now = Curl_now();
3433
3434 /* splay the lowest to the bottom */
3435 multi->timetree = Curl_splay(tv_zero, multi->timetree);
3436
3437 if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
3438 /* some time left before expiration */
3439 timediff_t diff = Curl_timediff_ceil(multi->timetree->key, now);
3440 /* this should be safe even on 32 bit archs, as we don't use that
3441 overly long timeouts */
3442 *timeout_ms = (long)diff;
3443 }
3444 else
3445 /* 0 means immediately */
3446 *timeout_ms = 0;
3447 }
3448 else
3449 *timeout_ms = -1;
3450
3451 return CURLM_OK;
3452 }
3453
3454 CURLMcode curl_multi_timeout(struct Curl_multi *multi,
3455 long *timeout_ms)
3456 {
3457 /* First, make some basic checks that the CURLM handle is a good handle */
3458 if(!GOOD_MULTI_HANDLE(multi))
3459 return CURLM_BAD_HANDLE;
3460
3461 if(multi->in_callback)
3462 return CURLM_RECURSIVE_API_CALL;
3463
3464 return multi_timeout(multi, timeout_ms);
3465 }
3466
3467 /*
3468 * Tell the application it should update its timers, if it subscribes to the
3469 * update timer callback.
3470 */
3471 CURLMcode Curl_update_timer(struct Curl_multi *multi)
3472 {
3473 long timeout_ms;
3474 int rc;
3475
3476 if(!multi->timer_cb || multi->dead)
3477 return CURLM_OK;
3478 if(multi_timeout(multi, &timeout_ms)) {
3479 return CURLM_OK;
3480 }
3481 if(timeout_ms < 0) {
3482 static const struct curltime none = {0, 0};
3483 if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
3484 multi->timer_lastcall = none;
3485 /* there's no timeout now but there was one previously, tell the app to
3486 disable it */
3487 set_in_callback(multi, TRUE);
3488 rc = multi->timer_cb(multi, -1, multi->timer_userp);
3489 set_in_callback(multi, FALSE);
3490 if(rc == -1) {
3491 multi->dead = TRUE;
3492 return CURLM_ABORTED_BY_CALLBACK;
3493 }
3494 return CURLM_OK;
3495 }
3496 return CURLM_OK;
3497 }
3498
3499 /* When multi_timeout() is done, multi->timetree points to the node with the
3500 * timeout we got the (relative) time-out time for. We can thus easily check
3501 * if this is the same (fixed) time as we got in a previous call and then
3502 * avoid calling the callback again. */
3503 if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
3504 return CURLM_OK;
3505
3506 multi->timer_lastcall = multi->timetree->key;
3507
3508 set_in_callback(multi, TRUE);
3509 rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
3510 set_in_callback(multi, FALSE);
3511 if(rc == -1) {
3512 multi->dead = TRUE;
3513 return CURLM_ABORTED_BY_CALLBACK;
3514 }
3515 return CURLM_OK;
3516 }
3517
3518 /*
3519 * multi_deltimeout()
3520 *
3521 * Remove a given timestamp from the list of timeouts.
3522 */
3523 static void
3524 multi_deltimeout(struct Curl_easy *data, expire_id eid)
3525 {
3526 struct Curl_llist_element *e;
3527 struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3528 /* find and remove the specific node from the list */
3529 for(e = timeoutlist->head; e; e = e->next) {
3530 struct time_node *n = (struct time_node *)e->ptr;
3531 if(n->eid == eid) {
3532 Curl_llist_remove(timeoutlist, e, NULL);
3533 return;
3534 }
3535 }
3536 }
3537
3538 /*
3539 * multi_addtimeout()
3540 *
3541 * Add a timestamp to the list of timeouts. Keep the list sorted so that head
3542 * of list is always the timeout nearest in time.
3543 *
3544 */
3545 static CURLMcode
3546 multi_addtimeout(struct Curl_easy *data,
3547 struct curltime *stamp,
3548 expire_id eid)
3549 {
3550 struct Curl_llist_element *e;
3551 struct time_node *node;
3552 struct Curl_llist_element *prev = NULL;
3553 size_t n;
3554 struct Curl_llist *timeoutlist = &data->state.timeoutlist;
3555
3556 node = &data->state.expires[eid];
3557
3558 /* copy the timestamp and id */
3559 memcpy(&node->time, stamp, sizeof(*stamp));
3560 node->eid = eid; /* also marks it as in use */
3561
3562 n = Curl_llist_count(timeoutlist);
3563 if(n) {
3564 /* find the correct spot in the list */
3565 for(e = timeoutlist->head; e; e = e->next) {
3566 struct time_node *check = (struct time_node *)e->ptr;
3567 timediff_t diff = Curl_timediff(check->time, node->time);
3568 if(diff > 0)
3569 break;
3570 prev = e;
3571 }
3572
3573 }
3574 /* else
3575 this is the first timeout on the list */
3576
3577 Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
3578 return CURLM_OK;
3579 }
3580
3581 /*
3582 * Curl_expire()
3583 *
3584 * given a number of milliseconds from now to use to set the 'act before
3585 * this'-time for the transfer, to be extracted by curl_multi_timeout()
3586 *
3587 * The timeout will be added to a queue of timeouts if it defines a moment in
3588 * time that is later than the current head of queue.
3589 *
3590 * Expire replaces a former timeout using the same id if already set.
3591 */
3592 void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
3593 {
3594 struct Curl_multi *multi = data->multi;
3595 struct curltime *nowp = &data->state.expiretime;
3596 struct curltime set;
3597
3598 /* this is only interesting while there is still an associated multi struct
3599 remaining! */
3600 if(!multi)
3601 return;
3602
3603 DEBUGASSERT(id < EXPIRE_LAST);
3604
3605 set = Curl_now();
3606 set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */
3607 set.tv_usec += (unsigned int)(milli%1000)*1000;
3608
3609 if(set.tv_usec >= 1000000) {
3610 set.tv_sec++;
3611 set.tv_usec -= 1000000;
3612 }
3613
3614 /* Remove any timer with the same id just in case. */
3615 multi_deltimeout(data, id);
3616
3617 /* Add it to the timer list. It must stay in the list until it has expired
3618 in case we need to recompute the minimum timer later. */
3619 multi_addtimeout(data, &set, id);
3620
3621 if(nowp->tv_sec || nowp->tv_usec) {
3622 /* This means that the struct is added as a node in the splay tree.
3623 Compare if the new time is earlier, and only remove-old/add-new if it
3624 is. */
3625 timediff_t diff = Curl_timediff(set, *nowp);
3626 int rc;
3627
3628 if(diff > 0) {
3629 /* The current splay tree entry is sooner than this new expiry time.
3630 We don't need to update our splay tree entry. */
3631 return;
3632 }
3633
3634 /* Since this is an updated time, we must remove the previous entry from
3635 the splay tree first and then re-add the new value */
3636 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3637 &multi->timetree);
3638 if(rc)
3639 infof(data, "Internal error removing splay node = %d", rc);
3640 }
3641
3642 /* Indicate that we are in the splay tree and insert the new timer expiry
3643 value since it is our local minimum. */
3644 *nowp = set;
3645 data->state.timenode.payload = data;
3646 multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
3647 &data->state.timenode);
3648 }
3649
3650 /*
3651 * Curl_expire_done()
3652 *
3653 * Removes the expire timer. Marks it as done.
3654 *
3655 */
3656 void Curl_expire_done(struct Curl_easy *data, expire_id id)
3657 {
3658 /* remove the timer, if there */
3659 multi_deltimeout(data, id);
3660 }
3661
3662 /*
3663 * Curl_expire_clear()
3664 *
3665 * Clear ALL timeout values for this handle.
3666 */
3667 void Curl_expire_clear(struct Curl_easy *data)
3668 {
3669 struct Curl_multi *multi = data->multi;
3670 struct curltime *nowp = &data->state.expiretime;
3671
3672 /* this is only interesting while there is still an associated multi struct
3673 remaining! */
3674 if(!multi)
3675 return;
3676
3677 if(nowp->tv_sec || nowp->tv_usec) {
3678 /* Since this is an cleared time, we must remove the previous entry from
3679 the splay tree */
3680 struct Curl_llist *list = &data->state.timeoutlist;
3681 int rc;
3682
3683 rc = Curl_splayremove(multi->timetree, &data->state.timenode,
3684 &multi->timetree);
3685 if(rc)
3686 infof(data, "Internal error clearing splay node = %d", rc);
3687
3688 /* flush the timeout list too */
3689 while(list->size > 0) {
3690 Curl_llist_remove(list, list->tail, NULL);
3691 }
3692
3693 #ifdef DEBUGBUILD
3694 infof(data, "Expire cleared");
3695 #endif
3696 nowp->tv_sec = 0;
3697 nowp->tv_usec = 0;
3698 }
3699 }
3700
3701
3702
3703
3704 CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
3705 void *hashp)
3706 {
3707 struct Curl_sh_entry *there = NULL;
3708
3709 there = sh_getentry(&multi->sockhash, s);
3710
3711 if(!there)
3712 return CURLM_BAD_SOCKET;
3713
3714 there->socketp = hashp;
3715
3716 return CURLM_OK;
3717 }
3718
3719 size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
3720 {
3721 return multi ? multi->max_host_connections : 0;
3722 }
3723
3724 size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
3725 {
3726 return multi ? multi->max_total_connections : 0;
3727 }
3728
3729 /*
3730 * When information about a connection has appeared, call this!
3731 */
3732
3733 void Curl_multiuse_state(struct Curl_easy *data,
3734 int bundlestate) /* use BUNDLE_* defines */
3735 {
3736 struct connectdata *conn;
3737 DEBUGASSERT(data);
3738 DEBUGASSERT(data->multi);
3739 conn = data->conn;
3740 DEBUGASSERT(conn);
3741 DEBUGASSERT(conn->bundle);
3742
3743 conn->bundle->multiuse = bundlestate;
3744 process_pending_handles(data->multi);
3745 }
3746
3747 static void move_pending_to_connect(struct Curl_multi *multi,
3748 struct Curl_easy *data)
3749 {
3750 DEBUGASSERT(data->mstate == MSTATE_PENDING);
3751
3752 /* put it back into the main list */
3753 link_easy(multi, data);
3754
3755 multistate(data, MSTATE_CONNECT);
3756
3757 /* Remove this node from the pending list */
3758 Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
3759
3760 /* Make sure that the handle will be processed soonish. */
3761 Curl_expire(data, 0, EXPIRE_RUN_NOW);
3762 }
3763
3764 /* process_pending_handles() moves a handle from PENDING back into the main
3765 list and change state to CONNECT.
3766
3767 We do not move all transfers because that can be a significant amount.
3768 Since this is tried every now and then doing too many too often becomes a
3769 performance problem.
3770
3771 When there is a change for connection limits like max host connections etc,
3772 this likely only allows one new transfer. When there is a pipewait change,
3773 it can potentially allow hundreds of new transfers.
3774
3775 We could consider an improvement where we store the queue reason and allow
3776 more pipewait rechecks than others.
3777 */
3778 static void process_pending_handles(struct Curl_multi *multi)
3779 {
3780 struct Curl_llist_element *e = multi->pending.head;
3781 if(e) {
3782 struct Curl_easy *data = e->ptr;
3783 move_pending_to_connect(multi, data);
3784 }
3785 }
3786
3787 void Curl_set_in_callback(struct Curl_easy *data, bool value)
3788 {
3789 if(data && data->multi)
3790 data->multi->in_callback = value;
3791 }
3792
3793 bool Curl_is_in_callback(struct Curl_easy *data)
3794 {
3795 return (data && data->multi && data->multi->in_callback);
3796 }
3797
3798 unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
3799 {
3800 DEBUGASSERT(multi);
3801 return multi->max_concurrent_streams;
3802 }
3803
3804 struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi)
3805 {
3806 struct Curl_easy **a = malloc(sizeof(struct Curl_easy *) *
3807 (multi->num_easy + 1));
3808 if(a) {
3809 unsigned int i = 0;
3810 struct Curl_easy *e = multi->easyp;
3811 while(e) {
3812 DEBUGASSERT(i < multi->num_easy);
3813 if(!e->state.internal)
3814 a[i++] = e;
3815 e = e->next;
3816 }
3817 a[i] = NULL; /* last entry is a NULL */
3818 }
3819 return a;
3820 }
3821
3822 CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data,
3823 char **pbuf, size_t *pbuflen)
3824 {
3825 DEBUGASSERT(data);
3826 DEBUGASSERT(data->multi);
3827 *pbuf = NULL;
3828 *pbuflen = 0;
3829 if(!data->multi) {
3830 failf(data, "transfer has no multi handle");
3831 return CURLE_FAILED_INIT;
3832 }
3833 if(!data->set.buffer_size) {
3834 failf(data, "transfer buffer size is 0");
3835 return CURLE_FAILED_INIT;
3836 }
3837 if(data->multi->xfer_buf_borrowed) {
3838 failf(data, "attempt to borrow xfer_buf when already borrowed");
3839 return CURLE_AGAIN;
3840 }
3841
3842 if(data->multi->xfer_buf &&
3843 data->set.buffer_size > data->multi->xfer_buf_len) {
3844 /* not large enough, get a new one */
3845 free(data->multi->xfer_buf);
3846 data->multi->xfer_buf = NULL;
3847 data->multi->xfer_buf_len = 0;
3848 }
3849
3850 if(!data->multi->xfer_buf) {
3851 data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
3852 if(!data->multi->xfer_buf) {
3853 failf(data, "could not allocate xfer_buf of %zu bytes",
3854 (size_t)data->set.buffer_size);
3855 return CURLE_OUT_OF_MEMORY;
3856 }
3857 data->multi->xfer_buf_len = data->set.buffer_size;
3858 }
3859
3860 data->multi->xfer_buf_borrowed = TRUE;
3861 *pbuf = data->multi->xfer_buf;
3862 *pbuflen = data->multi->xfer_buf_len;
3863 return CURLE_OK;
3864 }
3865
3866 void Curl_multi_xfer_buf_release(struct Curl_easy *data, char *buf)
3867 {
3868 (void)buf;
3869 DEBUGASSERT(data);
3870 DEBUGASSERT(data->multi);
3871 DEBUGASSERT(!buf || data->multi->xfer_buf == buf);
3872 data->multi->xfer_buf_borrowed = FALSE;
3873 }
3874
3875 CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data,
3876 char **pbuf, size_t *pbuflen)
3877 {
3878 DEBUGASSERT(data);
3879 DEBUGASSERT(data->multi);
3880 *pbuf = NULL;
3881 *pbuflen = 0;
3882 if(!data->multi) {
3883 failf(data, "transfer has no multi handle");
3884 return CURLE_FAILED_INIT;
3885 }
3886 if(!data->set.upload_buffer_size) {
3887 failf(data, "transfer upload buffer size is 0");
3888 return CURLE_FAILED_INIT;
3889 }
3890 if(data->multi->xfer_ulbuf_borrowed) {
3891 failf(data, "attempt to borrow xfer_ulbuf when already borrowed");
3892 return CURLE_AGAIN;
3893 }
3894
3895 if(data->multi->xfer_ulbuf &&
3896 data->set.upload_buffer_size > data->multi->xfer_ulbuf_len) {
3897 /* not large enough, get a new one */
3898 free(data->multi->xfer_ulbuf);
3899 data->multi->xfer_ulbuf = NULL;
3900 data->multi->xfer_ulbuf_len = 0;
3901 }
3902
3903 if(!data->multi->xfer_ulbuf) {
3904 data->multi->xfer_ulbuf = malloc((size_t)data->set.upload_buffer_size);
3905 if(!data->multi->xfer_ulbuf) {
3906 failf(data, "could not allocate xfer_ulbuf of %zu bytes",
3907 (size_t)data->set.upload_buffer_size);
3908 return CURLE_OUT_OF_MEMORY;
3909 }
3910 data->multi->xfer_ulbuf_len = data->set.upload_buffer_size;
3911 }
3912
3913 data->multi->xfer_ulbuf_borrowed = TRUE;
3914 *pbuf = data->multi->xfer_ulbuf;
3915 *pbuflen = data->multi->xfer_ulbuf_len;
3916 return CURLE_OK;
3917 }
3918
3919 void Curl_multi_xfer_ulbuf_release(struct Curl_easy *data, char *buf)
3920 {
3921 (void)buf;
3922 DEBUGASSERT(data);
3923 DEBUGASSERT(data->multi);
3924 DEBUGASSERT(!buf || data->multi->xfer_ulbuf == buf);
3925 data->multi->xfer_ulbuf_borrowed = FALSE;
3926 }
3927
3928 static void multi_xfer_bufs_free(struct Curl_multi *multi)
3929 {
3930 DEBUGASSERT(multi);
3931 Curl_safefree(multi->xfer_buf);
3932 multi->xfer_buf_len = 0;
3933 multi->xfer_buf_borrowed = FALSE;
3934 Curl_safefree(multi->xfer_ulbuf);
3935 multi->xfer_ulbuf_len = 0;
3936 multi->xfer_ulbuf_borrowed = FALSE;
3937 }
3938