mirror of https://github.com/getdnsapi/getdns.git
timed synchronous resolves
Also returns an response dict with status GETDNS_RESPSTATUS_ALL_TIMEOUT on timeout
This commit is contained in:
parent
a0c2c05811
commit
fc2f091f05
|
@ -77,7 +77,7 @@ EXTENSION_LIBUV_LDFLAGS=@EXTENSION_LIBUV_LDFLAGS@
|
||||||
|
|
||||||
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
|
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
|
||||||
hostname.lo service.lo request-internal.lo util-internal.lo \
|
hostname.lo service.lo request-internal.lo util-internal.lo \
|
||||||
getdns_error.lo rr-dict.lo dnssec.lo const-info.lo
|
getdns_error.lo rr-dict.lo dnssec.lo const-info.lo ub_timed_resolve.lo
|
||||||
|
|
||||||
.SUFFIXES: .c .o .a .lo .h
|
.SUFFIXES: .c .o .a .lo .h
|
||||||
|
|
||||||
|
|
24
src/dnssec.c
24
src/dnssec.c
|
@ -47,6 +47,7 @@
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
#include "dnssec.h"
|
#include "dnssec.h"
|
||||||
#include "rr-dict.h"
|
#include "rr-dict.h"
|
||||||
|
#include "ub_timed_resolve.h"
|
||||||
|
|
||||||
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
|
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ struct validation_chain {
|
||||||
getdns_dns_req *dns_req;
|
getdns_dns_req *dns_req;
|
||||||
size_t lock;
|
size_t lock;
|
||||||
struct getdns_dict **sync_response;
|
struct getdns_dict **sync_response;
|
||||||
|
uint64_t *timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chain_response {
|
struct chain_response {
|
||||||
|
@ -200,8 +202,8 @@ resolve(char* name, int rrtype, struct chain_response *response)
|
||||||
|
|
||||||
if (response->chain->sync_response) {
|
if (response->chain->sync_response) {
|
||||||
ub_res = NULL;
|
ub_res = NULL;
|
||||||
r = ub_resolve(response->chain->dns_req->context->unbound_ctx,
|
r = ub_timed_resolve(response->chain->dns_req->context->unbound_ctx,
|
||||||
name, rrtype, LDNS_RR_CLASS_IN, &ub_res);
|
name, rrtype, LDNS_RR_CLASS_IN, &ub_res, response->chain->timeout);
|
||||||
ub_chain_response_callback(response, r, ub_res);
|
ub_chain_response_callback(response, r, ub_res);
|
||||||
return r;
|
return r;
|
||||||
} else
|
} else
|
||||||
|
@ -243,8 +245,8 @@ launch_chain_link_lookup(struct validation_chain *chain, char *name)
|
||||||
chain->lock--;
|
chain->lock--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct validation_chain *create_chain(
|
static struct validation_chain *create_chain(getdns_dns_req *dns_req,
|
||||||
getdns_dns_req *dns_req, struct getdns_dict **sync_response)
|
struct getdns_dict **sync_response, uint64_t *timeout)
|
||||||
{
|
{
|
||||||
struct validation_chain *chain = GETDNS_MALLOC(
|
struct validation_chain *chain = GETDNS_MALLOC(
|
||||||
dns_req->context->mf, struct validation_chain);
|
dns_req->context->mf, struct validation_chain);
|
||||||
|
@ -261,6 +263,7 @@ static struct validation_chain *create_chain(
|
||||||
chain->dns_req = dns_req;
|
chain->dns_req = dns_req;
|
||||||
chain->lock = 0;
|
chain->lock = 0;
|
||||||
chain->sync_response = sync_response;
|
chain->sync_response = sync_response;
|
||||||
|
chain->timeout = timeout;
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,11 +287,12 @@ static void destroy_chain(struct validation_chain *chain)
|
||||||
|
|
||||||
/* Do some additional requests to fetch the complete validation chain */
|
/* Do some additional requests to fetch the complete validation chain */
|
||||||
static void
|
static void
|
||||||
getdns_get_validation_chain(
|
getdns_get_validation_chain(getdns_dns_req *dns_req,
|
||||||
getdns_dns_req *dns_req, struct getdns_dict **sync_response)
|
struct getdns_dict **sync_response, uint64_t *timeout)
|
||||||
{
|
{
|
||||||
getdns_network_req *netreq = dns_req->first_req;
|
getdns_network_req *netreq = dns_req->first_req;
|
||||||
struct validation_chain *chain = create_chain(dns_req, sync_response);
|
struct validation_chain *chain = create_chain(
|
||||||
|
dns_req, sync_response, timeout);
|
||||||
|
|
||||||
if (! chain) {
|
if (! chain) {
|
||||||
if (sync_response)
|
if (sync_response)
|
||||||
|
@ -315,14 +319,14 @@ getdns_get_validation_chain(
|
||||||
|
|
||||||
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req)
|
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req)
|
||||||
{
|
{
|
||||||
getdns_get_validation_chain(dns_req, NULL);
|
getdns_get_validation_chain(dns_req, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct getdns_dict *
|
struct getdns_dict *
|
||||||
priv_getdns_get_validation_chain_sync(getdns_dns_req *dns_req)
|
priv_getdns_get_validation_chain_sync(getdns_dns_req *dns_req, uint64_t *timeout)
|
||||||
{
|
{
|
||||||
struct getdns_dict *sync_response = NULL;
|
struct getdns_dict *sync_response = NULL;
|
||||||
getdns_get_validation_chain(dns_req, &sync_response);
|
getdns_get_validation_chain(dns_req, &sync_response, timeout);
|
||||||
return sync_response;
|
return sync_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req);
|
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req);
|
||||||
|
|
||||||
struct getdns_dict * priv_getdns_get_validation_chain_sync(
|
struct getdns_dict * priv_getdns_get_validation_chain_sync(
|
||||||
getdns_dns_req *dns_req);
|
getdns_dns_req *dns_req, uint64_t *timeout);
|
||||||
|
|
||||||
int priv_getdns_parse_ta_file(time_t *ta_mtime, ldns_rr_list *ta_rrs);
|
int priv_getdns_parse_ta_file(time_t *ta_mtime, ldns_rr_list *ta_rrs);
|
||||||
|
|
||||||
|
|
30
src/sync.c
30
src/sync.c
|
@ -42,30 +42,35 @@
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
#include "dnssec.h"
|
#include "dnssec.h"
|
||||||
|
#include "ub_timed_resolve.h"
|
||||||
|
|
||||||
/* stuff to make it compile pedantically */
|
/* stuff to make it compile pedantically */
|
||||||
#define UNUSED_PARAM(x) ((void)(x))
|
#define UNUSED_PARAM(x) ((void)(x))
|
||||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||||
|
|
||||||
getdns_return_t submit_request_sync(getdns_dns_req* req) {
|
static getdns_return_t submit_request_sync(
|
||||||
|
getdns_dns_req* req, uint64_t *timeout)
|
||||||
|
{
|
||||||
struct ub_result* ub_res = NULL;
|
struct ub_result* ub_res = NULL;
|
||||||
getdns_return_t gr = GETDNS_RETURN_GOOD;
|
getdns_return_t gr = GETDNS_RETURN_GOOD;
|
||||||
getdns_network_req *netreq = req->first_req;
|
getdns_network_req *netreq = req->first_req;
|
||||||
|
|
||||||
while (netreq) {
|
while (netreq) {
|
||||||
int r = ub_resolve(req->context->unbound_ctx,
|
int r = ub_timed_resolve(req->context->unbound_ctx,
|
||||||
req->name,
|
req->name,
|
||||||
netreq->request_type,
|
netreq->request_type,
|
||||||
netreq->request_class,
|
netreq->request_class,
|
||||||
&ub_res);
|
&ub_res,
|
||||||
if (r != 0) {
|
timeout);
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
gr = getdns_apply_network_result(netreq, ub_res);
|
gr = getdns_apply_network_result(netreq, ub_res);
|
||||||
ub_resolve_free(ub_res);
|
ub_resolve_free(ub_res);
|
||||||
ub_res = NULL;
|
ub_res = NULL;
|
||||||
if (gr != GETDNS_RETURN_GOOD) {
|
|
||||||
|
if (r != GETDNS_RETURN_GOOD)
|
||||||
|
return r;
|
||||||
|
else if (gr != GETDNS_RETURN_GOOD)
|
||||||
return gr;
|
return gr;
|
||||||
}
|
|
||||||
netreq = netreq->next;
|
netreq = netreq->next;
|
||||||
}
|
}
|
||||||
return gr;
|
return gr;
|
||||||
|
@ -80,6 +85,7 @@ getdns_general_sync(struct getdns_context *context,
|
||||||
{
|
{
|
||||||
getdns_dns_req *req;
|
getdns_dns_req *req;
|
||||||
getdns_return_t response_status;
|
getdns_return_t response_status;
|
||||||
|
uint64_t timeout = context->timeout;
|
||||||
|
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
RETURN_IF_NULL(response, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(response, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
@ -104,14 +110,16 @@ getdns_general_sync(struct getdns_context *context,
|
||||||
if (!req)
|
if (!req)
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
|
||||||
response_status = submit_request_sync(req);
|
response_status = submit_request_sync(req, &timeout);
|
||||||
if (response_status == GETDNS_RETURN_GOOD) {
|
if (response_status == GETDNS_RETURN_GOOD) {
|
||||||
if (is_extension_set(req->extensions,
|
if (is_extension_set(req->extensions,
|
||||||
"dnssec_return_validation_chain"))
|
"dnssec_return_validation_chain"))
|
||||||
*response = priv_getdns_get_validation_chain_sync(req);
|
*response = priv_getdns_get_validation_chain_sync(req, &timeout);
|
||||||
else
|
else
|
||||||
*response = create_getdns_response(req);
|
*response = create_getdns_response(req);
|
||||||
}
|
|
||||||
|
} else if (response_status == GETDNS_RESPSTATUS_ALL_TIMEOUT)
|
||||||
|
*response = create_getdns_response(req);
|
||||||
|
|
||||||
dns_req_free(req);
|
dns_req_free(req);
|
||||||
return response_status;
|
return response_status;
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* /brief A timed synchronous unbound resolve function
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, NLnet Labs, Verisign, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the names of the copyright holders nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "ub_timed_resolve.h"
|
||||||
|
|
||||||
|
static struct ub_result error_result;
|
||||||
|
|
||||||
|
static void cb_timed_resolve(void *my_arg, int err, struct ub_result *result)
|
||||||
|
{
|
||||||
|
struct ub_result **to_return = (struct ub_result **)my_arg;
|
||||||
|
*to_return = err ? &error_result : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ub_timed_resolve(struct ub_ctx* ctx, char* name,
|
||||||
|
int rrtype, int rrclass, struct ub_result** result, uint64_t *timeout)
|
||||||
|
{
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv, now, prev;
|
||||||
|
int r;
|
||||||
|
int ubfd;
|
||||||
|
int async_id;
|
||||||
|
uint64_t elapsed;
|
||||||
|
|
||||||
|
assert(ctx != NULL);
|
||||||
|
assert(name != NULL);
|
||||||
|
assert(result != NULL);
|
||||||
|
assert(timeout != NULL);
|
||||||
|
|
||||||
|
*result = NULL;
|
||||||
|
if (ub_resolve_async(ctx, name, rrtype, rrclass,
|
||||||
|
result, cb_timed_resolve, &async_id))
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
if (*result == &error_result) {
|
||||||
|
*result = NULL;
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
} else if (*result)
|
||||||
|
return GETDNS_RETURN_GOOD; /* result came from cache */
|
||||||
|
|
||||||
|
ubfd = ub_fd(ctx);
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(ubfd, &rfds);
|
||||||
|
|
||||||
|
if (gettimeofday(&now, NULL) < 0) {
|
||||||
|
ub_cancel(ctx, async_id);
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
/* timeout is in miliseconds, so map to seconds and microseconds */
|
||||||
|
tv.tv_sec = *timeout / 1000;
|
||||||
|
tv.tv_usec = (*timeout % 1000) * 1000;
|
||||||
|
|
||||||
|
r = select(ubfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (r <= 0)
|
||||||
|
ub_cancel(ctx, async_id);
|
||||||
|
if (r < 0)
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
else if (r == 0)
|
||||||
|
return GETDNS_RESPSTATUS_ALL_TIMEOUT;
|
||||||
|
|
||||||
|
prev = now;
|
||||||
|
if (gettimeofday(&now, NULL) < 0) {
|
||||||
|
ub_cancel(ctx, async_id);
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
elapsed = now.tv_sec * 1000 + now.tv_usec / 1000;
|
||||||
|
elapsed -= prev.tv_sec * 1000 + prev.tv_usec / 1000;
|
||||||
|
if (elapsed > *timeout) {
|
||||||
|
*timeout = 0;
|
||||||
|
ub_cancel(ctx, async_id);
|
||||||
|
return GETDNS_RESPSTATUS_ALL_TIMEOUT;
|
||||||
|
}
|
||||||
|
*timeout -= elapsed;
|
||||||
|
|
||||||
|
/* We have readiness */
|
||||||
|
if (! ub_poll(ctx))
|
||||||
|
continue;
|
||||||
|
if (ub_process(ctx)) {
|
||||||
|
ub_cancel(ctx, async_id);
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
if (*result == &error_result) {
|
||||||
|
*result = NULL;
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
} else if (*result)
|
||||||
|
return GETDNS_RETURN_GOOD; /* result came from cache */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ub_timed_resolve.c */
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* /brief A timed synchronous unbound resolve function
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, NLnet Labs, Verisign, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the names of the copyright holders nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UB_TIMED_RESOLVE_H_
|
||||||
|
#define UB_TIMED_RESOLVE_H_
|
||||||
|
|
||||||
|
#include "getdns/getdns.h"
|
||||||
|
#include <unbound.h>
|
||||||
|
|
||||||
|
int ub_timed_resolve(struct ub_ctx *ctx, char *name,
|
||||||
|
int rrtype, int rrclass, struct ub_result **result, uint64_t *timeout);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ub_timed_resolve.h */
|
|
@ -556,9 +556,10 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
completed_request->extensions, "dnssec_return_status") ||
|
completed_request->extensions, "dnssec_return_status") ||
|
||||||
completed_request->return_dnssec_status == GETDNS_EXTENSION_TRUE;
|
completed_request->return_dnssec_status == GETDNS_EXTENSION_TRUE;
|
||||||
|
|
||||||
if (completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
|
if (completed_request->first_req &&
|
||||||
|
(completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
|
||||||
completed_request->first_req->request_class ==
|
completed_request->first_req->request_class ==
|
||||||
GETDNS_RRTYPE_AAAA) {
|
GETDNS_RRTYPE_AAAA)) {
|
||||||
just_addrs = getdns_list_create_with_context(
|
just_addrs = getdns_list_create_with_context(
|
||||||
completed_request->context);
|
completed_request->context);
|
||||||
}
|
}
|
||||||
|
@ -581,6 +582,9 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
; netreq && r == GETDNS_RETURN_GOOD
|
; netreq && r == GETDNS_RETURN_GOOD
|
||||||
; netreq = netreq->next ) {
|
; netreq = netreq->next ) {
|
||||||
|
|
||||||
|
if (! netreq->result)
|
||||||
|
continue;
|
||||||
|
|
||||||
nreplies++;
|
nreplies++;
|
||||||
if (netreq->secure)
|
if (netreq->secure)
|
||||||
nsecure++;
|
nsecure++;
|
||||||
|
@ -771,7 +775,18 @@ validate_extensions(struct getdns_dict * extensions)
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_apply_network_result(getdns_network_req* netreq,
|
getdns_apply_network_result(getdns_network_req* netreq,
|
||||||
struct ub_result* ub_res) {
|
struct ub_result* ub_res) {
|
||||||
if (ub_res->answer_packet == NULL) {
|
|
||||||
|
if (ub_res == NULL) { /* Timeout */
|
||||||
|
netreq->result = NULL;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
|
||||||
|
} else if (ub_res->answer_packet == NULL) {
|
||||||
|
if (ub_res->rcode == GETDNS_RCODE_SERVFAIL) {
|
||||||
|
/* Likely to be caused by timeout from a synchronous
|
||||||
|
* lookup. Don't forge a packet.
|
||||||
|
*/
|
||||||
|
netreq->result = NULL;
|
||||||
|
} else {
|
||||||
/* Likely to be because libunbound refused the request
|
/* Likely to be because libunbound refused the request
|
||||||
* so ub_res->answer_packet=NULL, ub_res->answer_len=0
|
* so ub_res->answer_packet=NULL, ub_res->answer_len=0
|
||||||
* So we need to create an answer packet.
|
* So we need to create an answer packet.
|
||||||
|
@ -781,6 +796,7 @@ getdns_apply_network_result(getdns_network_req* netreq,
|
||||||
netreq->request_type,
|
netreq->request_type,
|
||||||
netreq->request_class,LDNS_QR|LDNS_RD|LDNS_RA);
|
netreq->request_class,LDNS_QR|LDNS_RD|LDNS_RA);
|
||||||
ldns_pkt_set_rcode(netreq->result, ub_res->rcode);
|
ldns_pkt_set_rcode(netreq->result, ub_res->rcode);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ldns_status r =
|
ldns_status r =
|
||||||
ldns_wire2pkt(&(netreq->result), ub_res->answer_packet, ub_res->answer_len);
|
ldns_wire2pkt(&(netreq->result), ub_res->answer_packet, ub_res->answer_len);
|
||||||
|
|
Loading…
Reference in New Issue