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