1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23 #include "curl_setup.h"
24
25 /*
26 * See comment in curl_memory.h for the explanation of this sanity check.
27 */
28
29 #ifdef CURLX_NO_MEMORY_CALLBACKS
30 #error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
31 #endif
32
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
35 #endif
36 #ifdef HAVE_NETDB_H
37 #include <netdb.h>
38 #endif
39 #ifdef HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
41 #endif
42 #ifdef HAVE_NET_IF_H
43 #include <net/if.h>
44 #endif
45 #ifdef HAVE_SYS_IOCTL_H
46 #include <sys/ioctl.h>
47 #endif
48
49 #ifdef HAVE_SYS_PARAM_H
50 #include <sys/param.h>
51 #endif
52
53 #include "urldata.h"
54 #include <curl/curl.h>
55 #include "transfer.h"
56 #include "vtls/vtls.h"
57 #include "url.h"
58 #include "getinfo.h"
59 #include "hostip.h"
60 #include "share.h"
61 #include "strdup.h"
62 #include "progress.h"
63 #include "easyif.h"
64 #include "multiif.h"
65 #include "select.h"
66 #include "sendf.h" /* for failf function prototype */
67 #include "connect.h" /* for Curl_getconnectinfo */
68 #include "slist.h"
69 #include "mime.h"
70 #include "amigaos.h"
71 #include "non-ascii.h"
72 #include "warnless.h"
73 #include "multiif.h"
74 #include "sigpipe.h"
75 #include "vssh/ssh.h"
76 #include "setopt.h"
77 #include "http_digest.h"
78 #include "system_win32.h"
79 #include "http2.h"
80 #include "dynbuf.h"
81 #include "altsvc.h"
82 #include "hsts.h"
83
84 /* The last 3 #include files should be in this order */
85 #include "curl_printf.h"
86 #include "curl_memory.h"
87 #include "memdebug.h"
88 #include "easy_lock.h"
89
90 /* true globals -- for curl_global_init() and curl_global_cleanup() */
91 static unsigned int initialized;
92 static long init_flags;
93
94 #ifdef GLOBAL_INIT_IS_THREADSAFE
95
96 static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT;
97 #define global_init_lock() curl_simple_lock_lock(&s_lock)
98 #define global_init_unlock() curl_simple_lock_unlock(&s_lock)
99
100 #else
101
102 #define global_init_lock()
103 #define global_init_unlock()
104
105 #endif
106
107 /*
108 * strdup (and other memory functions) is redefined in complicated
109 * ways, but at this point it must be defined as the system-supplied strdup
110 * so the callback pointer is initialized correctly.
111 */
112 #if defined(_WIN32_WCE)
113 #define system_strdup _strdup
114 #elif !defined(HAVE_STRDUP)
115 #define system_strdup curlx_strdup
116 #else
117 #define system_strdup strdup
118 #endif
119
120 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
121 # pragma warning(disable:4232) /* MSVC extension, dllimport identity */
122 #endif
123
124 /*
125 * If a memory-using function (like curl_getenv) is used before
126 * curl_global_init() is called, we need to have these pointers set already.
127 */
128 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
129 curl_free_callback Curl_cfree = (curl_free_callback)free;
130 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
131 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
132 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
133 #if defined(WIN32) && defined(UNICODE)
134 curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
135 #endif
136
137 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
138 # pragma warning(default:4232) /* MSVC extension, dllimport identity */
139 #endif
140
141 #ifdef DEBUGBUILD
142 static char *leakpointer;
143 #endif
144
145 /**
146 * curl_global_init() globally initializes curl given a bitwise set of the
147 * different features of what to initialize.
148 */
global_init(long flags,bool memoryfuncs)149 static CURLcode global_init(long flags, bool memoryfuncs)
150 {
151 if(initialized++)
152 return CURLE_OK;
153
154 if(memoryfuncs) {
155 /* Setup the default memory functions here (again) */
156 Curl_cmalloc = (curl_malloc_callback)malloc;
157 Curl_cfree = (curl_free_callback)free;
158 Curl_crealloc = (curl_realloc_callback)realloc;
159 Curl_cstrdup = (curl_strdup_callback)system_strdup;
160 Curl_ccalloc = (curl_calloc_callback)calloc;
161 #if defined(WIN32) && defined(UNICODE)
162 Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
163 #endif
164 }
165
166 if(!Curl_ssl_init()) {
167 DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
168 goto fail;
169 }
170
171 #ifdef WIN32
172 if(Curl_win32_init(flags)) {
173 DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
174 goto fail;
175 }
176 #endif
177
178 #ifdef __AMIGA__
179 if(!Curl_amiga_init()) {
180 DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
181 goto fail;
182 }
183 #endif
184
185 #ifdef NETWARE
186 if(netware_init()) {
187 DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
188 }
189 #endif
190
191 if(Curl_resolver_global_init()) {
192 DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
193 goto fail;
194 }
195
196 #if defined(USE_SSH)
197 if(Curl_ssh_init()) {
198 goto fail;
199 }
200 #endif
201
202 #ifdef USE_WOLFSSH
203 if(WS_SUCCESS != wolfSSH_Init()) {
204 DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n"));
205 return CURLE_FAILED_INIT;
206 }
207 #endif
208
209 init_flags = flags;
210
211 #ifdef DEBUGBUILD
212 if(getenv("CURL_GLOBAL_INIT"))
213 /* alloc data that will leak if *cleanup() is not called! */
214 leakpointer = malloc(1);
215 #endif
216
217 return CURLE_OK;
218
219 fail:
220 initialized--; /* undo the increase */
221 return CURLE_FAILED_INIT;
222 }
223
224
225 /**
226 * curl_global_init() globally initializes curl given a bitwise set of the
227 * different features of what to initialize.
228 */
curl_global_init(long flags)229 CURLcode curl_global_init(long flags)
230 {
231 CURLcode result;
232 global_init_lock();
233
234 result = global_init(flags, TRUE);
235
236 global_init_unlock();
237
238 return result;
239 }
240
241 /*
242 * curl_global_init_mem() globally initializes curl and also registers the
243 * user provided callback routines.
244 */
curl_global_init_mem(long flags,curl_malloc_callback m,curl_free_callback f,curl_realloc_callback r,curl_strdup_callback s,curl_calloc_callback c)245 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
246 curl_free_callback f, curl_realloc_callback r,
247 curl_strdup_callback s, curl_calloc_callback c)
248 {
249 CURLcode result;
250
251 /* Invalid input, return immediately */
252 if(!m || !f || !r || !s || !c)
253 return CURLE_FAILED_INIT;
254
255 global_init_lock();
256
257 if(initialized) {
258 /* Already initialized, don't do it again, but bump the variable anyway to
259 work like curl_global_init() and require the same amount of cleanup
260 calls. */
261 initialized++;
262 global_init_unlock();
263 return CURLE_OK;
264 }
265
266 /* set memory functions before global_init() in case it wants memory
267 functions */
268 Curl_cmalloc = m;
269 Curl_cfree = f;
270 Curl_cstrdup = s;
271 Curl_crealloc = r;
272 Curl_ccalloc = c;
273
274 /* Call the actual init function, but without setting */
275 result = global_init(flags, FALSE);
276
277 global_init_unlock();
278
279 return result;
280 }
281
282 /**
283 * curl_global_cleanup() globally cleanups curl, uses the value of
284 * "init_flags" to determine what needs to be cleaned up and what doesn't.
285 */
curl_global_cleanup(void)286 void curl_global_cleanup(void)
287 {
288 global_init_lock();
289
290 if(!initialized) {
291 global_init_unlock();
292 return;
293 }
294
295 if(--initialized) {
296 global_init_unlock();
297 return;
298 }
299
300 Curl_ssl_cleanup();
301 Curl_resolver_global_cleanup();
302
303 #ifdef WIN32
304 Curl_win32_cleanup(init_flags);
305 #endif
306
307 Curl_amiga_cleanup();
308
309 Curl_ssh_cleanup();
310
311 #ifdef USE_WOLFSSH
312 (void)wolfSSH_Cleanup();
313 #endif
314 #ifdef DEBUGBUILD
315 free(leakpointer);
316 #endif
317
318 init_flags = 0;
319
320 global_init_unlock();
321 }
322
323 /*
324 * curl_easy_init() is the external interface to alloc, setup and init an
325 * easy handle that is returned. If anything goes wrong, NULL is returned.
326 */
curl_easy_init(void)327 struct Curl_easy *curl_easy_init(void)
328 {
329 CURLcode result;
330 struct Curl_easy *data;
331
332 /* Make sure we inited the global SSL stuff */
333 global_init_lock();
334
335 if(!initialized) {
336 result = global_init(CURL_GLOBAL_DEFAULT, TRUE);
337 if(result) {
338 /* something in the global init failed, return nothing */
339 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
340 global_init_unlock();
341 return NULL;
342 }
343 }
344 global_init_unlock();
345
346 /* We use curl_open() with undefined URL so far */
347 result = Curl_open(&data);
348 if(result) {
349 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
350 return NULL;
351 }
352
353 return data;
354 }
355
356 #ifdef CURLDEBUG
357
358 struct socketmonitor {
359 struct socketmonitor *next; /* the next node in the list or NULL */
360 struct pollfd socket; /* socket info of what to monitor */
361 };
362
363 struct events {
364 long ms; /* timeout, run the timeout function when reached */
365 bool msbump; /* set TRUE when timeout is set by callback */
366 int num_sockets; /* number of nodes in the monitor list */
367 struct socketmonitor *list; /* list of sockets to monitor */
368 int running_handles; /* store the returned number */
369 };
370
371 /* events_timer
372 *
373 * Callback that gets called with a new value when the timeout should be
374 * updated.
375 */
376
events_timer(struct Curl_multi * multi,long timeout_ms,void * userp)377 static int events_timer(struct Curl_multi *multi, /* multi handle */
378 long timeout_ms, /* see above */
379 void *userp) /* private callback pointer */
380 {
381 struct events *ev = userp;
382 (void)multi;
383 if(timeout_ms == -1)
384 /* timeout removed */
385 timeout_ms = 0;
386 else if(timeout_ms == 0)
387 /* timeout is already reached! */
388 timeout_ms = 1; /* trigger asap */
389
390 ev->ms = timeout_ms;
391 ev->msbump = TRUE;
392 return 0;
393 }
394
395
396 /* poll2cselect
397 *
398 * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
399 */
poll2cselect(int pollmask)400 static int poll2cselect(int pollmask)
401 {
402 int omask = 0;
403 if(pollmask & POLLIN)
404 omask |= CURL_CSELECT_IN;
405 if(pollmask & POLLOUT)
406 omask |= CURL_CSELECT_OUT;
407 if(pollmask & POLLERR)
408 omask |= CURL_CSELECT_ERR;
409 return omask;
410 }
411
412
413 /* socketcb2poll
414 *
415 * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
416 */
socketcb2poll(int pollmask)417 static short socketcb2poll(int pollmask)
418 {
419 short omask = 0;
420 if(pollmask & CURL_POLL_IN)
421 omask |= POLLIN;
422 if(pollmask & CURL_POLL_OUT)
423 omask |= POLLOUT;
424 return omask;
425 }
426
427 /* events_socket
428 *
429 * Callback that gets called with information about socket activity to
430 * monitor.
431 */
events_socket(struct Curl_easy * easy,curl_socket_t s,int what,void * userp,void * socketp)432 static int events_socket(struct Curl_easy *easy, /* easy handle */
433 curl_socket_t s, /* socket */
434 int what, /* see above */
435 void *userp, /* private callback
436 pointer */
437 void *socketp) /* private socket
438 pointer */
439 {
440 struct events *ev = userp;
441 struct socketmonitor *m;
442 struct socketmonitor *prev = NULL;
443
444 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
445 (void) easy;
446 #endif
447 (void)socketp;
448
449 m = ev->list;
450 while(m) {
451 if(m->socket.fd == s) {
452
453 if(what == CURL_POLL_REMOVE) {
454 struct socketmonitor *nxt = m->next;
455 /* remove this node from the list of monitored sockets */
456 if(prev)
457 prev->next = nxt;
458 else
459 ev->list = nxt;
460 free(m);
461 m = nxt;
462 infof(easy, "socket cb: socket %d REMOVED", s);
463 }
464 else {
465 /* The socket 's' is already being monitored, update the activity
466 mask. Convert from libcurl bitmask to the poll one. */
467 m->socket.events = socketcb2poll(what);
468 infof(easy, "socket cb: socket %d UPDATED as %s%s", s,
469 (what&CURL_POLL_IN)?"IN":"",
470 (what&CURL_POLL_OUT)?"OUT":"");
471 }
472 break;
473 }
474 prev = m;
475 m = m->next; /* move to next node */
476 }
477 if(!m) {
478 if(what == CURL_POLL_REMOVE) {
479 /* this happens a bit too often, libcurl fix perhaps? */
480 /* fprintf(stderr,
481 "%s: socket %d asked to be REMOVED but not present!\n",
482 __func__, s); */
483 }
484 else {
485 m = malloc(sizeof(struct socketmonitor));
486 if(m) {
487 m->next = ev->list;
488 m->socket.fd = s;
489 m->socket.events = socketcb2poll(what);
490 m->socket.revents = 0;
491 ev->list = m;
492 infof(easy, "socket cb: socket %d ADDED as %s%s", s,
493 (what&CURL_POLL_IN)?"IN":"",
494 (what&CURL_POLL_OUT)?"OUT":"");
495 }
496 else
497 return CURLE_OUT_OF_MEMORY;
498 }
499 }
500
501 return 0;
502 }
503
504
505 /*
506 * events_setup()
507 *
508 * Do the multi handle setups that only event-based transfers need.
509 */
events_setup(struct Curl_multi * multi,struct events * ev)510 static void events_setup(struct Curl_multi *multi, struct events *ev)
511 {
512 /* timer callback */
513 curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
514 curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
515
516 /* socket callback */
517 curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
518 curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
519 }
520
521
522 /* wait_or_timeout()
523 *
524 * waits for activity on any of the given sockets, or the timeout to trigger.
525 */
526
wait_or_timeout(struct Curl_multi * multi,struct events * ev)527 static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
528 {
529 bool done = FALSE;
530 CURLMcode mcode = CURLM_OK;
531 CURLcode result = CURLE_OK;
532
533 while(!done) {
534 CURLMsg *msg;
535 struct socketmonitor *m;
536 struct pollfd *f;
537 struct pollfd fds[4];
538 int numfds = 0;
539 int pollrc;
540 int i;
541 struct curltime before;
542 struct curltime after;
543
544 /* populate the fds[] array */
545 for(m = ev->list, f = &fds[0]; m; m = m->next) {
546 f->fd = m->socket.fd;
547 f->events = m->socket.events;
548 f->revents = 0;
549 /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
550 f++;
551 numfds++;
552 }
553
554 /* get the time stamp to use to figure out how long poll takes */
555 before = Curl_now();
556
557 /* wait for activity or timeout */
558 pollrc = Curl_poll(fds, numfds, ev->ms);
559
560 after = Curl_now();
561
562 ev->msbump = FALSE; /* reset here */
563
564 if(0 == pollrc) {
565 /* timeout! */
566 ev->ms = 0;
567 /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */
568 mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
569 &ev->running_handles);
570 }
571 else if(pollrc > 0) {
572 /* loop over the monitored sockets to see which ones had activity */
573 for(i = 0; i< numfds; i++) {
574 if(fds[i].revents) {
575 /* socket activity, tell libcurl */
576 int act = poll2cselect(fds[i].revents); /* convert */
577 infof(multi->easyp, "call curl_multi_socket_action(socket %d)",
578 fds[i].fd);
579 mcode = curl_multi_socket_action(multi, fds[i].fd, act,
580 &ev->running_handles);
581 }
582 }
583
584 if(!ev->msbump) {
585 /* If nothing updated the timeout, we decrease it by the spent time.
586 * If it was updated, it has the new timeout time stored already.
587 */
588 timediff_t timediff = Curl_timediff(after, before);
589 if(timediff > 0) {
590 if(timediff > ev->ms)
591 ev->ms = 0;
592 else
593 ev->ms -= (long)timediff;
594 }
595 }
596 }
597 else
598 return CURLE_RECV_ERROR;
599
600 if(mcode)
601 return CURLE_URL_MALFORMAT;
602
603 /* we don't really care about the "msgs_in_queue" value returned in the
604 second argument */
605 msg = curl_multi_info_read(multi, &pollrc);
606 if(msg) {
607 result = msg->data.result;
608 done = TRUE;
609 }
610 }
611
612 return result;
613 }
614
615
616 /* easy_events()
617 *
618 * Runs a transfer in a blocking manner using the events-based API
619 */
easy_events(struct Curl_multi * multi)620 static CURLcode easy_events(struct Curl_multi *multi)
621 {
622 /* this struct is made static to allow it to be used after this function
623 returns and curl_multi_remove_handle() is called */
624 static struct events evs = {2, FALSE, 0, NULL, 0};
625
626 /* if running event-based, do some further multi inits */
627 events_setup(multi, &evs);
628
629 return wait_or_timeout(multi, &evs);
630 }
631 #else /* CURLDEBUG */
632 /* when not built with debug, this function doesn't exist */
633 #define easy_events(x) CURLE_NOT_BUILT_IN
634 #endif
635
easy_transfer(struct Curl_multi * multi)636 static CURLcode easy_transfer(struct Curl_multi *multi)
637 {
638 bool done = FALSE;
639 CURLMcode mcode = CURLM_OK;
640 CURLcode result = CURLE_OK;
641
642 while(!done && !mcode) {
643 int still_running = 0;
644
645 mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL);
646
647 if(!mcode)
648 mcode = curl_multi_perform(multi, &still_running);
649
650 /* only read 'still_running' if curl_multi_perform() return OK */
651 if(!mcode && !still_running) {
652 int rc;
653 CURLMsg *msg = curl_multi_info_read(multi, &rc);
654 if(msg) {
655 result = msg->data.result;
656 done = TRUE;
657 }
658 }
659 }
660
661 /* Make sure to return some kind of error if there was a multi problem */
662 if(mcode) {
663 result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
664 /* The other multi errors should never happen, so return
665 something suitably generic */
666 CURLE_BAD_FUNCTION_ARGUMENT;
667 }
668
669 return result;
670 }
671
672
673 /*
674 * easy_perform() is the external interface that performs a blocking
675 * transfer as previously setup.
676 *
677 * CONCEPT: This function creates a multi handle, adds the easy handle to it,
678 * runs curl_multi_perform() until the transfer is done, then detaches the
679 * easy handle, destroys the multi handle and returns the easy handle's return
680 * code.
681 *
682 * REALITY: it can't just create and destroy the multi handle that easily. It
683 * needs to keep it around since if this easy handle is used again by this
684 * function, the same multi handle must be re-used so that the same pools and
685 * caches can be used.
686 *
687 * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
688 * instead of curl_multi_perform() and use curl_multi_socket_action().
689 */
easy_perform(struct Curl_easy * data,bool events)690 static CURLcode easy_perform(struct Curl_easy *data, bool events)
691 {
692 struct Curl_multi *multi;
693 CURLMcode mcode;
694 CURLcode result = CURLE_OK;
695 SIGPIPE_VARIABLE(pipe_st);
696
697 if(!data)
698 return CURLE_BAD_FUNCTION_ARGUMENT;
699
700 if(data->set.errorbuffer)
701 /* clear this as early as possible */
702 data->set.errorbuffer[0] = 0;
703
704 if(data->multi) {
705 failf(data, "easy handle already used in multi handle");
706 return CURLE_FAILED_INIT;
707 }
708
709 if(data->multi_easy)
710 multi = data->multi_easy;
711 else {
712 /* this multi handle will only ever have a single easy handled attached
713 to it, so make it use minimal hashes */
714 multi = Curl_multi_handle(1, 3);
715 if(!multi)
716 return CURLE_OUT_OF_MEMORY;
717 data->multi_easy = multi;
718 }
719
720 if(multi->in_callback)
721 return CURLE_RECURSIVE_API_CALL;
722
723 /* Copy the MAXCONNECTS option to the multi handle */
724 curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
725
726 mcode = curl_multi_add_handle(multi, data);
727 if(mcode) {
728 curl_multi_cleanup(multi);
729 data->multi_easy = NULL;
730 if(mcode == CURLM_OUT_OF_MEMORY)
731 return CURLE_OUT_OF_MEMORY;
732 return CURLE_FAILED_INIT;
733 }
734
735 sigpipe_ignore(data, &pipe_st);
736
737 /* run the transfer */
738 result = events ? easy_events(multi) : easy_transfer(multi);
739
740 /* ignoring the return code isn't nice, but atm we can't really handle
741 a failure here, room for future improvement! */
742 (void)curl_multi_remove_handle(multi, data);
743
744 sigpipe_restore(&pipe_st);
745
746 /* The multi handle is kept alive, owned by the easy handle */
747 return result;
748 }
749
750
751 /*
752 * curl_easy_perform() is the external interface that performs a blocking
753 * transfer as previously setup.
754 */
curl_easy_perform(struct Curl_easy * data)755 CURLcode curl_easy_perform(struct Curl_easy *data)
756 {
757 return easy_perform(data, FALSE);
758 }
759
760 #ifdef CURLDEBUG
761 /*
762 * curl_easy_perform_ev() is the external interface that performs a blocking
763 * transfer using the event-based API internally.
764 */
curl_easy_perform_ev(struct Curl_easy * data)765 CURLcode curl_easy_perform_ev(struct Curl_easy *data)
766 {
767 return easy_perform(data, TRUE);
768 }
769
770 #endif
771
772 /*
773 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
774 * easy handle.
775 */
curl_easy_cleanup(struct Curl_easy * data)776 void curl_easy_cleanup(struct Curl_easy *data)
777 {
778 SIGPIPE_VARIABLE(pipe_st);
779
780 if(!data)
781 return;
782
783 sigpipe_ignore(data, &pipe_st);
784 Curl_close(&data);
785 sigpipe_restore(&pipe_st);
786 }
787
788 /*
789 * curl_easy_getinfo() is an external interface that allows an app to retrieve
790 * information from a performed transfer and similar.
791 */
792 #undef curl_easy_getinfo
curl_easy_getinfo(struct Curl_easy * data,CURLINFO info,...)793 CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
794 {
795 va_list arg;
796 void *paramp;
797 CURLcode result;
798
799 va_start(arg, info);
800 paramp = va_arg(arg, void *);
801
802 result = Curl_getinfo(data, info, paramp);
803
804 va_end(arg);
805 return result;
806 }
807
dupset(struct Curl_easy * dst,struct Curl_easy * src)808 static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
809 {
810 CURLcode result = CURLE_OK;
811 enum dupstring i;
812 enum dupblob j;
813
814 /* Copy src->set into dst->set first, then deal with the strings
815 afterwards */
816 dst->set = src->set;
817 Curl_mime_initpart(&dst->set.mimepost, dst);
818
819 /* clear all string pointers first */
820 memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
821
822 /* duplicate all strings */
823 for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
824 result = Curl_setstropt(&dst->set.str[i], src->set.str[i]);
825 if(result)
826 return result;
827 }
828
829 /* clear all blob pointers first */
830 memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *));
831 /* duplicate all blobs */
832 for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
833 result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]);
834 if(result)
835 return result;
836 }
837
838 /* duplicate memory areas pointed to */
839 i = STRING_COPYPOSTFIELDS;
840 if(src->set.postfieldsize && src->set.str[i]) {
841 /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
842 dst->set.str[i] = Curl_memdup(src->set.str[i],
843 curlx_sotouz(src->set.postfieldsize));
844 if(!dst->set.str[i])
845 return CURLE_OUT_OF_MEMORY;
846 /* point to the new copy */
847 dst->set.postfields = dst->set.str[i];
848 }
849
850 /* Duplicate mime data. */
851 result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost);
852
853 if(src->set.resolve)
854 dst->state.resolve = dst->set.resolve;
855
856 return result;
857 }
858
859 /*
860 * curl_easy_duphandle() is an external interface to allow duplication of a
861 * given input easy handle. The returned handle will be a new working handle
862 * with all options set exactly as the input source handle.
863 */
curl_easy_duphandle(struct Curl_easy * data)864 struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
865 {
866 struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
867 if(NULL == outcurl)
868 goto fail;
869
870 /*
871 * We setup a few buffers we need. We should probably make them
872 * get setup on-demand in the code, as that would probably decrease
873 * the likeliness of us forgetting to init a buffer here in the future.
874 */
875 outcurl->set.buffer_size = data->set.buffer_size;
876
877 /* copy all userdefined values */
878 if(dupset(outcurl, data))
879 goto fail;
880
881 Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
882
883 /* the connection cache is setup on demand */
884 outcurl->state.conn_cache = NULL;
885 outcurl->state.lastconnect_id = -1;
886
887 outcurl->progress.flags = data->progress.flags;
888 outcurl->progress.callback = data->progress.callback;
889
890 if(data->cookies) {
891 /* If cookies are enabled in the parent handle, we enable them
892 in the clone as well! */
893 outcurl->cookies = Curl_cookie_init(data,
894 data->cookies->filename,
895 outcurl->cookies,
896 data->set.cookiesession);
897 if(!outcurl->cookies)
898 goto fail;
899 }
900
901 /* duplicate all values in 'change' */
902 if(data->state.cookielist) {
903 outcurl->state.cookielist =
904 Curl_slist_duplicate(data->state.cookielist);
905 if(!outcurl->state.cookielist)
906 goto fail;
907 }
908
909 if(data->state.url) {
910 outcurl->state.url = strdup(data->state.url);
911 if(!outcurl->state.url)
912 goto fail;
913 outcurl->state.url_alloc = TRUE;
914 }
915
916 if(data->state.referer) {
917 outcurl->state.referer = strdup(data->state.referer);
918 if(!outcurl->state.referer)
919 goto fail;
920 outcurl->state.referer_alloc = TRUE;
921 }
922
923 /* Reinitialize an SSL engine for the new handle
924 * note: the engine name has already been copied by dupset */
925 if(outcurl->set.str[STRING_SSL_ENGINE]) {
926 if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE]))
927 goto fail;
928 }
929
930 #ifdef USE_ALTSVC
931 if(data->asi) {
932 outcurl->asi = Curl_altsvc_init();
933 if(!outcurl->asi)
934 goto fail;
935 if(outcurl->set.str[STRING_ALTSVC])
936 (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]);
937 }
938 #endif
939 #ifndef CURL_DISABLE_HSTS
940 if(data->hsts) {
941 outcurl->hsts = Curl_hsts_init();
942 if(!outcurl->hsts)
943 goto fail;
944 if(outcurl->set.str[STRING_HSTS])
945 (void)Curl_hsts_loadfile(outcurl,
946 outcurl->hsts, outcurl->set.str[STRING_HSTS]);
947 (void)Curl_hsts_loadcb(outcurl, outcurl->hsts);
948 }
949 #endif
950 /* Clone the resolver handle, if present, for the new handle */
951 if(Curl_resolver_duphandle(outcurl,
952 &outcurl->state.async.resolver,
953 data->state.async.resolver))
954 goto fail;
955
956 #ifdef USE_ARES
957 {
958 CURLcode rc;
959
960 rc = Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]);
961 if(rc && rc != CURLE_NOT_BUILT_IN)
962 goto fail;
963
964 rc = Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]);
965 if(rc && rc != CURLE_NOT_BUILT_IN)
966 goto fail;
967
968 rc = Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]);
969 if(rc && rc != CURLE_NOT_BUILT_IN)
970 goto fail;
971
972 rc = Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]);
973 if(rc && rc != CURLE_NOT_BUILT_IN)
974 goto fail;
975 }
976 #endif /* USE_ARES */
977
978 Curl_convert_setup(outcurl);
979
980 Curl_initinfo(outcurl);
981
982 outcurl->magic = CURLEASY_MAGIC_NUMBER;
983
984 /* we reach this point and thus we are OK */
985
986 return outcurl;
987
988 fail:
989
990 if(outcurl) {
991 curl_slist_free_all(outcurl->state.cookielist);
992 outcurl->state.cookielist = NULL;
993 Curl_safefree(outcurl->state.buffer);
994 Curl_dyn_free(&outcurl->state.headerb);
995 Curl_safefree(outcurl->state.url);
996 Curl_safefree(outcurl->state.referer);
997 Curl_altsvc_cleanup(&outcurl->asi);
998 Curl_hsts_cleanup(&outcurl->hsts);
999 Curl_freeset(outcurl);
1000 free(outcurl);
1001 }
1002
1003 return NULL;
1004 }
1005
1006 /*
1007 * curl_easy_reset() is an external interface that allows an app to re-
1008 * initialize a session handle to the default values.
1009 */
curl_easy_reset(struct Curl_easy * data)1010 void curl_easy_reset(struct Curl_easy *data)
1011 {
1012 Curl_free_request_state(data);
1013
1014 /* zero out UserDefined data: */
1015 Curl_freeset(data);
1016 memset(&data->set, 0, sizeof(struct UserDefined));
1017 (void)Curl_init_userdefined(data);
1018
1019 /* zero out Progress data: */
1020 memset(&data->progress, 0, sizeof(struct Progress));
1021
1022 /* zero out PureInfo data: */
1023 Curl_initinfo(data);
1024
1025 data->progress.flags |= PGRS_HIDE;
1026 data->state.current_speed = -1; /* init to negative == impossible */
1027 data->state.retrycount = 0; /* reset the retry counter */
1028
1029 /* zero out authentication data: */
1030 memset(&data->state.authhost, 0, sizeof(struct auth));
1031 memset(&data->state.authproxy, 0, sizeof(struct auth));
1032
1033 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
1034 Curl_http_auth_cleanup_digest(data);
1035 #endif
1036 }
1037
1038 /*
1039 * curl_easy_pause() allows an application to pause or unpause a specific
1040 * transfer and direction. This function sets the full new state for the
1041 * current connection this easy handle operates on.
1042 *
1043 * NOTE: if you have the receiving paused and you call this function to remove
1044 * the pausing, you may get your write callback called at this point.
1045 *
1046 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
1047 *
1048 * NOTE: This is one of few API functions that are allowed to be called from
1049 * within a callback.
1050 */
curl_easy_pause(struct Curl_easy * data,int action)1051 CURLcode curl_easy_pause(struct Curl_easy *data, int action)
1052 {
1053 struct SingleRequest *k;
1054 CURLcode result = CURLE_OK;
1055 int oldstate;
1056 int newstate;
1057
1058 if(!GOOD_EASY_HANDLE(data) || !data->conn)
1059 /* crazy input, don't continue */
1060 return CURLE_BAD_FUNCTION_ARGUMENT;
1061
1062 k = &data->req;
1063 oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
1064
1065 /* first switch off both pause bits then set the new pause bits */
1066 newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) |
1067 ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
1068 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
1069
1070 if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) {
1071 /* Not changing any pause state, return */
1072 DEBUGF(infof(data, "pause: no change, early return"));
1073 return CURLE_OK;
1074 }
1075
1076 /* Unpause parts in active mime tree. */
1077 if((k->keepon & ~newstate & KEEP_SEND_PAUSE) &&
1078 (data->mstate == MSTATE_PERFORMING ||
1079 data->mstate == MSTATE_RATELIMITING) &&
1080 data->state.fread_func == (curl_read_callback) Curl_mime_read) {
1081 Curl_mime_unpause(data->state.in);
1082 }
1083
1084 /* put it back in the keepon */
1085 k->keepon = newstate;
1086
1087 if(!(newstate & KEEP_RECV_PAUSE)) {
1088 Curl_http2_stream_pause(data, FALSE);
1089
1090 if(data->state.tempcount) {
1091 /* there are buffers for sending that can be delivered as the receive
1092 pausing is lifted! */
1093 unsigned int i;
1094 unsigned int count = data->state.tempcount;
1095 struct tempbuf writebuf[3]; /* there can only be three */
1096
1097 /* copy the structs to allow for immediate re-pausing */
1098 for(i = 0; i < data->state.tempcount; i++) {
1099 writebuf[i] = data->state.tempwrite[i];
1100 Curl_dyn_init(&data->state.tempwrite[i].b, DYN_PAUSE_BUFFER);
1101 }
1102 data->state.tempcount = 0;
1103
1104 for(i = 0; i < count; i++) {
1105 /* even if one function returns error, this loops through and frees
1106 all buffers */
1107 if(!result)
1108 result = Curl_client_write(data, writebuf[i].type,
1109 Curl_dyn_ptr(&writebuf[i].b),
1110 Curl_dyn_len(&writebuf[i].b));
1111 Curl_dyn_free(&writebuf[i].b);
1112 }
1113
1114 if(result)
1115 return result;
1116 }
1117 }
1118
1119 /* if there's no error and we're not pausing both directions, we want
1120 to have this handle checked soon */
1121 if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
1122 (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
1123 Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
1124
1125 /* reset the too-slow time keeper */
1126 data->state.keeps_speed.tv_sec = 0;
1127
1128 if(!data->state.tempcount)
1129 /* if not pausing again, force a recv/send check of this connection as
1130 the data might've been read off the socket already */
1131 data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
1132 if(data->multi)
1133 Curl_update_timer(data->multi);
1134 }
1135
1136 if(!data->state.done)
1137 /* This transfer may have been moved in or out of the bundle, update the
1138 corresponding socket callback, if used */
1139 Curl_updatesocket(data);
1140
1141 return result;
1142 }
1143
1144
easy_connection(struct Curl_easy * data,curl_socket_t * sfd,struct connectdata ** connp)1145 static CURLcode easy_connection(struct Curl_easy *data,
1146 curl_socket_t *sfd,
1147 struct connectdata **connp)
1148 {
1149 if(!data)
1150 return CURLE_BAD_FUNCTION_ARGUMENT;
1151
1152 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
1153 if(!data->set.connect_only) {
1154 failf(data, "CONNECT_ONLY is required!");
1155 return CURLE_UNSUPPORTED_PROTOCOL;
1156 }
1157
1158 *sfd = Curl_getconnectinfo(data, connp);
1159
1160 if(*sfd == CURL_SOCKET_BAD) {
1161 failf(data, "Failed to get recent socket");
1162 return CURLE_UNSUPPORTED_PROTOCOL;
1163 }
1164
1165 return CURLE_OK;
1166 }
1167
1168 /*
1169 * Receives data from the connected socket. Use after successful
1170 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1171 * Returns CURLE_OK on success, error code on error.
1172 */
curl_easy_recv(struct Curl_easy * data,void * buffer,size_t buflen,size_t * n)1173 CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
1174 size_t *n)
1175 {
1176 curl_socket_t sfd;
1177 CURLcode result;
1178 ssize_t n1;
1179 struct connectdata *c;
1180
1181 if(Curl_is_in_callback(data))
1182 return CURLE_RECURSIVE_API_CALL;
1183
1184 result = easy_connection(data, &sfd, &c);
1185 if(result)
1186 return result;
1187
1188 if(!data->conn)
1189 /* on first invoke, the transfer has been detached from the connection and
1190 needs to be reattached */
1191 Curl_attach_connnection(data, c);
1192
1193 *n = 0;
1194 result = Curl_read(data, sfd, buffer, buflen, &n1);
1195
1196 if(result)
1197 return result;
1198
1199 *n = (size_t)n1;
1200
1201 return CURLE_OK;
1202 }
1203
1204 /*
1205 * Sends data over the connected socket. Use after successful
1206 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1207 */
curl_easy_send(struct Curl_easy * data,const void * buffer,size_t buflen,size_t * n)1208 CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
1209 size_t buflen, size_t *n)
1210 {
1211 curl_socket_t sfd;
1212 CURLcode result;
1213 ssize_t n1;
1214 struct connectdata *c = NULL;
1215 SIGPIPE_VARIABLE(pipe_st);
1216
1217 if(Curl_is_in_callback(data))
1218 return CURLE_RECURSIVE_API_CALL;
1219
1220 result = easy_connection(data, &sfd, &c);
1221 if(result)
1222 return result;
1223
1224 if(!data->conn)
1225 /* on first invoke, the transfer has been detached from the connection and
1226 needs to be reattached */
1227 Curl_attach_connnection(data, c);
1228
1229 *n = 0;
1230 sigpipe_ignore(data, &pipe_st);
1231 result = Curl_write(data, sfd, buffer, buflen, &n1);
1232 sigpipe_restore(&pipe_st);
1233
1234 if(n1 == -1)
1235 return CURLE_SEND_ERROR;
1236
1237 /* detect EAGAIN */
1238 if(!result && !n1)
1239 return CURLE_AGAIN;
1240
1241 *n = (size_t)n1;
1242
1243 return result;
1244 }
1245
1246 /*
1247 * Wrapper to call functions in Curl_conncache_foreach()
1248 *
1249 * Returns always 0.
1250 */
conn_upkeep(struct Curl_easy * data,struct connectdata * conn,void * param)1251 static int conn_upkeep(struct Curl_easy *data,
1252 struct connectdata *conn,
1253 void *param)
1254 {
1255 /* Param is unused. */
1256 (void)param;
1257
1258 if(conn->handler->connection_check) {
1259 /* briefly attach the connection to this transfer for the purpose of
1260 checking it */
1261 Curl_attach_connnection(data, conn);
1262
1263 /* Do a protocol-specific keepalive check on the connection. */
1264 conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE);
1265 /* detach the connection again */
1266 Curl_detach_connnection(data);
1267 }
1268
1269 return 0; /* continue iteration */
1270 }
1271
upkeep(struct conncache * conn_cache,void * data)1272 static CURLcode upkeep(struct conncache *conn_cache, void *data)
1273 {
1274 /* Loop over every connection and make connection alive. */
1275 Curl_conncache_foreach(data,
1276 conn_cache,
1277 data,
1278 conn_upkeep);
1279 return CURLE_OK;
1280 }
1281
1282 /*
1283 * Performs connection upkeep for the given session handle.
1284 */
curl_easy_upkeep(struct Curl_easy * data)1285 CURLcode curl_easy_upkeep(struct Curl_easy *data)
1286 {
1287 /* Verify that we got an easy handle we can work with. */
1288 if(!GOOD_EASY_HANDLE(data))
1289 return CURLE_BAD_FUNCTION_ARGUMENT;
1290
1291 if(data->multi_easy) {
1292 /* Use the common function to keep connections alive. */
1293 return upkeep(&data->multi_easy->conn_cache, data);
1294 }
1295 else {
1296 /* No connections, so just return success */
1297 return CURLE_OK;
1298 }
1299 }
1300