mirror of https://github.com/getdnsapi/getdns.git
Named upstreams
This commit is contained in:
parent
b86f149523
commit
b4083ddb6f
32
src/anchor.c
32
src/anchor.c
|
@ -1517,6 +1517,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
char tas_hostname[256];
|
||||
const char *verify_CA;
|
||||
const char *verify_email;
|
||||
getdns_context *sys_ctxt;
|
||||
|
||||
if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname"
|
||||
|
@ -1557,32 +1558,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__,
|
||||
loop == &context->sync_eventloop.loop ? "" : "a");
|
||||
|
||||
while (!context->sys_ctxt) { /* Used as breakable if. Never repeats. */
|
||||
if ((r = getdns_context_create_with_extended_memory_functions(
|
||||
&context->sys_ctxt, 1, context->mf.mf_arg,
|
||||
context->mf.mf.ext.malloc, context->mf.mf.ext.realloc,
|
||||
context->mf.mf.ext.free)))
|
||||
DEBUG_ANCHOR("Could not create system context: %s\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if ((r = getdns_context_set_eventloop(
|
||||
context->sys_ctxt, loop)))
|
||||
DEBUG_ANCHOR("Could not configure %ssynchronous loop "
|
||||
"with system context: %s\n"
|
||||
, ( loop == &context->sync_eventloop.loop
|
||||
? "" : "a" )
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if ((r = getdns_context_set_resolution_type(
|
||||
context->sys_ctxt, GETDNS_RESOLUTION_STUB)))
|
||||
DEBUG_ANCHOR("Could not configure system context for "
|
||||
"stub resolver: %s\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
else
|
||||
break;
|
||||
|
||||
getdns_context_destroy(context->sys_ctxt);
|
||||
context->sys_ctxt = NULL;
|
||||
if (!(sys_ctxt = _getdns_context_get_sys_ctxt(context, loop))) {
|
||||
DEBUG_ANCHOR("Fatal error fetching trust anchor: "
|
||||
"missing system context\n");
|
||||
context->trust_anchors_source = GETDNS_TASRC_FAILED;
|
||||
|
@ -1592,7 +1568,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
scheduled = 0;
|
||||
#if 1
|
||||
context->a.state = TAS_LOOKUP_ADDRESSES;
|
||||
if ((r = _getdns_general_loop(context->sys_ctxt, loop,
|
||||
if ((r = _getdns_general_loop(sys_ctxt, loop,
|
||||
tas_hostname, GETDNS_RRTYPE_A, NULL, context,
|
||||
&context->a.req, NULL, _tas_hostname_lookup_cb))) {
|
||||
DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n"
|
||||
|
@ -1603,7 +1579,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
|
||||
#if 1
|
||||
context->aaaa.state = TAS_LOOKUP_ADDRESSES;
|
||||
if ((r = _getdns_general_loop(context->sys_ctxt, loop,
|
||||
if ((r = _getdns_general_loop(sys_ctxt, loop,
|
||||
tas_hostname, GETDNS_RRTYPE_AAAA, NULL, context,
|
||||
&context->aaaa.req, NULL, _tas_hostname_lookup_cb))) {
|
||||
DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n"
|
||||
|
|
|
@ -37,26 +37,6 @@
|
|||
#include "config.h"
|
||||
#include "anchor.h"
|
||||
|
||||
#ifndef USE_WINSOCK
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
typedef unsigned short in_port_t;
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -952,7 +932,7 @@ static getdns_tsig_algo _getdns_get_tsig_algo(getdns_bindata *algo)
|
|||
return GETDNS_NO_TSIG;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
upstream_init(getdns_upstream *upstream,
|
||||
getdns_upstreams *parent, struct addrinfo *ai)
|
||||
{
|
||||
|
@ -964,6 +944,8 @@ upstream_init(getdns_upstream *upstream,
|
|||
} else
|
||||
upstream->addr_len = 0;
|
||||
|
||||
upstream->addr_notify = NULL;
|
||||
|
||||
/* How is this upstream doing on connections? */
|
||||
upstream->conn_completed = 0;
|
||||
upstream->conn_shutdowns = 0;
|
||||
|
@ -989,7 +971,6 @@ upstream_init(getdns_upstream *upstream,
|
|||
upstream->fd = -1;
|
||||
upstream->tls_obj = NULL;
|
||||
upstream->tls_session = NULL;
|
||||
upstream->transport = GETDNS_TRANSPORT_TCP;
|
||||
upstream->tls_hs_state = GETDNS_HS_NONE;
|
||||
upstream->tls_auth_name[0] = '\0';
|
||||
upstream->tls_auth_state = GETDNS_AUTH_NONE;
|
||||
|
@ -2763,7 +2744,7 @@ getdns_context_set_upstream_recursive_servers(getdns_context *context,
|
|||
size_t count = 0;
|
||||
size_t i;
|
||||
getdns_upstreams *upstreams;
|
||||
char addrstr[1024], portstr[1024], *eos;
|
||||
char addrstr[1024], portstr[11], *eos;
|
||||
struct addrinfo hints;
|
||||
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
@ -2827,6 +2808,9 @@ getdns_context_set_upstream_recursive_servers(getdns_context *context,
|
|||
if ((r = getdns_dict_get_bindata(
|
||||
dict, "name", &name)))
|
||||
goto error;
|
||||
else
|
||||
assert(name);
|
||||
|
||||
} else if (address_data->size == 4)
|
||||
addr.ss_family = AF_INET;
|
||||
else if (address_data->size == 16)
|
||||
|
@ -2935,20 +2919,25 @@ getdns_context_set_upstream_recursive_servers(getdns_context *context,
|
|||
|
||||
/* Loop to create upstreams as needed*/
|
||||
for (j = 0; j < GETDNS_UPSTREAM_TRANSPORTS; j++) {
|
||||
uint32_t port;
|
||||
struct addrinfo *ai;
|
||||
port = getdns_port_array[j];
|
||||
if (port == GETDNS_PORT_ZERO)
|
||||
|
||||
upstream = &upstreams->upstreams[upstreams->count];
|
||||
upstream->port = getdns_port_array[j];
|
||||
if (upstream->port == GETDNS_PORT_ZERO)
|
||||
continue;
|
||||
upstream->addr.ss_family = addr.ss_family;
|
||||
|
||||
if (getdns_upstream_transports[j] != GETDNS_TRANSPORT_TLS) {
|
||||
if (dict)
|
||||
(void) getdns_dict_get_int(dict, "port", &port);
|
||||
(void) getdns_dict_get_int(
|
||||
dict, "port", &upstream->port);
|
||||
} else {
|
||||
if (dict)
|
||||
(void) getdns_dict_get_int(dict, "tls_port", &port);
|
||||
(void) getdns_dict_get_int(
|
||||
dict, "tls_port", &upstream->port);
|
||||
}
|
||||
(void) snprintf(portstr, 1024, "%d", (int)port);
|
||||
(void) snprintf(
|
||||
portstr, sizeof(portstr), "%d", (int)upstream->port);
|
||||
|
||||
if (!name) {
|
||||
if (getaddrinfo(addrstr, portstr, &hints, &ai))
|
||||
|
@ -2962,8 +2951,6 @@ getdns_context_set_upstream_recursive_servers(getdns_context *context,
|
|||
* already exist (in case user has specified TLS port explicitly and
|
||||
* to prevent duplicates) */
|
||||
|
||||
upstream = &upstreams->upstreams[upstreams->count];
|
||||
upstream->addr.ss_family = addr.ss_family;
|
||||
(void)strncpy(upstream->addr_str, addrstr
|
||||
, sizeof(upstream->addr_str));
|
||||
upstream_init(upstream, upstreams, ai);
|
||||
|
@ -5024,5 +5011,40 @@ getdns_context_set_appdata_dir(
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_context *_getdns_context_get_sys_ctxt(
|
||||
getdns_context *context, getdns_eventloop *loop)
|
||||
{
|
||||
getdns_return_t r;
|
||||
|
||||
if (context->sys_ctxt)
|
||||
return context->sys_ctxt;
|
||||
|
||||
if ((r = getdns_context_create_with_extended_memory_functions(
|
||||
&context->sys_ctxt, 1, context->mf.mf_arg,
|
||||
context->mf.mf.ext.malloc, context->mf.mf.ext.realloc,
|
||||
context->mf.mf.ext.free)))
|
||||
DEBUG_ANCHOR("Could not create system context: %s\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if ((r = getdns_context_set_eventloop(
|
||||
context->sys_ctxt, loop)))
|
||||
DEBUG_ANCHOR("Could not configure %ssynchronous loop "
|
||||
"with system context: %s\n"
|
||||
, ( loop == &context->sync_eventloop.loop
|
||||
? "" : "a" )
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if ((r = getdns_context_set_resolution_type(
|
||||
context->sys_ctxt, GETDNS_RESOLUTION_STUB)))
|
||||
DEBUG_ANCHOR("Could not configure system context for "
|
||||
"stub resolver: %s\n"
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
else
|
||||
return context->sys_ctxt;
|
||||
|
||||
getdns_context_destroy(context->sys_ctxt);
|
||||
context->sys_ctxt = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* context.c */
|
||||
|
|
|
@ -37,9 +37,29 @@
|
|||
#ifndef _GETDNS_CONTEXT_H_
|
||||
#define _GETDNS_CONTEXT_H_
|
||||
|
||||
#include "config.h"
|
||||
#ifndef USE_WINSOCK
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
typedef unsigned short in_port_t;
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "getdns/getdns.h"
|
||||
#include "getdns/getdns_extra.h"
|
||||
#include "config.h"
|
||||
#include "types-internal.h"
|
||||
#include "extension/default_eventloop.h"
|
||||
#include "util/rbtree.h"
|
||||
|
@ -141,6 +161,8 @@ typedef struct getdns_upstream {
|
|||
socklen_t addr_len;
|
||||
struct sockaddr_storage addr;
|
||||
char addr_str[1024];
|
||||
getdns_network_req *addr_notify;
|
||||
uint32_t port;
|
||||
|
||||
/**
|
||||
* How is this upstream doing over UDP?
|
||||
|
@ -557,4 +579,10 @@ int _getdns_context_write_priv_file(getdns_context *context,
|
|||
|
||||
int _getdns_context_can_write_appdata(getdns_context *context);
|
||||
|
||||
getdns_context *_getdns_context_get_sys_ctxt(
|
||||
getdns_context *context, getdns_eventloop *loop);
|
||||
|
||||
void upstream_init(getdns_upstream *upstream,
|
||||
getdns_upstreams *parent, struct addrinfo *ai);
|
||||
|
||||
#endif /* _GETDNS_CONTEXT_H_ */
|
||||
|
|
|
@ -717,12 +717,12 @@ _getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_return_t
|
||||
_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callback)
|
||||
getdns_network_req **netreq_p, getdns_callback_t callback,
|
||||
internal_cb_t internal_cb)
|
||||
{
|
||||
getdns_dict *my_extensions = extensions;
|
||||
getdns_return_t r;
|
||||
uint32_t value;
|
||||
getdns_network_req *netreq = NULL;
|
||||
|
||||
if (!my_extensions) {
|
||||
if (!(my_extensions=getdns_dict_create_with_context(context)))
|
||||
|
@ -738,9 +738,7 @@ _getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
r = getdns_general_ns(context, loop,
|
||||
name, GETDNS_RRTYPE_AAAA, my_extensions,
|
||||
userarg, &netreq, callback, NULL, 1);
|
||||
if (netreq && transaction_id)
|
||||
*transaction_id = netreq->owner->trans_id;
|
||||
userarg, netreq_p, callback, internal_cb, 1);
|
||||
|
||||
if (my_extensions != extensions)
|
||||
getdns_dict_destroy(my_extensions);
|
||||
|
@ -882,10 +880,16 @@ getdns_address(getdns_context *context,
|
|||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callbackfn)
|
||||
{
|
||||
getdns_return_t r;
|
||||
getdns_network_req *netreq = NULL;
|
||||
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
return _getdns_address_loop(context, context->extension,
|
||||
name, extensions, userarg,
|
||||
transaction_id, callbackfn);
|
||||
r = _getdns_address_loop(context, context->extension,
|
||||
name, extensions, userarg, &netreq, callbackfn, NULL);
|
||||
if (netreq && transaction_id)
|
||||
*transaction_id = netreq->owner->trans_id;
|
||||
return r;
|
||||
|
||||
} /* getdns_address */
|
||||
|
||||
/*
|
||||
|
|
|
@ -70,8 +70,8 @@ _getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_return_t
|
||||
_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
getdns_callback_t callbackfn);
|
||||
void *userarg, getdns_network_req **netreq_p,
|
||||
getdns_callback_t callbackfn, internal_cb_t internal_cb);
|
||||
|
||||
getdns_return_t
|
||||
_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
|
|
|
@ -135,6 +135,7 @@ netreq_reset(getdns_network_req *net_req)
|
|||
net_req->query_id_registered = NULL;
|
||||
net_req->node.key = NULL;
|
||||
}
|
||||
net_req->addr_notify = NULL;
|
||||
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
net_req->response_len = 0;
|
||||
|
|
148
src/stub.c
148
src/stub.c
|
@ -61,6 +61,7 @@
|
|||
* level triggered). See also lines containing WSA TODO below...
|
||||
*/
|
||||
#define STUB_TRY_AGAIN_LATER -24 /* EMFILE, i.e. Out of OS resources */
|
||||
#define STUB_RESOLVE_UPSTREAM_NAME -89 /* EDESTADDRREQ, i.e. lookup name */
|
||||
#define STUB_NO_AUTH -8 /* Existing TLS connection is not authenticated */
|
||||
#define STUB_CONN_GONE -7 /* Connection has failed, clear queue*/
|
||||
#define STUB_TCP_RETRY -6
|
||||
|
@ -1750,7 +1751,7 @@ upstream_usable(getdns_upstream *upstream, int backoff_ok)
|
|||
upstream->keepalive_shutdown == 0)
|
||||
return 1;
|
||||
/* Otherwise, allow upstreams that are backed off to be used because that
|
||||
is better that having no upstream at all. */
|
||||
is better than having no upstream at all. */
|
||||
if (backoff_ok == 1 &&
|
||||
upstream->conn_state == GETDNS_CONN_BACKOFF)
|
||||
return 1;
|
||||
|
@ -1929,7 +1930,7 @@ upstream_select(getdns_network_req *netreq)
|
|||
|
||||
if (!upstreams->count)
|
||||
return NULL;
|
||||
/* First UPD/TCP upstream is always at i=0 and then start of each upstream block*/
|
||||
/* First UDP/TCP upstream is always at i=0 and then start of each upstream block*/
|
||||
/* TODO: Have direct access to sets of upstreams for different transports*/
|
||||
for (i = 0; i < upstreams->count; i+=GETDNS_UPSTREAM_TRANSPORTS)
|
||||
if (upstreams->upstreams[i].to_retry <= 0)
|
||||
|
@ -2020,7 +2021,8 @@ upstream_find_for_transport(getdns_network_req *netreq,
|
|||
no socket is available, in which case that is an error.*/
|
||||
if (transport == GETDNS_TRANSPORT_UDP) {
|
||||
upstream = upstream_select(netreq);
|
||||
*fd = upstream_connect(upstream, transport, netreq->owner);
|
||||
if (upstream->addr_len > 0) /* not an upstream by name */
|
||||
*fd = upstream_connect(upstream, transport, netreq->owner);
|
||||
return upstream;
|
||||
}
|
||||
else {
|
||||
|
@ -2032,6 +2034,8 @@ upstream_find_for_transport(getdns_network_req *netreq,
|
|||
upstream = upstream_select_stateful(netreq, transport);
|
||||
if (!upstream)
|
||||
return NULL;
|
||||
if (upstream->addr_len == 0) /* an upstream by name */
|
||||
return upstream;
|
||||
*fd = upstream_connect(upstream, transport, netreq->owner);
|
||||
if (i >= upstream->upstreams->count)
|
||||
return NULL;
|
||||
|
@ -2059,6 +2063,12 @@ upstream_find_for_netreq(getdns_network_req *netreq)
|
|||
if (!upstream)
|
||||
continue;
|
||||
|
||||
if (upstream->addr_len == 0) { /* upstream by name */
|
||||
netreq->transport_current = i;
|
||||
netreq->upstream = upstream;
|
||||
netreq->keepalive_sent = 0;
|
||||
return STUB_RESOLVE_UPSTREAM_NAME;
|
||||
}
|
||||
if (fd == -1) {
|
||||
if (_getdns_resource_depletion())
|
||||
return STUB_TRY_AGAIN_LATER;
|
||||
|
@ -2191,12 +2201,120 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
|
|||
}
|
||||
}
|
||||
|
||||
static int upstream_address_found(
|
||||
getdns_upstream *upstream, getdns_network_req *netreq)
|
||||
{
|
||||
_getdns_rrset_spc rrset_spc;
|
||||
_getdns_rrset *rrset;
|
||||
_getdns_rrtype_iter rr_spc, *rr;
|
||||
struct addrinfo hints;
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
hints.ai_flags = AI_NUMERICHOST; /* No reverse name lookups */
|
||||
|
||||
if (!(rrset = _getdns_rrset_answer(
|
||||
&rrset_spc, netreq->response, netreq->response_len)))
|
||||
; /* FORMERR */
|
||||
|
||||
else if (rrset->rr_type != netreq->request_type)
|
||||
; /* Can this happen? */
|
||||
|
||||
else if (!(rr = _getdns_rrtype_iter_init(&rr_spc, rrset)))
|
||||
; /* NOERROR */
|
||||
|
||||
else for(; rr; rr = _getdns_rrtype_iter_next(rr)) {
|
||||
struct sockaddr_storage addr;
|
||||
char addrstr[1024], portstr[11];
|
||||
struct addrinfo *ai;
|
||||
|
||||
if (rr->rr_i.nxt - (rr->rr_i.rr_type + 10) !=
|
||||
( netreq->request_type == GETDNS_RRTYPE_A ? 4
|
||||
: netreq->request_type == GETDNS_RRTYPE_AAAA ? 16 : -1))
|
||||
continue;
|
||||
|
||||
addr.ss_family = netreq->request_type == GETDNS_RRTYPE_A
|
||||
? AF_INET : AF_INET6;
|
||||
if (inet_ntop(addr.ss_family, rr->rr_i.rr_type + 10,
|
||||
addrstr, sizeof(addrstr)) == NULL)
|
||||
continue;
|
||||
|
||||
(void) snprintf( portstr, sizeof(portstr)
|
||||
, "%d", (int)upstream->port);
|
||||
|
||||
if (getaddrinfo(addrstr, portstr, &hints, &ai))
|
||||
continue;
|
||||
|
||||
(void)strncpy( upstream->addr_str, addrstr
|
||||
, sizeof(upstream->addr_str));
|
||||
upstream->addr_len = ai->ai_addrlen;
|
||||
(void) memcpy(&upstream->addr, ai->ai_addr, ai->ai_addrlen);
|
||||
freeaddrinfo(ai);
|
||||
return 1;
|
||||
}
|
||||
DEBUG_STUB("Some error!\n");
|
||||
return 0; /* Try the other netreq */
|
||||
}
|
||||
|
||||
static void upstream_name_cb(getdns_dns_req *dnsreq)
|
||||
{
|
||||
getdns_upstream *upstream = (getdns_upstream *)dnsreq->user_pointer;
|
||||
uint64_t now_ms = 0;
|
||||
getdns_network_req *addr_notify;
|
||||
|
||||
DEBUG_STUB("YAY: %d, %d\n", (int)dnsreq->netreqs[0]->response_len
|
||||
, (int)dnsreq->netreqs[1]->response_len);
|
||||
DEBUG_STUB("upstream: %p, upstream->addr_notify: %p\n",
|
||||
(void *)upstream, (void *)upstream->addr_notify);
|
||||
|
||||
if (dnsreq->netreqs[0]->response_len &&
|
||||
upstream_address_found(upstream, dnsreq->netreqs[0]))
|
||||
; /* pass */
|
||||
|
||||
else if (dnsreq->netreqs[1]->response_len &&
|
||||
upstream_address_found(upstream, dnsreq->netreqs[1]))
|
||||
; /* pass */
|
||||
|
||||
else {
|
||||
/* Fail this upstream */
|
||||
if (upstream->transport == GETDNS_TRANSPORT_UDP) {
|
||||
if (upstream->addr_notify)
|
||||
stub_next_upstream(upstream->addr_notify);
|
||||
} else
|
||||
upstream->conn_setup_failed++;
|
||||
|
||||
addr_notify = upstream->addr_notify;
|
||||
upstream->addr_notify = NULL;
|
||||
while (addr_notify) {
|
||||
DEBUG_STUB("Error netreq: %p", (void *)addr_notify);
|
||||
_getdns_netreq_change_state(
|
||||
addr_notify, NET_REQ_ERRORED);
|
||||
_getdns_check_dns_req_complete(
|
||||
addr_notify->owner);
|
||||
addr_notify = addr_notify->addr_notify;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Upstream has now changed to an address upstream,
|
||||
* so reschedule queries.
|
||||
*/
|
||||
addr_notify = upstream->addr_notify;
|
||||
upstream->addr_notify = NULL;
|
||||
while (addr_notify) {
|
||||
DEBUG_STUB("Resubmit netreq: %p", (void *)addr_notify);
|
||||
_getdns_submit_stub_request(addr_notify, &now_ms);
|
||||
addr_notify = addr_notify->addr_notify;
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_submit_stub_request(getdns_network_req *netreq, uint64_t *now_ms)
|
||||
{
|
||||
int fd = -1;
|
||||
getdns_dns_req *dnsreq;
|
||||
getdns_context *context;
|
||||
getdns_return_t r;
|
||||
getdns_context *sys_ctxt;
|
||||
|
||||
DEBUG_STUB("%s %-35s: MSG: %p TYPE: %d\n", STUB_DEBUG_ENTRY, __FUNC__,
|
||||
(void*)netreq, netreq->request_type);
|
||||
|
@ -2217,6 +2335,30 @@ _getdns_submit_stub_request(getdns_network_req *netreq, uint64_t *now_ms)
|
|||
&context->pending_netreqs, &netreq->node))
|
||||
return GETDNS_RETURN_GOOD;
|
||||
return GETDNS_RETURN_NO_UPSTREAM_AVAILABLE;
|
||||
|
||||
} else if (fd == STUB_RESOLVE_UPSTREAM_NAME) {
|
||||
assert( netreq->upstream->addr_len == 0);
|
||||
assert(*netreq->upstream->addr_str != 0);
|
||||
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_NOT_SENT);
|
||||
if (netreq->addr_notify) {
|
||||
netreq->addr_notify = netreq->upstream->addr_notify;
|
||||
netreq->upstream->addr_notify = netreq;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} else
|
||||
netreq->upstream->addr_notify = netreq;
|
||||
|
||||
if (!(sys_ctxt = _getdns_context_get_sys_ctxt(context, dnsreq->loop)))
|
||||
/* TODO: retry something else? */
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
DEBUG_STUB("Scheduling address lookup for: %s\n", netreq->upstream->addr_str);
|
||||
if ((r =_getdns_address_loop(sys_ctxt, dnsreq->loop,
|
||||
netreq->upstream->addr_str, NULL, netreq->upstream,
|
||||
NULL, NULL, upstream_name_cb)))
|
||||
return r;
|
||||
else
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
switch(netreq->transports[netreq->transport_current]) {
|
||||
case GETDNS_TRANSPORT_UDP:
|
||||
|
|
|
@ -199,7 +199,7 @@ getdns_address_sync(getdns_context *context, const char *name,
|
|||
return r;
|
||||
|
||||
if ((r = _getdns_address_loop(context, &context->sync_eventloop.loop,
|
||||
name, extensions, &data, NULL, getdns_sync_cb))) {
|
||||
name, extensions, &data, NULL, getdns_sync_cb, NULL))) {
|
||||
|
||||
getdns_sync_data_cleanup(&data);
|
||||
return r;
|
||||
|
|
|
@ -237,6 +237,11 @@ typedef struct getdns_network_req
|
|||
/* Network requests scheduled to write after me */
|
||||
struct getdns_network_req *write_queue_tail;
|
||||
|
||||
/* Network requests subscribed to be notified after me,
|
||||
* when an address lookup for a "name" upstream completed.
|
||||
*/
|
||||
struct getdns_network_req *addr_notify;
|
||||
|
||||
/* Some fields to record info for return_call_reporting */
|
||||
uint64_t debug_start_time;
|
||||
uint64_t debug_end_time;
|
||||
|
|
Loading…
Reference in New Issue