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