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