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