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