/***************************************************************************1* _ _ ____ _2* Project ___| | | | _ \| |3* / __| | | | |_) | |4* | (__| |_| | _ <| |___5* \___|\___/|_| \_\_____|6*7* Copyright (C) Daniel Stenberg, <[email protected]>, et al.8*9* This software is licensed as described in the file COPYING, which10* you should have received as part of this distribution. The terms11* are also available at https://curl.se/docs/copyright.html.12*13* You may opt to use, copy, modify, merge, publish, distribute and/or sell14* copies of the Software, and permit persons to whom the Software is15* furnished to do so, under the terms of the COPYING file.16*17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY18* KIND, either express or implied.19*20* SPDX-License-Identifier: curl21*22***************************************************************************/2324#include "curl_setup.h"2526#ifdef HAVE_NETINET_IN_H27#include <netinet/in.h>28#endif29#ifdef HAVE_NETDB_H30#include <netdb.h>31#endif32#ifdef HAVE_ARPA_INET_H33#include <arpa/inet.h>34#endif35#ifdef __VMS36#include <in.h>37#include <inet.h>38#endif3940#ifdef USE_ARES41#include <ares.h>42#include <ares_version.h> /* really old c-ares did not include this by43itself */44#endif4546#include "urldata.h"47#include "asyn.h"48#include "sendf.h"49#include "hostip.h"50#include "hash.h"51#include "multiif.h"52#include "select.h"53#include "share.h"54#include "url.h"55#include "curl_memory.h"56/* The last #include file should be: */57#include "memdebug.h"5859/***********************************************************************60* Only for builds using asynchronous name resolves61**********************************************************************/62#ifdef CURLRES_ASYNCH636465#ifdef USE_ARES6667#if ARES_VERSION < 0x01060068#error "requires c-ares 1.6.0 or newer"69#endif7071/*72* Curl_ares_getsock() is called when the outside world (using73* curl_multi_fdset()) wants to get our fd_set setup and we are talking with74* ares. The caller must make sure that this function is only called when we75* have a working ares channel.76*77* Returns: sockets-in-use-bitmap78*/7980int Curl_ares_getsock(struct Curl_easy *data,81ares_channel channel,82curl_socket_t *socks)83{84struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 };85struct timeval timebuf;86int max = ares_getsock(channel,87(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);88struct timeval *timeout = ares_timeout(channel, &maxtime, &timebuf);89timediff_t milli = curlx_tvtoms(timeout);90Curl_expire(data, milli, EXPIRE_ASYNC_NAME);91return max;92}9394/*95* Curl_ares_perform()96*97* 1) Ask ares what sockets it currently plays with, then98* 2) wait for the timeout period to check for action on ares' sockets.99* 3) tell ares to act on all the sockets marked as "with action"100*101* return number of sockets it worked on, or -1 on error102*/103int Curl_ares_perform(ares_channel channel,104timediff_t timeout_ms)105{106int nfds;107int bitmask;108ares_socket_t socks[ARES_GETSOCK_MAXNUM];109struct pollfd pfd[ARES_GETSOCK_MAXNUM];110int i;111int num = 0;112113if(!channel)114return 0;115116bitmask = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM);117118for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {119pfd[i].events = 0;120pfd[i].revents = 0;121if(ARES_GETSOCK_READABLE(bitmask, i)) {122pfd[i].fd = socks[i];123pfd[i].events |= POLLRDNORM|POLLIN;124}125if(ARES_GETSOCK_WRITABLE(bitmask, i)) {126pfd[i].fd = socks[i];127pfd[i].events |= POLLWRNORM|POLLOUT;128}129if(pfd[i].events)130num++;131else132break;133}134135if(num) {136nfds = Curl_poll(pfd, (unsigned int)num, timeout_ms);137if(nfds < 0)138return -1;139}140else141nfds = 0;142143if(!nfds)144/* Call ares_process() unconditionally here, even if we simply timed out145above, as otherwise the ares name resolve will not timeout! */146ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);147else {148/* move through the descriptors and ask for processing on them */149for(i = 0; i < num; i++)150ares_process_fd(channel,151(pfd[i].revents & (POLLRDNORM|POLLIN)) ?152pfd[i].fd : ARES_SOCKET_BAD,153(pfd[i].revents & (POLLWRNORM|POLLOUT)) ?154pfd[i].fd : ARES_SOCKET_BAD);155}156return nfds;157}158159#endif160161#endif /* CURLRES_ASYNCH */162163#ifdef USE_CURL_ASYNC164165#include "doh.h"166167void Curl_async_shutdown(struct Curl_easy *data)168{169#ifdef CURLRES_ARES170Curl_async_ares_shutdown(data);171#endif172#ifdef CURLRES_THREADED173Curl_async_thrdd_shutdown(data);174#endif175#ifndef CURL_DISABLE_DOH176Curl_doh_cleanup(data);177#endif178Curl_safefree(data->state.async.hostname);179}180181void Curl_async_destroy(struct Curl_easy *data)182{183#ifdef CURLRES_ARES184Curl_async_ares_destroy(data);185#endif186#ifdef CURLRES_THREADED187Curl_async_thrdd_destroy(data);188#endif189#ifndef CURL_DISABLE_DOH190Curl_doh_cleanup(data);191#endif192Curl_safefree(data->state.async.hostname);193}194195#endif /* USE_CURL_ASYNC */196197198