mirror of
https://github.com/moparisthebest/curl
synced 2024-12-23 16:48:49 -05:00
hostip: remove conn->data from resolver functions
This also moves the 'async' struct from the connectdata struct into the Curl_easy struct, which seems like a better home for it. Closes #6497
This commit is contained in:
parent
d3a3bdb5ef
commit
8335c6417e
132
lib/asyn-ares.c
132
lib/asyn-ares.c
@ -204,22 +204,22 @@ static void destroy_async_data(struct Curl_async *async);
|
|||||||
/*
|
/*
|
||||||
* Cancel all possibly still on-going resolves for this connection.
|
* Cancel all possibly still on-going resolves for this connection.
|
||||||
*/
|
*/
|
||||||
void Curl_resolver_cancel(struct connectdata *conn)
|
void Curl_resolver_cancel(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
if(conn->data && conn->data->state.resolver)
|
if(data && data->state.async.resolver)
|
||||||
ares_cancel((ares_channel)conn->data->state.resolver);
|
ares_cancel((ares_channel)data->state.async.resolver);
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(&data->state.async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We
|
* We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We
|
||||||
* never block.
|
* never block.
|
||||||
*/
|
*/
|
||||||
void Curl_resolver_kill(struct connectdata *conn)
|
void Curl_resolver_kill(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
/* We don't need to check the resolver state because we can be called safely
|
/* We don't need to check the resolver state because we can be called safely
|
||||||
at any time and we always do the same thing. */
|
at any time and we always do the same thing. */
|
||||||
Curl_resolver_cancel(conn);
|
Curl_resolver_cancel(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -253,25 +253,25 @@ static void destroy_async_data(struct Curl_async *async)
|
|||||||
* Returns: sockets-in-use-bitmap
|
* Returns: sockets-in-use-bitmap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Curl_resolver_getsock(struct connectdata *conn,
|
int Curl_resolver_getsock(struct Curl_easy *data,
|
||||||
curl_socket_t *socks)
|
curl_socket_t *socks)
|
||||||
{
|
{
|
||||||
struct timeval maxtime;
|
struct timeval maxtime;
|
||||||
struct timeval timebuf;
|
struct timeval timebuf;
|
||||||
struct timeval *timeout;
|
struct timeval *timeout;
|
||||||
long milli;
|
long milli;
|
||||||
int max = ares_getsock((ares_channel)conn->data->state.resolver,
|
int max = ares_getsock((ares_channel)data->state.async.resolver,
|
||||||
(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
|
(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
|
||||||
|
|
||||||
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
|
||||||
maxtime.tv_usec = 0;
|
maxtime.tv_usec = 0;
|
||||||
|
|
||||||
timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
|
timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime,
|
||||||
&timebuf);
|
&timebuf);
|
||||||
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
||||||
if(milli == 0)
|
if(milli == 0)
|
||||||
milli += 10;
|
milli += 10;
|
||||||
Curl_expire(conn->data, milli, EXPIRE_ASYNC_NAME);
|
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||||
|
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
@ -286,9 +286,8 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|||||||
* return number of sockets it worked on
|
* return number of sockets it worked on
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
|
static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
int nfds;
|
int nfds;
|
||||||
int bitmask;
|
int bitmask;
|
||||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||||
@ -296,7 +295,7 @@ static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
|
|||||||
int i;
|
int i;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
|
bitmask = ares_getsock((ares_channel)data->state.async.resolver, socks,
|
||||||
ARES_GETSOCK_MAXNUM);
|
ARES_GETSOCK_MAXNUM);
|
||||||
|
|
||||||
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
|
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
|
||||||
@ -324,12 +323,12 @@ static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
|
|||||||
if(!nfds)
|
if(!nfds)
|
||||||
/* Call ares_process() unconditonally here, even if we simply timed out
|
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||||
above, as otherwise the ares name resolve won't timeout! */
|
above, as otherwise the ares name resolve won't timeout! */
|
||||||
ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
|
ares_process_fd((ares_channel)data->state.async.resolver, ARES_SOCKET_BAD,
|
||||||
ARES_SOCKET_BAD);
|
ARES_SOCKET_BAD);
|
||||||
else {
|
else {
|
||||||
/* move through the descriptors and ask for processing on them */
|
/* move through the descriptors and ask for processing on them */
|
||||||
for(i = 0; i < num; i++)
|
for(i = 0; i < num; i++)
|
||||||
ares_process_fd((ares_channel)data->state.resolver,
|
ares_process_fd((ares_channel)data->state.async.resolver,
|
||||||
(pfd[i].revents & (POLLRDNORM|POLLIN))?
|
(pfd[i].revents & (POLLRDNORM|POLLIN))?
|
||||||
pfd[i].fd:ARES_SOCKET_BAD,
|
pfd[i].fd:ARES_SOCKET_BAD,
|
||||||
(pfd[i].revents & (POLLWRNORM|POLLOUT))?
|
(pfd[i].revents & (POLLWRNORM|POLLOUT))?
|
||||||
@ -345,17 +344,16 @@ static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
|
|||||||
*
|
*
|
||||||
* Returns normal CURLcode errors.
|
* Returns normal CURLcode errors.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **dns)
|
struct Curl_dns_entry **dns)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
struct thread_data *res = data->state.async.tdata;
|
||||||
struct thread_data *res = conn->async.tdata;
|
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
DEBUGASSERT(dns);
|
DEBUGASSERT(dns);
|
||||||
*dns = NULL;
|
*dns = NULL;
|
||||||
|
|
||||||
waitperform(conn, 0);
|
waitperform(data, 0);
|
||||||
|
|
||||||
/* Now that we've checked for any last minute results above, see if there are
|
/* Now that we've checked for any last minute results above, see if there are
|
||||||
any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
||||||
@ -376,26 +374,27 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
ARES_ECANCELLED synchronously for all pending responses. This will
|
ARES_ECANCELLED synchronously for all pending responses. This will
|
||||||
leave us with res->num_pending == 0, which is perfect for the next
|
leave us with res->num_pending == 0, which is perfect for the next
|
||||||
block. */
|
block. */
|
||||||
ares_cancel((ares_channel)data->state.resolver);
|
ares_cancel((ares_channel)data->state.async.resolver);
|
||||||
DEBUGASSERT(res->num_pending == 0);
|
DEBUGASSERT(res->num_pending == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(res && !res->num_pending) {
|
if(res && !res->num_pending) {
|
||||||
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
|
(void)Curl_addrinfo_callback(data, res->last_status, res->temp_ai);
|
||||||
/* temp_ai ownership is moved to the connection, so we need not free-up
|
/* temp_ai ownership is moved to the connection, so we need not free-up
|
||||||
them */
|
them */
|
||||||
res->temp_ai = NULL;
|
res->temp_ai = NULL;
|
||||||
|
|
||||||
if(!conn->async.dns) {
|
if(!data->state.async.dns) {
|
||||||
failf(data, "Could not resolve: %s (%s)",
|
failf(data, "Could not resolve: %s (%s)",
|
||||||
conn->async.hostname, ares_strerror(conn->async.status));
|
data->state.async.hostname,
|
||||||
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
ares_strerror(data->state.async.status));
|
||||||
|
result = data->conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||||
CURLE_COULDNT_RESOLVE_HOST;
|
CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*dns = conn->async.dns;
|
*dns = data->state.async.dns;
|
||||||
|
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(&data->state.async);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -412,11 +411,10 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
timediff_t timeout;
|
timediff_t timeout;
|
||||||
struct curltime now = Curl_now();
|
struct curltime now = Curl_now();
|
||||||
|
|
||||||
@ -426,7 +424,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
|||||||
timeout = Curl_timeleft(data, &now, TRUE);
|
timeout = Curl_timeleft(data, &now, TRUE);
|
||||||
if(timeout < 0) {
|
if(timeout < 0) {
|
||||||
/* already expired! */
|
/* already expired! */
|
||||||
connclose(conn, "Timed out before name resolve started");
|
connclose(data->conn, "Timed out before name resolve started");
|
||||||
return CURLE_OPERATION_TIMEDOUT;
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
if(!timeout)
|
if(!timeout)
|
||||||
@ -447,7 +445,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
|||||||
store.tv_sec = itimeout/1000;
|
store.tv_sec = itimeout/1000;
|
||||||
store.tv_usec = (itimeout%1000)*1000;
|
store.tv_usec = (itimeout%1000)*1000;
|
||||||
|
|
||||||
tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
|
tvp = ares_timeout((ares_channel)data->state.async.resolver, &store, &tv);
|
||||||
|
|
||||||
/* use the timeout period ares returned to us above if less than one
|
/* use the timeout period ares returned to us above if less than one
|
||||||
second is left, otherwise just use 1000ms to make sure the progress
|
second is left, otherwise just use 1000ms to make sure the progress
|
||||||
@ -457,10 +455,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
timeout_ms = 1000;
|
timeout_ms = 1000;
|
||||||
|
|
||||||
waitperform(conn, timeout_ms);
|
waitperform(data, timeout_ms);
|
||||||
result = Curl_resolver_is_resolved(conn, entry);
|
result = Curl_resolver_is_resolved(data, entry);
|
||||||
|
|
||||||
if(result || conn->async.done)
|
if(result || data->state.async.done)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(Curl_pgrsUpdate(data))
|
if(Curl_pgrsUpdate(data))
|
||||||
@ -481,17 +479,17 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
if(result)
|
if(result)
|
||||||
/* failure, so we cancel the ares operation */
|
/* failure, so we cancel the ares operation */
|
||||||
ares_cancel((ares_channel)data->state.resolver);
|
ares_cancel((ares_channel)data->state.async.resolver);
|
||||||
|
|
||||||
/* Operation complete, if the lookup was successful we now have the entry
|
/* Operation complete, if the lookup was successful we now have the entry
|
||||||
in the cache. */
|
in the cache. */
|
||||||
if(entry)
|
if(entry)
|
||||||
*entry = conn->async.dns;
|
*entry = data->state.async.dns;
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
/* close the connection, since we can't return failure here without
|
/* close the connection, since we can't return failure here without
|
||||||
cleaning up this connection properly. */
|
cleaning up this connection properly. */
|
||||||
connclose(conn, "c-ares resolve failed");
|
connclose(data->conn, "c-ares resolve failed");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -525,7 +523,7 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
|||||||
#endif
|
#endif
|
||||||
struct hostent *hostent)
|
struct hostent *hostent)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = (struct connectdata *)arg;
|
struct Curl_easy *data = (struct Curl_easy *)arg;
|
||||||
struct thread_data *res;
|
struct thread_data *res;
|
||||||
|
|
||||||
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
|
||||||
@ -537,12 +535,12 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
|||||||
be valid so only defer it when we know the 'status' says its fine! */
|
be valid so only defer it when we know the 'status' says its fine! */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
res = conn->async.tdata;
|
res = data->state.async.tdata;
|
||||||
if(res) {
|
if(res) {
|
||||||
res->num_pending--;
|
res->num_pending--;
|
||||||
|
|
||||||
if(CURL_ASYNC_SUCCESS == status) {
|
if(CURL_ASYNC_SUCCESS == status) {
|
||||||
struct Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
|
struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->state.async.port);
|
||||||
if(ai) {
|
if(ai) {
|
||||||
compound_results(res, ai);
|
compound_results(res, ai);
|
||||||
}
|
}
|
||||||
@ -607,8 +605,8 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
|||||||
c-ares retry cycle each request is.
|
c-ares retry cycle each request is.
|
||||||
*/
|
*/
|
||||||
res->happy_eyeballs_dns_time = Curl_now();
|
res->happy_eyeballs_dns_time = Curl_now();
|
||||||
Curl_expire(
|
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT,
|
||||||
conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
|
EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,19 +619,18 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
|||||||
* memory we need to free after use. That memory *MUST* be freed with
|
* memory we need to free after use. That memory *MUST* be freed with
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
* Curl_freeaddrinfo(), nothing else.
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
char *bufp;
|
char *bufp;
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
int family = PF_INET;
|
int family = PF_INET;
|
||||||
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
*waitp = 0; /* default to synchronous response */
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
switch(conn->ip_version) {
|
switch(data->set.ipver) {
|
||||||
default:
|
default:
|
||||||
#if ARES_VERSION >= 0x010601
|
#if ARES_VERSION >= 0x010601
|
||||||
family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
|
family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
|
||||||
@ -653,19 +650,19 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
bufp = strdup(hostname);
|
bufp = strdup(hostname);
|
||||||
if(bufp) {
|
if(bufp) {
|
||||||
struct thread_data *res = NULL;
|
struct thread_data *res = NULL;
|
||||||
free(conn->async.hostname);
|
free(data->state.async.hostname);
|
||||||
conn->async.hostname = bufp;
|
data->state.async.hostname = bufp;
|
||||||
conn->async.port = port;
|
data->state.async.port = port;
|
||||||
conn->async.done = FALSE; /* not done */
|
data->state.async.done = FALSE; /* not done */
|
||||||
conn->async.status = 0; /* clear */
|
data->state.async.status = 0; /* clear */
|
||||||
conn->async.dns = NULL; /* clear */
|
data->state.async.dns = NULL; /* clear */
|
||||||
res = calloc(sizeof(struct thread_data), 1);
|
res = calloc(sizeof(struct thread_data), 1);
|
||||||
if(!res) {
|
if(!res) {
|
||||||
free(conn->async.hostname);
|
free(data->state.async.hostname);
|
||||||
conn->async.hostname = NULL;
|
data->state.async.hostname = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
conn->async.tdata = res;
|
data->state.async.tdata = res;
|
||||||
|
|
||||||
/* initial status - failed */
|
/* initial status - failed */
|
||||||
res->last_status = ARES_ENOTFOUND;
|
res->last_status = ARES_ENOTFOUND;
|
||||||
@ -675,17 +672,17 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
res->num_pending = 2;
|
res->num_pending = 2;
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
|
||||||
PF_INET, query_completed_cb, conn);
|
PF_INET, query_completed_cb, data);
|
||||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
|
||||||
PF_INET6, query_completed_cb, conn);
|
PF_INET6, query_completed_cb, data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res->num_pending = 1;
|
res->num_pending = 1;
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname,
|
ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
|
||||||
PF_INET, query_completed_cb, conn);
|
PF_INET, query_completed_cb, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -694,8 +691,9 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
res->num_pending = 1;
|
res->num_pending = 1;
|
||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
|
ares_gethostbyname((ares_channel)data->state.async.resolver,
|
||||||
query_completed_cb, conn);
|
hostname, family,
|
||||||
|
query_completed_cb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
*waitp = 1; /* expect asynchronous response */
|
*waitp = 1; /* expect asynchronous response */
|
||||||
@ -720,9 +718,10 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
|||||||
|
|
||||||
#if (ARES_VERSION >= 0x010704)
|
#if (ARES_VERSION >= 0x010704)
|
||||||
#if (ARES_VERSION >= 0x010b00)
|
#if (ARES_VERSION >= 0x010b00)
|
||||||
ares_result = ares_set_servers_ports_csv(data->state.resolver, servers);
|
ares_result = ares_set_servers_ports_csv(data->state.async.resolver,
|
||||||
|
servers);
|
||||||
#else
|
#else
|
||||||
ares_result = ares_set_servers_csv(data->state.resolver, servers);
|
ares_result = ares_set_servers_csv(data->state.async.resolver, servers);
|
||||||
#endif
|
#endif
|
||||||
switch(ares_result) {
|
switch(ares_result) {
|
||||||
case ARES_SUCCESS:
|
case ARES_SUCCESS:
|
||||||
@ -752,7 +751,7 @@ CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
|||||||
if(!interf)
|
if(!interf)
|
||||||
interf = "";
|
interf = "";
|
||||||
|
|
||||||
ares_set_local_dev((ares_channel)data->state.resolver, interf);
|
ares_set_local_dev((ares_channel)data->state.async.resolver, interf);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
#else /* c-ares version too old! */
|
#else /* c-ares version too old! */
|
||||||
@ -777,7 +776,8 @@ CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
|
ares_set_local_ip4((ares_channel)data->state.async.resolver,
|
||||||
|
ntohl(a4.s_addr));
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
#else /* c-ares version too old! */
|
#else /* c-ares version too old! */
|
||||||
@ -803,7 +803,7 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ares_set_local_ip6((ares_channel)data->state.resolver, a6);
|
ares_set_local_ip6((ares_channel)data->state.async.resolver, a6);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
#else /* c-ares version too old! */
|
#else /* c-ares version too old! */
|
||||||
|
@ -145,13 +145,13 @@ static void destroy_async_data(struct Curl_async *);
|
|||||||
/*
|
/*
|
||||||
* Cancel all possibly still on-going resolves for this connection.
|
* Cancel all possibly still on-going resolves for this connection.
|
||||||
*/
|
*/
|
||||||
void Curl_resolver_cancel(struct connectdata *conn)
|
void Curl_resolver_cancel(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(&data->state.async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is used to init a threaded resolve */
|
/* This function is used to init a threaded resolve */
|
||||||
static bool init_resolve_thread(struct connectdata *conn,
|
static bool init_resolve_thread(struct Curl_easy *data,
|
||||||
const char *hostname, int port,
|
const char *hostname, int port,
|
||||||
const struct addrinfo *hints);
|
const struct addrinfo *hints);
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ struct thread_sync_data {
|
|||||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
char *hostname; /* hostname to resolve, Curl_async.hostname
|
||||||
duplicate */
|
duplicate */
|
||||||
#ifdef USE_SOCKETPAIR
|
#ifdef USE_SOCKETPAIR
|
||||||
struct connectdata *conn;
|
struct Curl_easy *data;
|
||||||
curl_socket_t sock_pair[2]; /* socket pair */
|
curl_socket_t sock_pair[2]; /* socket pair */
|
||||||
#endif
|
#endif
|
||||||
int sock_error;
|
int sock_error;
|
||||||
@ -182,9 +182,9 @@ struct thread_data {
|
|||||||
struct thread_sync_data tsd;
|
struct thread_sync_data tsd;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
|
static struct thread_sync_data *conn_thread_sync_data(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
return &(conn->async.tdata->tsd);
|
return &(data->state.async.tdata->tsd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy resolver thread synchronization data */
|
/* Destroy resolver thread synchronization data */
|
||||||
@ -268,12 +268,12 @@ int init_thread_sync_data(struct thread_data *td,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getaddrinfo_complete(struct connectdata *conn)
|
static int getaddrinfo_complete(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct thread_sync_data *tsd = conn_thread_sync_data(conn);
|
struct thread_sync_data *tsd = conn_thread_sync_data(data);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
|
rc = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res);
|
||||||
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
|
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
|
||||||
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
|
||||||
*/
|
*/
|
||||||
@ -384,7 +384,7 @@ static void destroy_async_data(struct Curl_async *async)
|
|||||||
int done;
|
int done;
|
||||||
#ifdef USE_SOCKETPAIR
|
#ifdef USE_SOCKETPAIR
|
||||||
curl_socket_t sock_rd = td->tsd.sock_pair[0];
|
curl_socket_t sock_rd = td->tsd.sock_pair[0];
|
||||||
struct connectdata *conn = td->tsd.conn;
|
struct Curl_easy *data = td->tsd.data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -412,8 +412,7 @@ static void destroy_async_data(struct Curl_async *async)
|
|||||||
* ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
|
* ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
|
||||||
* before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
|
* before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
|
||||||
*/
|
*/
|
||||||
if(conn)
|
Curl_multi_closed(data, sock_rd);
|
||||||
Curl_multi_closed(conn->data, sock_rd);
|
|
||||||
sclose(sock_rd);
|
sclose(sock_rd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -429,32 +428,33 @@ static void destroy_async_data(struct Curl_async *async)
|
|||||||
*
|
*
|
||||||
* Returns FALSE in case of failure, otherwise TRUE.
|
* Returns FALSE in case of failure, otherwise TRUE.
|
||||||
*/
|
*/
|
||||||
static bool init_resolve_thread(struct connectdata *conn,
|
static bool init_resolve_thread(struct Curl_easy *data,
|
||||||
const char *hostname, int port,
|
const char *hostname, int port,
|
||||||
const struct addrinfo *hints)
|
const struct addrinfo *hints)
|
||||||
{
|
{
|
||||||
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
struct thread_data *td = calloc(1, sizeof(struct thread_data));
|
||||||
int err = ENOMEM;
|
int err = ENOMEM;
|
||||||
|
struct Curl_async *asp = &data->state.async;
|
||||||
|
|
||||||
conn->async.tdata = td;
|
data->state.async.tdata = td;
|
||||||
if(!td)
|
if(!td)
|
||||||
goto errno_exit;
|
goto errno_exit;
|
||||||
|
|
||||||
conn->async.port = port;
|
asp->port = port;
|
||||||
conn->async.done = FALSE;
|
asp->done = FALSE;
|
||||||
conn->async.status = 0;
|
asp->status = 0;
|
||||||
conn->async.dns = NULL;
|
asp->dns = NULL;
|
||||||
td->thread_hnd = curl_thread_t_null;
|
td->thread_hnd = curl_thread_t_null;
|
||||||
|
|
||||||
if(!init_thread_sync_data(td, hostname, port, hints)) {
|
if(!init_thread_sync_data(td, hostname, port, hints)) {
|
||||||
conn->async.tdata = NULL;
|
asp->tdata = NULL;
|
||||||
free(td);
|
free(td);
|
||||||
goto errno_exit;
|
goto errno_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(conn->async.hostname);
|
free(asp->hostname);
|
||||||
conn->async.hostname = strdup(hostname);
|
asp->hostname = strdup(hostname);
|
||||||
if(!conn->async.hostname)
|
if(!asp->hostname)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
||||||
/* The thread will set this to 1 when complete. */
|
/* The thread will set this to 1 when complete. */
|
||||||
@ -476,7 +476,7 @@ static bool init_resolve_thread(struct connectdata *conn,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(asp);
|
||||||
|
|
||||||
errno_exit:
|
errno_exit:
|
||||||
errno = err;
|
errno = err;
|
||||||
@ -488,12 +488,13 @@ static bool init_resolve_thread(struct connectdata *conn,
|
|||||||
* error
|
* error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static CURLcode resolver_error(struct connectdata *conn)
|
static CURLcode resolver_error(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
const char *host_or_proxy;
|
const char *host_or_proxy;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
|
struct connectdata *conn = data->conn;
|
||||||
if(conn->bits.httpproxy) {
|
if(conn->bits.httpproxy) {
|
||||||
host_or_proxy = "proxy";
|
host_or_proxy = "proxy";
|
||||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||||
@ -505,8 +506,8 @@ static CURLcode resolver_error(struct connectdata *conn)
|
|||||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
|
|
||||||
failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
|
failf(data, "Could not resolve %s: %s", host_or_proxy,
|
||||||
conn->async.hostname);
|
data->state.async.hostname);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -514,37 +515,39 @@ static CURLcode resolver_error(struct connectdata *conn)
|
|||||||
/*
|
/*
|
||||||
* 'entry' may be NULL and then no data is returned
|
* 'entry' may be NULL and then no data is returned
|
||||||
*/
|
*/
|
||||||
static CURLcode thread_wait_resolv(struct connectdata *conn,
|
static CURLcode thread_wait_resolv(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **entry,
|
struct Curl_dns_entry **entry,
|
||||||
bool report)
|
bool report)
|
||||||
{
|
{
|
||||||
struct thread_data *td = conn->async.tdata;
|
struct thread_data *td;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
DEBUGASSERT(conn && td);
|
DEBUGASSERT(data);
|
||||||
|
td = data->state.async.tdata;
|
||||||
|
DEBUGASSERT(td);
|
||||||
DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
|
DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
|
||||||
|
|
||||||
/* wait for the thread to resolve the name */
|
/* wait for the thread to resolve the name */
|
||||||
if(Curl_thread_join(&td->thread_hnd)) {
|
if(Curl_thread_join(&td->thread_hnd)) {
|
||||||
if(entry)
|
if(entry)
|
||||||
result = getaddrinfo_complete(conn);
|
result = getaddrinfo_complete(data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DEBUGASSERT(0);
|
DEBUGASSERT(0);
|
||||||
|
|
||||||
conn->async.done = TRUE;
|
data->state.async.done = TRUE;
|
||||||
|
|
||||||
if(entry)
|
if(entry)
|
||||||
*entry = conn->async.dns;
|
*entry = data->state.async.dns;
|
||||||
|
|
||||||
if(!conn->async.dns && report)
|
if(!data->state.async.dns && report)
|
||||||
/* a name was not resolved, report error */
|
/* a name was not resolved, report error */
|
||||||
result = resolver_error(conn);
|
result = resolver_error(data);
|
||||||
|
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(&data->state.async);
|
||||||
|
|
||||||
if(!conn->async.dns && report)
|
if(!data->state.async.dns && report)
|
||||||
connclose(conn, "asynch resolve failed");
|
connclose(data->conn, "asynch resolve failed");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -554,17 +557,17 @@ static CURLcode thread_wait_resolv(struct connectdata *conn,
|
|||||||
* Until we gain a way to signal the resolver threads to stop early, we must
|
* Until we gain a way to signal the resolver threads to stop early, we must
|
||||||
* simply wait for them and ignore their results.
|
* simply wait for them and ignore their results.
|
||||||
*/
|
*/
|
||||||
void Curl_resolver_kill(struct connectdata *conn)
|
void Curl_resolver_kill(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct thread_data *td = conn->async.tdata;
|
struct thread_data *td = data->state.async.tdata;
|
||||||
|
|
||||||
/* If we're still resolving, we must wait for the threads to fully clean up,
|
/* If we're still resolving, we must wait for the threads to fully clean up,
|
||||||
unfortunately. Otherwise, we can simply cancel to clean up any resolver
|
unfortunately. Otherwise, we can simply cancel to clean up any resolver
|
||||||
data. */
|
data. */
|
||||||
if(td && td->thread_hnd != curl_thread_t_null)
|
if(td && td->thread_hnd != curl_thread_t_null)
|
||||||
(void)thread_wait_resolv(conn, NULL, FALSE);
|
(void)thread_wait_resolv(data, NULL, FALSE);
|
||||||
else
|
else
|
||||||
Curl_resolver_cancel(conn);
|
Curl_resolver_cancel(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -580,10 +583,10 @@ void Curl_resolver_kill(struct connectdata *conn)
|
|||||||
*
|
*
|
||||||
* This is the version for resolves-in-a-thread.
|
* This is the version for resolves-in-a-thread.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
return thread_wait_resolv(conn, entry, TRUE);
|
return thread_wait_resolv(data, entry, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -591,11 +594,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
|||||||
* name resolve request has completed. It should also make sure to time-out if
|
* name resolve request has completed. It should also make sure to time-out if
|
||||||
* the operation seems to take too long.
|
* the operation seems to take too long.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
struct thread_data *td = data->state.async.tdata;
|
||||||
struct thread_data *td = conn->async.tdata;
|
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
DEBUGASSERT(entry);
|
DEBUGASSERT(entry);
|
||||||
@ -611,15 +613,15 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
Curl_mutex_release(td->tsd.mtx);
|
Curl_mutex_release(td->tsd.mtx);
|
||||||
|
|
||||||
if(done) {
|
if(done) {
|
||||||
getaddrinfo_complete(conn);
|
getaddrinfo_complete(data);
|
||||||
|
|
||||||
if(!conn->async.dns) {
|
if(!data->state.async.dns) {
|
||||||
CURLcode result = resolver_error(conn);
|
CURLcode result = resolver_error(data);
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(&data->state.async);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
destroy_async_data(&conn->async);
|
destroy_async_data(&data->state.async);
|
||||||
*entry = conn->async.dns;
|
*entry = data->state.async.dns;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||||
@ -640,22 +642,20 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
td->poll_interval = 250;
|
td->poll_interval = 250;
|
||||||
|
|
||||||
td->interval_end = elapsed + td->poll_interval;
|
td->interval_end = elapsed + td->poll_interval;
|
||||||
Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME);
|
Curl_expire(data, td->poll_interval, EXPIRE_ASYNC_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Curl_resolver_getsock(struct connectdata *conn,
|
int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||||
curl_socket_t *socks)
|
|
||||||
{
|
{
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
timediff_t milli;
|
timediff_t milli;
|
||||||
timediff_t ms;
|
timediff_t ms;
|
||||||
struct Curl_easy *data = conn->data;
|
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
|
||||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
|
||||||
#ifdef USE_SOCKETPAIR
|
#ifdef USE_SOCKETPAIR
|
||||||
struct thread_data *td = conn->async.tdata;
|
struct thread_data *td = data->state.async.tdata;
|
||||||
#else
|
#else
|
||||||
(void)socks;
|
(void)socks;
|
||||||
#endif
|
#endif
|
||||||
@ -664,8 +664,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|||||||
if(td) {
|
if(td) {
|
||||||
/* return read fd to client for polling the DNS resolution status */
|
/* return read fd to client for polling the DNS resolution status */
|
||||||
socks[0] = td->tsd.sock_pair[0];
|
socks[0] = td->tsd.sock_pair[0];
|
||||||
DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn);
|
td->tsd.data = data;
|
||||||
td->tsd.conn = conn;
|
|
||||||
ret_val = GETSOCK_READSOCK(0);
|
ret_val = GETSOCK_READSOCK(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -692,12 +691,11 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
|||||||
/*
|
/*
|
||||||
* Curl_getaddrinfo() - for platforms without getaddrinfo
|
* Curl_getaddrinfo() - for platforms without getaddrinfo
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
||||||
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
*waitp = 0; /* default to synchronous response */
|
||||||
@ -705,7 +703,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
reslv->start = Curl_now();
|
reslv->start = Curl_now();
|
||||||
|
|
||||||
/* fire up a new resolver thread! */
|
/* fire up a new resolver thread! */
|
||||||
if(init_resolve_thread(conn, hostname, port, NULL)) {
|
if(init_resolve_thread(data, hostname, port, NULL)) {
|
||||||
*waitp = 1; /* expect asynchronous response */
|
*waitp = 1; /* expect asynchronous response */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -720,15 +718,14 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
/*
|
/*
|
||||||
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
* Curl_resolver_getaddrinfo() - for getaddrinfo
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int pf = PF_INET;
|
int pf = PF_INET;
|
||||||
struct Curl_easy *data = conn->data;
|
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
|
||||||
struct resdata *reslv = (struct resdata *)data->state.resolver;
|
|
||||||
|
|
||||||
*waitp = 0; /* default to synchronous response */
|
*waitp = 0; /* default to synchronous response */
|
||||||
|
|
||||||
@ -736,7 +733,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
/*
|
/*
|
||||||
* Check if a limited name resolve has been requested.
|
* Check if a limited name resolve has been requested.
|
||||||
*/
|
*/
|
||||||
switch(conn->ip_version) {
|
switch(data->set.ipver) {
|
||||||
case CURL_IPRESOLVE_V4:
|
case CURL_IPRESOLVE_V4:
|
||||||
pf = PF_INET;
|
pf = PF_INET;
|
||||||
break;
|
break;
|
||||||
@ -755,12 +752,12 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = pf;
|
hints.ai_family = pf;
|
||||||
hints.ai_socktype = (conn->transport == TRNSPRT_TCP)?
|
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
|
||||||
SOCK_STREAM : SOCK_DGRAM;
|
SOCK_STREAM : SOCK_DGRAM;
|
||||||
|
|
||||||
reslv->start = Curl_now();
|
reslv->start = Curl_now();
|
||||||
/* fire up a new resolver thread! */
|
/* fire up a new resolver thread! */
|
||||||
if(init_resolve_thread(conn, hostname, port, &hints)) {
|
if(init_resolve_thread(data, hostname, port, &hints)) {
|
||||||
*waitp = 1; /* expect asynchronous response */
|
*waitp = 1; /* expect asynchronous response */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
14
lib/asyn.h
14
lib/asyn.h
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -91,7 +91,7 @@ CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to,
|
|||||||
*
|
*
|
||||||
* It is safe to call this when conn is in any state.
|
* It is safe to call this when conn is in any state.
|
||||||
*/
|
*/
|
||||||
void Curl_resolver_cancel(struct connectdata *conn);
|
void Curl_resolver_cancel(struct Curl_easy *data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_resolver_kill().
|
* Curl_resolver_kill().
|
||||||
@ -104,7 +104,7 @@ void Curl_resolver_cancel(struct connectdata *conn);
|
|||||||
*
|
*
|
||||||
* It is safe to call this when conn is in any state.
|
* It is safe to call this when conn is in any state.
|
||||||
*/
|
*/
|
||||||
void Curl_resolver_kill(struct connectdata *conn);
|
void Curl_resolver_kill(struct Curl_easy *data);
|
||||||
|
|
||||||
/* Curl_resolver_getsock()
|
/* Curl_resolver_getsock()
|
||||||
*
|
*
|
||||||
@ -114,7 +114,7 @@ void Curl_resolver_kill(struct connectdata *conn);
|
|||||||
* return bitmask indicating what file descriptors (referring to array indexes
|
* return bitmask indicating what file descriptors (referring to array indexes
|
||||||
* in the 'sock' array) to wait for, read/write.
|
* in the 'sock' array) to wait for, read/write.
|
||||||
*/
|
*/
|
||||||
int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock);
|
int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *sock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_resolver_is_resolved()
|
* Curl_resolver_is_resolved()
|
||||||
@ -125,7 +125,7 @@ int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock);
|
|||||||
*
|
*
|
||||||
* Returns normal CURLcode errors.
|
* Returns normal CURLcode errors.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **dns);
|
struct Curl_dns_entry **dns);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -139,7 +139,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
|||||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **dnsentry);
|
struct Curl_dns_entry **dnsentry);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -153,7 +153,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
|||||||
* Each resolver backend must of course make sure to return data in the
|
* Each resolver backend must of course make sure to return data in the
|
||||||
* correct format to comply with this.
|
* correct format to comply with this.
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp);
|
int *waitp);
|
||||||
|
@ -358,9 +358,9 @@ static CURLcode bindlocal(struct Curl_easy *data,
|
|||||||
conn->ip_version = CURL_IPRESOLVE_V6;
|
conn->ip_version = CURL_IPRESOLVE_V6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rc = Curl_resolv(conn, dev, 0, FALSE, &h);
|
rc = Curl_resolv(data, dev, 0, FALSE, &h);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
(void)Curl_resolver_wait_resolv(conn, &h);
|
(void)Curl_resolver_wait_resolv(data, &h);
|
||||||
conn->ip_version = ipver;
|
conn->ip_version = ipver;
|
||||||
|
|
||||||
if(h) {
|
if(h) {
|
||||||
|
15
lib/doh.c
15
lib/doh.c
@ -379,21 +379,21 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
|||||||
* 'Curl_addrinfo *' with the address information.
|
* 'Curl_addrinfo *' with the address information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
int slot;
|
int slot;
|
||||||
struct dohdata *dohp;
|
struct dohdata *dohp;
|
||||||
|
struct connectdata *conn = data->conn;
|
||||||
*waitp = TRUE; /* this never returns synchronously */
|
*waitp = TRUE; /* this never returns synchronously */
|
||||||
(void)conn;
|
|
||||||
(void)hostname;
|
(void)hostname;
|
||||||
(void)port;
|
(void)port;
|
||||||
|
|
||||||
DEBUGASSERT(!data->req.doh);
|
DEBUGASSERT(!data->req.doh);
|
||||||
|
DEBUGASSERT(conn);
|
||||||
|
|
||||||
/* start clean, consider allocating this struct on demand */
|
/* start clean, consider allocating this struct on demand */
|
||||||
dohp = data->req.doh = calloc(sizeof(struct dohdata), 1);
|
dohp = data->req.doh = calloc(sizeof(struct dohdata), 1);
|
||||||
@ -911,11 +911,10 @@ UNITTEST void de_cleanup(struct dohentry *d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **dnsp)
|
struct Curl_dns_entry **dnsp)
|
||||||
{
|
{
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
struct dohdata *dohp = data->req.doh;
|
struct dohdata *dohp = data->req.doh;
|
||||||
*dnsp = NULL; /* defaults to no response */
|
*dnsp = NULL; /* defaults to no response */
|
||||||
if(!dohp)
|
if(!dohp)
|
||||||
@ -923,8 +922,8 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
|
|
||||||
if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
|
if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
|
||||||
!dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
|
!dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
|
||||||
failf(data, "Could not DOH-resolve: %s", conn->async.hostname);
|
failf(data, "Could not DOH-resolve: %s", data->state.async.hostname);
|
||||||
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
return data->conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||||
CURLE_COULDNT_RESOLVE_HOST;
|
CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
else if(!dohp->pending) {
|
else if(!dohp->pending) {
|
||||||
@ -984,7 +983,7 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
Curl_freeaddrinfo(ai);
|
Curl_freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conn->async.dns = dns;
|
data->state.async.dns = dns;
|
||||||
*dnsp = dns;
|
*dnsp = dns;
|
||||||
result = CURLE_OK; /* address resolution OK */
|
result = CURLE_OK; /* address resolution OK */
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -32,12 +32,12 @@
|
|||||||
* and returns a 'Curl_addrinfo *' with the address information.
|
* and returns a 'Curl_addrinfo *' with the address information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp);
|
int *waitp);
|
||||||
|
|
||||||
CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **dns);
|
struct Curl_dns_entry **dns);
|
||||||
|
|
||||||
int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks);
|
int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks);
|
||||||
|
@ -908,8 +908,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
|||||||
#endif
|
#endif
|
||||||
/* Clone the resolver handle, if present, for the new handle */
|
/* Clone the resolver handle, if present, for the new handle */
|
||||||
if(Curl_resolver_duphandle(outcurl,
|
if(Curl_resolver_duphandle(outcurl,
|
||||||
&outcurl->state.resolver,
|
&outcurl->state.async.resolver,
|
||||||
data->state.resolver))
|
data->state.async.resolver))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
#ifdef USE_ARES
|
#ifdef USE_ARES
|
||||||
|
12
lib/ftp.c
12
lib/ftp.c
@ -1079,9 +1079,9 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* resolv ip/host to ip */
|
/* resolv ip/host to ip */
|
||||||
rc = Curl_resolv(conn, host, 0, FALSE, &h);
|
rc = Curl_resolv(data, host, 0, FALSE, &h);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
(void)Curl_resolver_wait_resolv(conn, &h);
|
(void)Curl_resolver_wait_resolv(data, &h);
|
||||||
if(h) {
|
if(h) {
|
||||||
res = h->addr;
|
res = h->addr;
|
||||||
/* when we return from this function, we can forget about this entry
|
/* when we return from this function, we can forget about this entry
|
||||||
@ -1945,11 +1945,11 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
|||||||
*/
|
*/
|
||||||
const char * const host_name = conn->bits.socksproxy ?
|
const char * const host_name = conn->bits.socksproxy ?
|
||||||
conn->socks_proxy.host.name : conn->http_proxy.host.name;
|
conn->socks_proxy.host.name : conn->http_proxy.host.name;
|
||||||
rc = Curl_resolv(conn, host_name, (int)conn->port, FALSE, &addr);
|
rc = Curl_resolv(data, host_name, (int)conn->port, FALSE, &addr);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
||||||
case of failure */
|
case of failure */
|
||||||
(void)Curl_resolver_wait_resolv(conn, &addr);
|
(void)Curl_resolver_wait_resolv(data, &addr);
|
||||||
|
|
||||||
connectport =
|
connectport =
|
||||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||||
@ -1974,10 +1974,10 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
|
rc = Curl_resolv(data, ftpc->newhost, ftpc->newport, FALSE, &addr);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
(void)Curl_resolver_wait_resolv(conn, &addr);
|
(void)Curl_resolver_wait_resolv(data, &addr);
|
||||||
|
|
||||||
connectport = ftpc->newport; /* we connect to the remote port */
|
connectport = ftpc->newport; /* we connect to the remote port */
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -66,25 +66,23 @@
|
|||||||
*
|
*
|
||||||
* The storage operation locks and unlocks the DNS cache.
|
* The storage operation locks and unlocks the DNS cache.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
CURLcode Curl_addrinfo_callback(struct Curl_easy *data,
|
||||||
int status,
|
int status,
|
||||||
struct Curl_addrinfo *ai)
|
struct Curl_addrinfo *ai)
|
||||||
{
|
{
|
||||||
struct Curl_dns_entry *dns = NULL;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
conn->async.status = status;
|
data->state.async.status = status;
|
||||||
|
|
||||||
if(CURL_ASYNC_SUCCESS == status) {
|
if(CURL_ASYNC_SUCCESS == status) {
|
||||||
if(ai) {
|
if(ai) {
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
|
|
||||||
dns = Curl_cache_addr(data, ai,
|
dns = Curl_cache_addr(data, ai,
|
||||||
conn->async.hostname,
|
data->state.async.hostname,
|
||||||
conn->async.port);
|
data->state.async.port);
|
||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||||
|
|
||||||
@ -99,12 +97,12 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->async.dns = dns;
|
data->state.async.dns = dns;
|
||||||
|
|
||||||
/* Set async.done TRUE last in this function since it may be used multi-
|
/* Set async.done TRUE last in this function since it may be used multi-
|
||||||
threaded and once this is TRUE the other thread may read fields from the
|
threaded and once this is TRUE the other thread may read fields from the
|
||||||
async struct */
|
async struct */
|
||||||
conn->async.done = TRUE;
|
data->state.async.done = TRUE;
|
||||||
|
|
||||||
/* IPv4: The input hostent struct will be freed by ares when we return from
|
/* IPv4: The input hostent struct will be freed by ares when we return from
|
||||||
this function */
|
this function */
|
||||||
@ -117,12 +115,12 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
|||||||
* name resolve layers (selected at build-time). They all take this same set
|
* name resolve layers (selected at build-time). They all take this same set
|
||||||
* of arguments
|
* of arguments
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
|
return Curl_resolver_getaddrinfo(data, hostname, port, waitp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CURLRES_ASYNCH */
|
#endif /* CURLRES_ASYNCH */
|
||||||
|
63
lib/hostip.c
63
lib/hostip.c
@ -253,14 +253,12 @@ sigjmp_buf curl_jmpenv;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* lookup address, returns entry if found and not stale */
|
/* lookup address, returns entry if found and not stale */
|
||||||
static struct Curl_dns_entry *
|
static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
|
||||||
fetch_addr(struct connectdata *conn,
|
const char *hostname,
|
||||||
const char *hostname,
|
int port)
|
||||||
int port)
|
|
||||||
{
|
{
|
||||||
struct Curl_dns_entry *dns = NULL;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
size_t entry_len;
|
size_t entry_len;
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
char entry_id[MAX_HOSTCACHE_LEN];
|
char entry_id[MAX_HOSTCACHE_LEN];
|
||||||
|
|
||||||
/* Create an entry id, based upon the hostname and port */
|
/* Create an entry id, based upon the hostname and port */
|
||||||
@ -321,7 +319,7 @@ Curl_fetch_addr(struct connectdata *conn,
|
|||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
|
|
||||||
dns = fetch_addr(conn, hostname, port);
|
dns = fetch_addr(data, hostname, port);
|
||||||
|
|
||||||
if(dns)
|
if(dns)
|
||||||
dns->inuse++; /* we use it! */
|
dns->inuse++; /* we use it! */
|
||||||
@ -480,16 +478,16 @@ Curl_cache_addr(struct Curl_easy *data,
|
|||||||
* CURLRESOLV_PENDING (1) = waiting for response, no pointer
|
* CURLRESOLV_PENDING (1) = waiting for response, no pointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum resolve_t Curl_resolv(struct connectdata *conn,
|
enum resolve_t Curl_resolv(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
bool allowDOH,
|
bool allowDOH,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
struct Curl_dns_entry *dns = NULL;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
|
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
|
||||||
|
struct connectdata *conn = data->conn;
|
||||||
|
|
||||||
*entry = NULL;
|
*entry = NULL;
|
||||||
conn->bits.doh = FALSE; /* default is not */
|
conn->bits.doh = FALSE; /* default is not */
|
||||||
@ -497,7 +495,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
|||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
|
|
||||||
dns = fetch_addr(conn, hostname, port);
|
dns = fetch_addr(data, hostname, port);
|
||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
infof(data, "Hostname %s was found in DNS cache\n", hostname);
|
infof(data, "Hostname %s was found in DNS cache\n", hostname);
|
||||||
@ -523,7 +521,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
|||||||
if(data->set.resolver_start) {
|
if(data->set.resolver_start) {
|
||||||
int st;
|
int st;
|
||||||
Curl_set_in_callback(data, true);
|
Curl_set_in_callback(data, true);
|
||||||
st = data->set.resolver_start(data->state.resolver, NULL,
|
st = data->set.resolver_start(data->state.async.resolver, NULL,
|
||||||
data->set.resolver_start_client);
|
data->set.resolver_start_client);
|
||||||
Curl_set_in_callback(data, false);
|
Curl_set_in_callback(data, false);
|
||||||
if(st)
|
if(st)
|
||||||
@ -569,13 +567,13 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
|||||||
return CURLRESOLV_ERROR;
|
return CURLRESOLV_ERROR;
|
||||||
|
|
||||||
if(allowDOH && data->set.doh && !ipnum) {
|
if(allowDOH && data->set.doh && !ipnum) {
|
||||||
addr = Curl_doh(conn, hostname, port, &respwait);
|
addr = Curl_doh(data, hostname, port, &respwait);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
|
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
|
||||||
non-zero value indicating that we need to wait for the response to
|
non-zero value indicating that we need to wait for the response to
|
||||||
the resolve call */
|
the resolve call */
|
||||||
addr = Curl_getaddrinfo(conn,
|
addr = Curl_getaddrinfo(data,
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
(data->set.str[STRING_DEVICE]
|
(data->set.str[STRING_DEVICE]
|
||||||
&& !strcmp(data->set.str[STRING_DEVICE],
|
&& !strcmp(data->set.str[STRING_DEVICE],
|
||||||
@ -589,7 +587,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
|
|||||||
/* the response to our resolve call will come asynchronously at
|
/* the response to our resolve call will come asynchronously at
|
||||||
a later time, good or bad */
|
a later time, good or bad */
|
||||||
/* First, check that we haven't received the info by now */
|
/* First, check that we haven't received the info by now */
|
||||||
result = Curl_resolv_check(conn, &dns);
|
result = Curl_resolv_check(data, &dns);
|
||||||
if(result) /* error detected */
|
if(result) /* error detected */
|
||||||
return CURLRESOLV_ERROR;
|
return CURLRESOLV_ERROR;
|
||||||
if(dns)
|
if(dns)
|
||||||
@ -658,7 +656,7 @@ RETSIGTYPE alarmfunc(int sig)
|
|||||||
* CURLRESOLV_PENDING (1) = waiting for response, no pointer
|
* CURLRESOLV_PENDING (1) = waiting for response, no pointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
struct Curl_dns_entry **entry,
|
struct Curl_dns_entry **entry,
|
||||||
@ -676,7 +674,6 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
|||||||
#endif /* HAVE_SIGACTION */
|
#endif /* HAVE_SIGACTION */
|
||||||
volatile long timeout;
|
volatile long timeout;
|
||||||
volatile unsigned int prev_alarm = 0;
|
volatile unsigned int prev_alarm = 0;
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
#endif /* USE_ALARM_TIMEOUT */
|
#endif /* USE_ALARM_TIMEOUT */
|
||||||
enum resolve_t rc;
|
enum resolve_t rc;
|
||||||
|
|
||||||
@ -695,7 +692,7 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
|||||||
|
|
||||||
if(!timeout)
|
if(!timeout)
|
||||||
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
|
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
|
||||||
return Curl_resolv(conn, hostname, port, TRUE, entry);
|
return Curl_resolv(data, hostname, port, TRUE, entry);
|
||||||
|
|
||||||
if(timeout < 1000) {
|
if(timeout < 1000) {
|
||||||
/* The alarm() function only provides integer second resolution, so if
|
/* The alarm() function only provides integer second resolution, so if
|
||||||
@ -748,7 +745,7 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
|||||||
#else
|
#else
|
||||||
#ifndef CURLRES_ASYNCH
|
#ifndef CURLRES_ASYNCH
|
||||||
if(timeoutms)
|
if(timeoutms)
|
||||||
infof(conn->data, "timeout on name lookup is not supported\n");
|
infof(data, "timeout on name lookup is not supported\n");
|
||||||
#else
|
#else
|
||||||
(void)timeoutms; /* timeoutms not used with an async resolver */
|
(void)timeoutms; /* timeoutms not used with an async resolver */
|
||||||
#endif
|
#endif
|
||||||
@ -757,7 +754,7 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
|||||||
/* Perform the actual name resolution. This might be interrupted by an
|
/* Perform the actual name resolution. This might be interrupted by an
|
||||||
* alarm if it takes too long.
|
* alarm if it takes too long.
|
||||||
*/
|
*/
|
||||||
rc = Curl_resolv(conn, hostname, port, TRUE, entry);
|
rc = Curl_resolv(data, hostname, port, TRUE, entry);
|
||||||
|
|
||||||
#ifdef USE_ALARM_TIMEOUT
|
#ifdef USE_ALARM_TIMEOUT
|
||||||
clean_up:
|
clean_up:
|
||||||
@ -784,7 +781,7 @@ clean_up:
|
|||||||
if(prev_alarm) {
|
if(prev_alarm) {
|
||||||
/* there was an alarm() set before us, now put it back */
|
/* there was an alarm() set before us, now put it back */
|
||||||
timediff_t elapsed_secs = Curl_timediff(Curl_now(),
|
timediff_t elapsed_secs = Curl_timediff(Curl_now(),
|
||||||
conn->created) / 1000;
|
data->conn->created) / 1000;
|
||||||
|
|
||||||
/* the alarm period is counted in even number of seconds */
|
/* the alarm period is counted in even number of seconds */
|
||||||
unsigned long alarm_set = (unsigned long)(prev_alarm - elapsed_secs);
|
unsigned long alarm_set = (unsigned long)(prev_alarm - elapsed_secs);
|
||||||
@ -1068,29 +1065,29 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_resolv_check(struct connectdata *conn,
|
CURLcode Curl_resolv_check(struct Curl_easy *data,
|
||||||
struct Curl_dns_entry **dns)
|
struct Curl_dns_entry **dns)
|
||||||
{
|
{
|
||||||
#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
|
#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
|
||||||
(void)dns;
|
(void)dns;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(conn->bits.doh)
|
if(data->conn->bits.doh)
|
||||||
return Curl_doh_is_resolved(conn, dns);
|
return Curl_doh_is_resolved(data, dns);
|
||||||
return Curl_resolver_is_resolved(conn, dns);
|
return Curl_resolver_is_resolved(data, dns);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Curl_resolv_getsock(struct connectdata *conn,
|
int Curl_resolv_getsock(struct Curl_easy *data,
|
||||||
curl_socket_t *socks)
|
curl_socket_t *socks)
|
||||||
{
|
{
|
||||||
#ifdef CURLRES_ASYNCH
|
#ifdef CURLRES_ASYNCH
|
||||||
if(conn->bits.doh)
|
if(data->conn->bits.doh)
|
||||||
/* nothing to wait for during DOH resolve, those handles have their own
|
/* nothing to wait for during DOH resolve, those handles have their own
|
||||||
sockets */
|
sockets */
|
||||||
return GETSOCK_BLANK;
|
return GETSOCK_BLANK;
|
||||||
return Curl_resolver_getsock(conn, socks);
|
return Curl_resolver_getsock(data, socks);
|
||||||
#else
|
#else
|
||||||
(void)conn;
|
(void)data;
|
||||||
(void)socks;
|
(void)socks;
|
||||||
return GETSOCK_BLANK;
|
return GETSOCK_BLANK;
|
||||||
#endif
|
#endif
|
||||||
@ -1101,21 +1098,19 @@ int Curl_resolv_getsock(struct connectdata *conn,
|
|||||||
|
|
||||||
Note: this function disconnects and frees the conn data in case of
|
Note: this function disconnects and frees the conn data in case of
|
||||||
resolve failure */
|
resolve failure */
|
||||||
CURLcode Curl_once_resolved(struct connectdata *conn,
|
CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_done)
|
||||||
bool *protocol_done)
|
|
||||||
{
|
{
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
struct connectdata *conn = data->conn;
|
||||||
|
|
||||||
if(conn->async.dns) {
|
if(data->state.async.dns) {
|
||||||
conn->dns_entry = conn->async.dns;
|
conn->dns_entry = data->state.async.dns;
|
||||||
conn->async.dns = NULL;
|
data->state.async.dns = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_setup_conn(conn, protocol_done);
|
result = Curl_setup_conn(conn, protocol_done);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
DEBUGASSERT(data);
|
|
||||||
Curl_detach_connnection(data);
|
Curl_detach_connnection(data);
|
||||||
Curl_conncache_remove_conn(data, conn, TRUE);
|
Curl_conncache_remove_conn(data, conn, TRUE);
|
||||||
Curl_disconnect(data, conn, TRUE);
|
Curl_disconnect(data, conn, TRUE);
|
||||||
|
15
lib/hostip.h
15
lib/hostip.h
@ -85,12 +85,12 @@ enum resolve_t {
|
|||||||
CURLRESOLV_RESOLVED = 0,
|
CURLRESOLV_RESOLVED = 0,
|
||||||
CURLRESOLV_PENDING = 1
|
CURLRESOLV_PENDING = 1
|
||||||
};
|
};
|
||||||
enum resolve_t Curl_resolv(struct connectdata *conn,
|
enum resolve_t Curl_resolv(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
bool allowDOH,
|
bool allowDOH,
|
||||||
struct Curl_dns_entry **dnsentry);
|
struct Curl_dns_entry **dnsentry);
|
||||||
enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
|
enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
|
||||||
const char *hostname, int port,
|
const char *hostname, int port,
|
||||||
struct Curl_dns_entry **dnsentry,
|
struct Curl_dns_entry **dnsentry,
|
||||||
timediff_t timeoutms);
|
timediff_t timeoutms);
|
||||||
@ -117,7 +117,7 @@ bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn);
|
|||||||
* name resolve layers (selected at build-time). They all take this same set
|
* name resolve layers (selected at build-time). They all take this same set
|
||||||
* of arguments
|
* of arguments
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp);
|
int *waitp);
|
||||||
@ -148,7 +148,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
|
|||||||
/* IPv4 threadsafe resolve function used for synch and asynch builds */
|
/* IPv4 threadsafe resolve function used for synch and asynch builds */
|
||||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
|
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
|
||||||
|
|
||||||
CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
|
CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_connect);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_addrinfo_callback() is used when we build with any asynch specialty.
|
* Curl_addrinfo_callback() is used when we build with any asynch specialty.
|
||||||
@ -156,7 +156,7 @@ CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
|
|||||||
* status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
|
* status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
|
||||||
* request completed whether successful or failed.
|
* request completed whether successful or failed.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
CURLcode Curl_addrinfo_callback(struct Curl_easy *data,
|
||||||
int status,
|
int status,
|
||||||
struct Curl_addrinfo *ai);
|
struct Curl_addrinfo *ai);
|
||||||
|
|
||||||
@ -240,10 +240,9 @@ void Curl_hostcache_clean(struct Curl_easy *data, struct Curl_hash *hash);
|
|||||||
* Populate the cache with specified entries from CURLOPT_RESOLVE.
|
* Populate the cache with specified entries from CURLOPT_RESOLVE.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_loadhostpairs(struct Curl_easy *data);
|
CURLcode Curl_loadhostpairs(struct Curl_easy *data);
|
||||||
|
CURLcode Curl_resolv_check(struct Curl_easy *data,
|
||||||
CURLcode Curl_resolv_check(struct connectdata *conn,
|
|
||||||
struct Curl_dns_entry **dns);
|
struct Curl_dns_entry **dns);
|
||||||
int Curl_resolv_getsock(struct connectdata *conn,
|
int Curl_resolv_getsock(struct Curl_easy *data,
|
||||||
curl_socket_t *socks);
|
curl_socket_t *socks);
|
||||||
|
|
||||||
#endif /* HEADER_CURL_HOSTIP_H */
|
#endif /* HEADER_CURL_HOSTIP_H */
|
||||||
|
@ -89,7 +89,7 @@ bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn)
|
|||||||
* flavours have thread-safe versions of the plain gethostbyname() etc.
|
* flavours have thread-safe versions of the plain gethostbyname() etc.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
@ -97,14 +97,14 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
struct Curl_addrinfo *ai = NULL;
|
struct Curl_addrinfo *ai = NULL;
|
||||||
|
|
||||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||||
(void)conn;
|
(void)data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*waitp = 0; /* synchronous response only */
|
*waitp = 0; /* synchronous response only */
|
||||||
|
|
||||||
ai = Curl_ipv4_resolve_r(hostname, port);
|
ai = Curl_ipv4_resolve_r(hostname, port);
|
||||||
if(!ai)
|
if(!ai)
|
||||||
infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
|
infof(data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
|
||||||
|
|
||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ static void dump_addrinfo(struct connectdata *conn,
|
|||||||
* memory we need to free after use. That memory *MUST* be freed with
|
* memory we need to free after use. That memory *MUST* be freed with
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
* Curl_freeaddrinfo(), nothing else.
|
||||||
*/
|
*/
|
||||||
struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
@ -141,14 +141,11 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
char addrbuf[128];
|
char addrbuf[128];
|
||||||
#endif
|
#endif
|
||||||
int pf;
|
int pf;
|
||||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
|
||||||
struct Curl_easy *data = conn->data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*waitp = 0; /* synchronous response only */
|
*waitp = 0; /* synchronous response only */
|
||||||
|
|
||||||
/* Check if a limited name resolve has been requested */
|
/* Check if a limited name resolve has been requested */
|
||||||
switch(conn->ip_version) {
|
switch(data->set.ipver) {
|
||||||
case CURL_IPRESOLVE_V4:
|
case CURL_IPRESOLVE_V4:
|
||||||
pf = PF_INET;
|
pf = PF_INET;
|
||||||
break;
|
break;
|
||||||
@ -166,7 +163,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = pf;
|
hints.ai_family = pf;
|
||||||
hints.ai_socktype = (conn->transport == TRNSPRT_TCP) ?
|
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ?
|
||||||
SOCK_STREAM : SOCK_DGRAM;
|
SOCK_STREAM : SOCK_DGRAM;
|
||||||
|
|
||||||
#ifndef USE_RESOLVE_ON_IPS
|
#ifndef USE_RESOLVE_ON_IPS
|
||||||
|
12
lib/multi.c
12
lib/multi.c
@ -565,7 +565,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
|||||||
conn->data = data; /* ensure the connection uses this transfer now */
|
conn->data = data; /* ensure the connection uses this transfer now */
|
||||||
|
|
||||||
/* Stop the resolver and free its own resources (but not dns_entry yet). */
|
/* Stop the resolver and free its own resources (but not dns_entry yet). */
|
||||||
Curl_resolver_kill(conn);
|
Curl_resolver_kill(data);
|
||||||
|
|
||||||
/* Cleanup possible redirect junk */
|
/* Cleanup possible redirect junk */
|
||||||
Curl_safefree(data->req.newurl);
|
Curl_safefree(data->req.newurl);
|
||||||
@ -995,7 +995,7 @@ static int multi_getsock(struct Curl_easy *data,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case CURLM_STATE_WAITRESOLVE:
|
case CURLM_STATE_WAITRESOLVE:
|
||||||
return Curl_resolv_getsock(conn, socks);
|
return Curl_resolv_getsock(data, socks);
|
||||||
|
|
||||||
case CURLM_STATE_PROTOCONNECT:
|
case CURLM_STATE_PROTOCONNECT:
|
||||||
case CURLM_STATE_SENDPROTOCONNECT:
|
case CURLM_STATE_SENDPROTOCONNECT:
|
||||||
@ -1733,15 +1733,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
#ifdef CURLRES_ASYNCH
|
#ifdef CURLRES_ASYNCH
|
||||||
conn->async.dns = dns;
|
data->state.async.dns = dns;
|
||||||
conn->async.done = TRUE;
|
data->state.async.done = TRUE;
|
||||||
#endif
|
#endif
|
||||||
result = CURLE_OK;
|
result = CURLE_OK;
|
||||||
infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
|
infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!dns)
|
if(!dns)
|
||||||
result = Curl_resolv_check(data->conn, &dns);
|
result = Curl_resolv_check(data, &dns);
|
||||||
|
|
||||||
/* Update sockets here, because the socket(s) may have been
|
/* Update sockets here, because the socket(s) may have been
|
||||||
closed and the application thus needs to be told, even if it
|
closed and the application thus needs to be told, even if it
|
||||||
@ -1754,7 +1754,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
if(dns) {
|
if(dns) {
|
||||||
/* Perform the next step in the connection phase, and then move on
|
/* Perform the next step in the connection phase, and then move on
|
||||||
to the WAITCONNECT state */
|
to the WAITCONNECT state */
|
||||||
result = Curl_once_resolved(data->conn, &protocol_connected);
|
result = Curl_once_resolved(data, &protocol_connected);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
/* if Curl_once_resolved() returns failure, the connection struct
|
/* if Curl_once_resolved() returns failure, the connection struct
|
||||||
|
16
lib/socks.c
16
lib/socks.c
@ -238,7 +238,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
|||||||
/* DNS resolve only for SOCKS4, not SOCKS4a */
|
/* DNS resolve only for SOCKS4, not SOCKS4a */
|
||||||
if(!protocol4a) {
|
if(!protocol4a) {
|
||||||
enum resolve_t rc =
|
enum resolve_t rc =
|
||||||
Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
|
Curl_resolv(data, hostname, remote_port, FALSE, &dns);
|
||||||
|
|
||||||
if(rc == CURLRESOLV_ERROR)
|
if(rc == CURLRESOLV_ERROR)
|
||||||
return CURLPX_RESOLVE_HOST;
|
return CURLPX_RESOLVE_HOST;
|
||||||
@ -261,14 +261,14 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
|
|||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
#ifdef CURLRES_ASYNCH
|
#ifdef CURLRES_ASYNCH
|
||||||
conn->async.dns = dns;
|
data->state.async.dns = dns;
|
||||||
conn->async.done = TRUE;
|
data->state.async.done = TRUE;
|
||||||
#endif
|
#endif
|
||||||
infof(data, "Hostname '%s' was found\n", hostname);
|
infof(data, "Hostname '%s' was found\n", hostname);
|
||||||
sxstate(data, CONNECT_RESOLVED);
|
sxstate(data, CONNECT_RESOLVED);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = Curl_resolv_check(data->conn, &dns);
|
result = Curl_resolv_check(data, &dns);
|
||||||
if(!dns) {
|
if(!dns) {
|
||||||
if(result)
|
if(result)
|
||||||
return CURLPX_RESOLVE_HOST;
|
return CURLPX_RESOLVE_HOST;
|
||||||
@ -754,7 +754,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
|||||||
CONNECT_REQ_INIT:
|
CONNECT_REQ_INIT:
|
||||||
case CONNECT_REQ_INIT:
|
case CONNECT_REQ_INIT:
|
||||||
if(socks5_resolve_local) {
|
if(socks5_resolve_local) {
|
||||||
enum resolve_t rc = Curl_resolv(conn, hostname, remote_port,
|
enum resolve_t rc = Curl_resolv(data, hostname, remote_port,
|
||||||
FALSE, &dns);
|
FALSE, &dns);
|
||||||
|
|
||||||
if(rc == CURLRESOLV_ERROR)
|
if(rc == CURLRESOLV_ERROR)
|
||||||
@ -775,14 +775,14 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
|
|||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
#ifdef CURLRES_ASYNCH
|
#ifdef CURLRES_ASYNCH
|
||||||
conn->async.dns = dns;
|
data->state.async.dns = dns;
|
||||||
conn->async.done = TRUE;
|
data->state.async.done = TRUE;
|
||||||
#endif
|
#endif
|
||||||
infof(data, "SOCKS5: hostname '%s' found\n", hostname);
|
infof(data, "SOCKS5: hostname '%s' found\n", hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!dns) {
|
if(!dns) {
|
||||||
result = Curl_resolv_check(data->conn, &dns);
|
result = Curl_resolv_check(data, &dns);
|
||||||
if(!dns) {
|
if(!dns) {
|
||||||
if(result)
|
if(result)
|
||||||
return CURLPX_RESOLVE_HOST;
|
return CURLPX_RESOLVE_HOST;
|
||||||
|
12
lib/url.c
12
lib/url.c
@ -427,7 +427,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
|
|||||||
Curl_safefree(data->info.wouldredirect);
|
Curl_safefree(data->info.wouldredirect);
|
||||||
|
|
||||||
/* this destroys the channel and we cannot use it anymore after this */
|
/* this destroys the channel and we cannot use it anymore after this */
|
||||||
Curl_resolver_cleanup(data->state.resolver);
|
Curl_resolver_cleanup(data->state.async.resolver);
|
||||||
|
|
||||||
Curl_http2_cleanup_dependencies(data);
|
Curl_http2_cleanup_dependencies(data);
|
||||||
Curl_convert_close(data);
|
Curl_convert_close(data);
|
||||||
@ -643,7 +643,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
|
|||||||
|
|
||||||
data->magic = CURLEASY_MAGIC_NUMBER;
|
data->magic = CURLEASY_MAGIC_NUMBER;
|
||||||
|
|
||||||
result = Curl_resolver_init(data, &data->state.resolver);
|
result = Curl_resolver_init(data, &data->state.async.resolver);
|
||||||
if(result) {
|
if(result) {
|
||||||
DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
|
DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
|
||||||
free(data);
|
free(data);
|
||||||
@ -664,7 +664,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
Curl_resolver_cleanup(data->state.resolver);
|
Curl_resolver_cleanup(data->state.async.resolver);
|
||||||
Curl_dyn_free(&data->state.headerb);
|
Curl_dyn_free(&data->state.headerb);
|
||||||
Curl_freeset(data);
|
Curl_freeset(data);
|
||||||
free(data);
|
free(data);
|
||||||
@ -722,7 +722,7 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
|
|||||||
infof(data, "Closing connection %ld\n", conn->connection_id);
|
infof(data, "Closing connection %ld\n", conn->connection_id);
|
||||||
|
|
||||||
/* possible left-overs from the async name resolvers */
|
/* possible left-overs from the async name resolvers */
|
||||||
Curl_resolver_cancel(conn);
|
Curl_resolver_cancel(data);
|
||||||
|
|
||||||
/* close the SSL stuff before we close any sockets since they will/may
|
/* close the SSL stuff before we close any sockets since they will/may
|
||||||
write to the sockets */
|
write to the sockets */
|
||||||
@ -3307,7 +3307,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
|||||||
conn->hostname_resolve = strdup(connhost->name);
|
conn->hostname_resolve = strdup(connhost->name);
|
||||||
if(!conn->hostname_resolve)
|
if(!conn->hostname_resolve)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
rc = Curl_resolv_timeout(conn, conn->hostname_resolve, (int)conn->port,
|
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
|
||||||
&hostaddr, timeout_ms);
|
&hostaddr, timeout_ms);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
*async = TRUE;
|
*async = TRUE;
|
||||||
@ -3332,7 +3332,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
|||||||
conn->hostname_resolve = strdup(host->name);
|
conn->hostname_resolve = strdup(host->name);
|
||||||
if(!conn->hostname_resolve)
|
if(!conn->hostname_resolve)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
rc = Curl_resolv_timeout(conn, conn->hostname_resolve, (int)conn->port,
|
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
|
||||||
&hostaddr, timeout_ms);
|
&hostaddr, timeout_ms);
|
||||||
|
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
|
@ -539,15 +539,21 @@ struct hostname {
|
|||||||
#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
|
#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
|
||||||
#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
|
#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
|
||||||
|
|
||||||
|
#if defined(CURLRES_ASYNCH) || !defined(CURL_DISABLE_DOH)
|
||||||
|
#define USE_CURL_ASYNC
|
||||||
struct Curl_async {
|
struct Curl_async {
|
||||||
char *hostname;
|
char *hostname;
|
||||||
int port;
|
|
||||||
int status; /* if done is TRUE, this is the status from the callback */
|
|
||||||
struct Curl_dns_entry *dns;
|
struct Curl_dns_entry *dns;
|
||||||
struct thread_data *tdata;
|
struct thread_data *tdata;
|
||||||
|
void *resolver; /* resolver state, if it is used in the URL state -
|
||||||
|
ares_channel f.e. */
|
||||||
|
int port;
|
||||||
|
int status; /* if done is TRUE, this is the status from the callback */
|
||||||
BIT(done); /* set TRUE when the lookup is complete */
|
BIT(done); /* set TRUE when the lookup is complete */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FIRSTSOCKET 0
|
#define FIRSTSOCKET 0
|
||||||
#define SECONDARYSOCKET 1
|
#define SECONDARYSOCKET 1
|
||||||
|
|
||||||
@ -1093,9 +1099,6 @@ struct connectdata {
|
|||||||
struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
|
struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* data used for the asynch name resolve callback */
|
|
||||||
struct Curl_async async;
|
|
||||||
|
|
||||||
/* for chunked-encoded trailer */
|
/* for chunked-encoded trailer */
|
||||||
struct dynbuf trailer;
|
struct dynbuf trailer;
|
||||||
|
|
||||||
@ -1330,7 +1333,6 @@ struct urlpieces {
|
|||||||
struct UrlState {
|
struct UrlState {
|
||||||
/* Points to the connection cache */
|
/* Points to the connection cache */
|
||||||
struct conncache *conn_cache;
|
struct conncache *conn_cache;
|
||||||
|
|
||||||
int retrycount; /* number of retries on a new connection */
|
int retrycount; /* number of retries on a new connection */
|
||||||
|
|
||||||
/* buffers to store authentication data in, as parsed from input options */
|
/* buffers to store authentication data in, as parsed from input options */
|
||||||
@ -1365,8 +1367,9 @@ struct UrlState {
|
|||||||
|
|
||||||
struct auth authhost; /* auth details for host */
|
struct auth authhost; /* auth details for host */
|
||||||
struct auth authproxy; /* auth details for proxy */
|
struct auth authproxy; /* auth details for proxy */
|
||||||
void *resolver; /* resolver state, if it is used in the URL state -
|
#ifdef USE_CURL_ASYNC
|
||||||
ares_channel f.e. */
|
struct Curl_async async; /* asynchronous name resolver data */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(USE_OPENSSL)
|
#if defined(USE_OPENSSL)
|
||||||
/* void instead of ENGINE to avoid bleeding OpenSSL into this header */
|
/* void instead of ENGINE to avoid bleeding OpenSSL into this header */
|
||||||
|
@ -32,7 +32,7 @@ http
|
|||||||
HTTP GET with localhost --interface
|
HTTP GET with localhost --interface
|
||||||
</name>
|
</name>
|
||||||
<command>
|
<command>
|
||||||
http://%HOSTIP:%HTTPPORT/1082 --interface localhost
|
http://%HOSTIP:%HTTPPORT/1082 -4 --interface localhost
|
||||||
</command>
|
</command>
|
||||||
<precheck>
|
<precheck>
|
||||||
perl -e "print 'Test requires default test client host address' if ( '%CLIENTIP' ne '127.0.0.1' );"
|
perl -e "print 'Test requires default test client host address' if ( '%CLIENTIP' ne '127.0.0.1' );"
|
||||||
|
Loading…
Reference in New Issue
Block a user