Move stub resolving to stub.c again

Merged hostname.c and service.c in general so that getdns_general_ns can become static.
Removed specialized synchronous handling from return_validation_chain code.
Removed un_timed_resolve (specialized sync handling is not needed anymore)
Renamed inter-object file symbols to priv_<name> and made intra-object symbols static as much as possible.
This commit is contained in:
Willem Toorop 2014-10-15 23:04:39 +02:00
parent 02ea4ae82b
commit a0cb4e1774
12 changed files with 298 additions and 588 deletions

View File

@ -75,11 +75,9 @@ EXTENSION_LIBUV_LIB=@EXTENSION_LIBUV_LIB@
EXTENSION_LIBUV_EXT_LIBS=@EXTENSION_LIBUV_EXT_LIBS@
EXTENSION_LIBUV_LDFLAGS=@EXTENSION_LIBUV_LDFLAGS@
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
hostname.lo service.lo request-internal.lo util-internal.lo \
getdns_error.lo rr-dict.lo dnssec.lo const-info.lo \
ub_timed_resolve.lo stub.lo \
libmini_event.lo
GETDNS_OBJ=const-info.lo context.lo convert.lo dict.lo dnssec.lo general.lo \
getdns_error.lo libmini_event.lo list.lo request-internal.lo \
rr-dict.lo stub.lo sync.lo util-internal.lo
GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
str2wire.lo
@ -194,11 +192,14 @@ configure.status: configure
depend:
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
(cd $(srcdir) ; gcc -MM -I. gldns/*.c compat/*.c util/*.c extension/libmini_event.c| \
(cd $(srcdir) ; gcc -MM -I. *.c gldns/*.c compat/*.c util/*.c extension/libmini_event.c| \
sed -e 's?gldns/?$$(srcdir)/gldns/?g' \
-e 's?compat/?$$(srcdir)/compat/?g' \
-e 's?util/?$$(srcdir)/util/?g' \
-e 's?extension/?$$(srcdir)/extension/?g' \
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
-e 's? \$$(srcdir)/config\.h? config.h?g' \
-e 's? getdns/getdns_extra\.h? $$(srcdir)/getdns/getdns_extra.h?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' >> Makefile.in.new )
(cd $(srcdir) ; diff Makefile.in.new Makefile.in && rm Makefile.in.new \
|| mv Makefile.in.new Makefile.in )
@ -207,6 +208,53 @@ depend:
FORCE:
# Dependencies for gldns, utils, the mini_event extension and compat functions
const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h $(srcdir)/const-info.h
context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/context.h getdns/getdns.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h
convert.lo convert.o: $(srcdir)/convert.c getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h config.h $(srcdir)/types-internal.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/getdns_error.h
dict.lo dict.o: $(srcdir)/dict.c $(srcdir)/types-internal.h getdns/getdns.h $(srcdir)/getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h config.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/dict.h $(srcdir)/rr-dict.h $(srcdir)/const-info.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c getdns/getdns.h config.h $(srcdir)/context.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/rr-dict.h
general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/context.h getdns/getdns.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/stub.h
getdns_error.lo getdns_error.o: $(srcdir)/getdns_error.c getdns/getdns.h $(srcdir)/const-info.h
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h $(srcdir)/getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h config.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/list.h
request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h $(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util-internal.h \
$(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h \
$(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/gldns/rrdef.h
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/context.h config.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/dict.h
stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/general.h
sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h $(srcdir)/getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/general.h \
$(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h
util-internal.lo util-internal.o: $(srcdir)/util-internal.c getdns/getdns.h $(srcdir)/dict.h $(srcdir)/types-internal.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h \
config.h $(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h \
$(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-dict.h
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h
keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h
parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \
@ -223,6 +271,7 @@ mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/
$(srcdir)/util/fptr_wlist.h
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/rbtree.h
libmini_event.lo libmini_event.o: $(srcdir)/extension/libmini_event.c config.h \
$(srcdir)/extension/libmini_event.h types-internal.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
libmini_event.lo libmini_event.o: $(srcdir)/extension/libmini_event.c $(srcdir)/extension/libmini_event.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
getdns/getdns.h $(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/context.h config.h \
$(srcdir)/types-internal.h $(srcdir)/extension/libmini_event.h

View File

@ -47,7 +47,6 @@
#include "types-internal.h"
#include "dnssec.h"
#include "rr-dict.h"
#include "ub_timed_resolve.h"
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
@ -56,7 +55,6 @@ struct validation_chain {
struct mem_funcs mf;
getdns_dns_req *dns_req;
size_t lock;
struct getdns_dict **sync_response;
uint64_t *timeout;
};
@ -111,10 +109,7 @@ static void callback_on_complete_chain(struct validation_chain *chain)
getdns_keys);
getdns_list_destroy(getdns_keys);
ldns_rr_list_free(keys);
if (chain->sync_response) {
*chain->sync_response = response;
} else
priv_getdns_call_user_callback(dns_req, response);
priv_getdns_call_user_callback(dns_req, response);
destroy_chain(chain);
}
}
@ -197,20 +192,10 @@ static void chain_response_init(
static int
resolve(char* name, int rrtype, struct chain_response *response)
{
int r;
struct ub_result *ub_res;
if (response->chain->sync_response) {
ub_res = NULL;
r = ub_timed_resolve(response->chain->dns_req->context->unbound_ctx,
name, rrtype, LDNS_RR_CLASS_IN, &ub_res, response->chain->timeout);
ub_chain_response_callback(response, r, ub_res);
return r;
} else
return ub_resolve_async(
response->chain->dns_req->context->unbound_ctx,
name, rrtype, LDNS_RR_CLASS_IN, response,
ub_chain_response_callback, &response->unbound_id);
return ub_resolve_async(
response->chain->dns_req->context->unbound_ctx,
name, rrtype, LDNS_RR_CLASS_IN, response,
ub_chain_response_callback, &response->unbound_id);
}
static void
@ -246,7 +231,7 @@ launch_chain_link_lookup(struct validation_chain *chain, char *name)
}
static struct validation_chain *create_chain(getdns_dns_req *dns_req,
struct getdns_dict **sync_response, uint64_t *timeout)
uint64_t *timeout)
{
struct validation_chain *chain = GETDNS_MALLOC(
dns_req->context->mf, struct validation_chain);
@ -262,7 +247,6 @@ static struct validation_chain *create_chain(getdns_dns_req *dns_req,
chain->mf.mf.ext.free = dns_req->context->mf.mf.ext.free;
chain->dns_req = dns_req;
chain->lock = 0;
chain->sync_response = sync_response;
chain->timeout = timeout;
return chain;
}
@ -287,19 +271,14 @@ static void destroy_chain(struct validation_chain *chain)
/* Do some additional requests to fetch the complete validation chain */
static void
getdns_get_validation_chain(getdns_dns_req *dns_req,
struct getdns_dict **sync_response, uint64_t *timeout)
getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
{
getdns_network_req *netreq = dns_req->first_req;
struct validation_chain *chain = create_chain(
dns_req, sync_response, timeout);
struct validation_chain *chain = create_chain(dns_req, timeout);
if (! chain) {
if (sync_response)
*sync_response = create_getdns_response(dns_req);
else
priv_getdns_call_user_callback(
dns_req, create_getdns_response(dns_req));
priv_getdns_call_user_callback(
dns_req, create_getdns_response(dns_req));
return;
}
while (netreq) {
@ -326,15 +305,7 @@ 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, NULL);
}
struct getdns_dict *
priv_getdns_get_validation_chain_sync(getdns_dns_req *dns_req, uint64_t *timeout)
{
struct getdns_dict *sync_response = NULL;
getdns_get_validation_chain(dns_req, &sync_response, timeout);
return sync_response;
getdns_get_validation_chain(dns_req, NULL);
}
/********************** functions for validate_dnssec *************************/

View File

@ -44,9 +44,6 @@
/* Do some additional requests to fetch the complete validation chain */
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req);
struct getdns_dict * priv_getdns_get_validation_chain_sync(
getdns_dns_req *dns_req, uint64_t *timeout);
int priv_getdns_parse_ta_file(time_t *ta_mtime, ldns_rr_list *ta_rrs);
#endif

View File

@ -45,19 +45,6 @@
#include "util-internal.h"
#include "dnssec.h"
#include "stub.h"
#include "gldns/str2wire.h"
#include "gldns/pkthdr.h"
/* stuff to make it compile pedantically */
#define UNUSED_PARAM(x) ((void)(x))
/* declarations */
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
static void ub_resolve_timeout(void *arg);
static void handle_network_request_error(getdns_network_req * netreq, int err);
static void handle_dns_request_complete(getdns_dns_req * dns_req);
/* cancel, cleanup and send timeout to callback */
static void
@ -91,11 +78,18 @@ handle_network_request_error(getdns_network_req * netreq, int err)
priv_getdns_call_user_callback(netreq->owner, NULL);
}
/* cleanup and send the response to the user callback */
static void
handle_dns_request_complete(getdns_dns_req * dns_req)
void
priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req)
{
if (is_extension_set(dns_req->extensions, "dnssec_return_validation_chain"))
getdns_network_req *netreq;
for (netreq = dns_req->first_req; netreq; netreq = netreq->next)
if (netreq->state != NET_REQ_FINISHED &&
netreq->state != NET_REQ_CANCELED)
return;
if (is_extension_set(dns_req->extensions,
"dnssec_return_validation_chain"))
priv_getdns_get_validation_chain(dns_req);
else
priv_getdns_call_user_callback(
@ -103,109 +97,28 @@ handle_dns_request_complete(getdns_dns_req * dns_req)
}
static void
stub_resolve_timeout_cb(void *userarg)
ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_network_req *netreq = (getdns_network_req *) arg;
getdns_dns_req *dns_req = netreq->owner;
(void) getdns_context_request_timed_out(dns_req);
}
static void
stub_resolve_read_cb(void *userarg)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_dns_req *dns_req = netreq->owner;
static size_t pkt_buf_len = 4096;
size_t pkt_len = pkt_buf_len;
uint8_t pkt_buf[pkt_buf_len];
uint8_t *pkt = pkt_buf;
size_t read;
dns_req->loop->vmt->clear(dns_req->loop, &netreq->event);
read = recvfrom(netreq->udp_fd, pkt, pkt_len, 0, NULL, NULL);
if (read < GLDNS_HEADER_SIZE)
return; /* Not DNS */
if (GLDNS_ID_WIRE(pkt) != netreq->query_id)
return; /* Cache poisoning attempt ;) */
close(netreq->udp_fd);
netreq->state = NET_REQ_FINISHED;
ldns_wire2pkt(&(netreq->result), pkt, read);
/* Do the dnssec here */
netreq->secure = 0;
netreq->bogus = 0;
netreq = dns_req->first_req;
while (netreq) {
if (netreq->state != NET_REQ_FINISHED &&
netreq->state != NET_REQ_CANCELED)
return;
netreq = netreq->next;
if (err != 0) {
handle_network_request_error(netreq, err);
return;
}
handle_dns_request_complete(dns_req);
}
static getdns_return_t
submit_stub_request(getdns_network_req *netreq)
{
getdns_dns_req *dns_req = netreq->owner;
static size_t pkt_buf_len = 4096;
size_t pkt_len = pkt_buf_len;
uint8_t pkt_buf[pkt_buf_len];
uint8_t *pkt = pkt_buf;
int s;
struct getdns_upstream *upstream;
ssize_t sent;
s = getdns_make_query_pkt_buf(dns_req->context, dns_req->name,
netreq->request_type, dns_req->extensions, pkt_buf, &pkt_len);
if (s == GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL) {
/* TODO: Allocate 64K and retry */
return GETDNS_RETURN_GENERIC_ERROR;
} else if (s)
return GETDNS_RETURN_GENERIC_ERROR;
netreq->query_id = ldns_get_random();
GLDNS_ID_SET(pkt, netreq->query_id);
upstream = &dns_req->upstreams->upstreams[dns_req->ns_index];
/* TODO: TCP */
if (dns_req->context->dns_transport != GETDNS_TRANSPORT_UDP_ONLY &&
dns_req->context->dns_transport !=
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP)
return GETDNS_RETURN_GENERIC_ERROR;
if ((netreq->udp_fd = socket(
upstream->addr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1)
return GETDNS_RETURN_GENERIC_ERROR;
sent = sendto(netreq->udp_fd, pkt, pkt_len, 0,
(struct sockaddr *)&upstream->addr, upstream->addr_len);
if (sent != pkt_len) {
close(netreq->udp_fd);
return GETDNS_RETURN_GENERIC_ERROR;
/* parse */
if (getdns_apply_network_result(netreq, ub_res)) {
ub_resolve_free(ub_res);
handle_network_request_error(netreq, err);
return;
}
ub_resolve_free(ub_res);
netreq->event.userarg = netreq;
netreq->event.read_cb = stub_resolve_read_cb;
netreq->event.write_cb = NULL;
netreq->event.timeout_cb = stub_resolve_timeout_cb;
netreq->event.ev = NULL;
dns_req->loop->vmt->schedule(dns_req->loop,
netreq->udp_fd, dns_req->context->timeout, &netreq->event);
priv_getdns_check_dns_req_complete(dns_req);
} /* ub_resolve_callback */
if (s == GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL) {
/* TODO: Free the 64K allocated buffer */
}
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
submit_network_request(getdns_network_req *netreq)
@ -235,41 +148,10 @@ submit_network_request(getdns_network_req *netreq)
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
}
/* Submit with stub resolver */
return submit_stub_request(netreq);
return priv_getdns_submit_stub_request(netreq);
}
static void
ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
// ub_resolve_callback(void *arg, int err, ldns_buffer * result, int sec,
// char *bogus)
{
getdns_network_req *netreq = (getdns_network_req *) arg;
getdns_dns_req *dns_req = netreq->owner;
netreq->state = NET_REQ_FINISHED;
if (err != 0) {
handle_network_request_error(netreq, err);
return;
}
/* parse */
if (getdns_apply_network_result(netreq, ub_res)) {
ub_resolve_free(ub_res);
handle_network_request_error(netreq, err);
return;
}
ub_resolve_free(ub_res);
netreq = dns_req->first_req;
while (netreq) {
if (netreq->state != NET_REQ_FINISHED &&
netreq->state != NET_REQ_CANCELED)
return;
netreq = netreq->next;
}
handle_dns_request_complete(dns_req);
} /* ub_resolve_callback */
getdns_return_t
static getdns_return_t
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
const char *name, uint16_t request_type, getdns_dict *extensions,
void *userarg, getdns_transaction_t *transaction_id,
@ -349,7 +231,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
} /* getdns_general_ns */
getdns_return_t
getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
const char *name, uint16_t request_type, getdns_dict *extensions,
void *userarg, getdns_transaction_t *transaction_id,
getdns_callback_t callback)
@ -361,7 +243,7 @@ getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
} /* getdns_general_loop */
getdns_return_t
getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
priv_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)
{
@ -387,6 +269,53 @@ getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
return r;
} /* getdns_address_loop */
getdns_return_t
priv_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
getdns_dict *address, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
struct getdns_bindata *address_data;
struct getdns_bindata *address_type;
uint16_t req_type;
char *name;
getdns_return_t retval;
if ((retval =
getdns_dict_get_bindata(address, "address_data",
&address_data)) != GETDNS_RETURN_GOOD)
return retval;
if ((retval =
getdns_dict_get_bindata(address, "address_type",
&address_type)) != GETDNS_RETURN_GOOD)
return retval;
if ((strncmp(GETDNS_STR_IPV4, (char *) address_type->data,
( strlen(GETDNS_STR_IPV4) < address_type->size
? strlen(GETDNS_STR_IPV4) : address_type->size )) == 0
&& address_data->size == 4)
|| (strncmp(GETDNS_STR_IPV6, (char *) address_type->data,
( strlen(GETDNS_STR_IPV6) < address_type->size
? strlen(GETDNS_STR_IPV6) : address_type->size )) == 0
&& address_data->size == 16))
req_type = GETDNS_RRTYPE_PTR;
else
return GETDNS_RETURN_INVALID_PARAMETER;
if ((name = reverse_address(address_data)) == NULL)
return GETDNS_RETURN_INVALID_PARAMETER;
retval = priv_getdns_general_loop(context, loop, name, req_type,
extensions, userarg, transaction_id, callback);
free(name);
return retval;
} /* getdns_hostname_loop */
getdns_return_t
priv_getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t * transaction_id, getdns_callback_t callback)
{
return getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
extensions, userarg, transaction_id, callback, 1);
} /* getdns_service_loop */
/**
* getdns_general
*/
@ -397,7 +326,7 @@ getdns_general(getdns_context *context,
getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_general_loop(context, context->extension,
return priv_getdns_general_loop(context, context->extension,
name, request_type, extensions,
userarg, transaction_id, callback);
@ -413,10 +342,37 @@ getdns_address(getdns_context *context,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_address_loop(context, context->extension,
return priv_getdns_address_loop(context, context->extension,
name, extensions, userarg,
transaction_id, callback);
} /* getdns_address */
/*
* getdns_hostname
*
*/
getdns_return_t
getdns_hostname(getdns_context *context,
getdns_dict *address, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return priv_getdns_hostname_loop(context, context->extension,
address, extensions, userarg, transaction_id, callback);
} /* getdns_hostname */
/*
* getdns_service
*
*/
getdns_return_t
getdns_service(getdns_context *context,
const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return priv_getdns_service_loop(context, context->extension,
name, extensions, userarg, transaction_id, callback);
} /* getdns_service */
/* getdns_general.c */

View File

@ -1,6 +1,7 @@
/**
*
* /brief getdns contect management functions
* \file general.h
* @brief getdns_general and related support functions
*
* This is the meat of the API
* Originally taken from the getdns API description pseudo implementation.
@ -41,34 +42,29 @@
/* private inner helper used by sync and async */
getdns_return_t
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
const char *name, uint16_t request_type, getdns_dict *extensions,
void *userarg, getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn, int usenamespaces);
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
void priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req);
getdns_return_t
getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
const char *name, uint16_t request_type, getdns_dict *extensions,
void *userarg, getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn);
getdns_return_t
getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
priv_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);
getdns_return_t
getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
priv_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
getdns_dict *address, getdns_dict *extensions,
void *userarg, getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn);
getdns_return_t
getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
priv_getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
const char *name, getdns_dict *extensions,
void *userarg, getdns_transaction_t *transaction_id,
getdns_callback_t callbackfn);

View File

@ -1,105 +0,0 @@
/**
*
* \file hostname.c
* @brief getdns core functions
*
* Originally taken from the getdns API description pseudo implementation.
*
*/
/*
* Copyright (c) 2013, 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 <string.h>
#include "getdns/getdns.h"
#include "context.h"
#include "general.h"
#include "util-internal.h"
#include "types-internal.h"
/* stuff to make it compile pedantically */
#define UNUSED_PARAM(x) ((void)(x))
/*
* getdns_hostname
*
*/
getdns_return_t
getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
getdns_dict *address, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
struct getdns_bindata *address_data;
struct getdns_bindata *address_type;
uint16_t req_type;
char *name;
getdns_return_t retval;
if ((retval =
getdns_dict_get_bindata(address, "address_data",
&address_data)) != GETDNS_RETURN_GOOD)
return retval;
if ((retval =
getdns_dict_get_bindata(address, "address_type",
&address_type)) != GETDNS_RETURN_GOOD)
return retval;
if ((strncmp(GETDNS_STR_IPV4, (char *) address_type->data,
( strlen(GETDNS_STR_IPV4) < address_type->size
? strlen(GETDNS_STR_IPV4) : address_type->size )) == 0
&& address_data->size == 4)
|| (strncmp(GETDNS_STR_IPV6, (char *) address_type->data,
( strlen(GETDNS_STR_IPV6) < address_type->size
? strlen(GETDNS_STR_IPV6) : address_type->size )) == 0
&& address_data->size == 16))
req_type = GETDNS_RRTYPE_PTR;
else
return GETDNS_RETURN_INVALID_PARAMETER;
if ((name = reverse_address(address_data)) == NULL)
return GETDNS_RETURN_INVALID_PARAMETER;
retval = getdns_general_loop(context, loop, name, req_type, extensions,
userarg, transaction_id, callback);
free(name);
return retval;
} /* getdns_hostname_loop */
/*
* getdns_hostname
*
*/
getdns_return_t
getdns_hostname(getdns_context *context,
getdns_dict *address, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_hostname_loop(context, context->extension,
address, extensions, userarg, transaction_id, callback);
} /* getdns_hostname */
/* hostname.c */

View File

@ -1,68 +0,0 @@
/**
*
* \file service.c
* @brief getdns core functions
*
* Originally taken from the getdns API description pseudo implementation.
*
*/
/*
* Copyright (c) 2013, 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 "getdns/getdns.h"
#include "general.h"
#include "util-internal.h"
/*
* getdns_service
*
*/
getdns_return_t
getdns_service_loop(struct getdns_context *context, getdns_eventloop *loop,
const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t * transaction_id, getdns_callback_t callback)
{
return getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
extensions, userarg, transaction_id, callback, 1);
} /* getdns_service_loop */
/*
* getdns_service
*
*/
getdns_return_t
getdns_service(getdns_context *context,
const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback)
{
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_service_loop(context, context->extension,
name, extensions, userarg, transaction_id, callback);
} /* getdns_service */
/* service.c */

View File

@ -35,12 +35,15 @@
#include "stub.h"
#include "gldns/rrdef.h"
#include "gldns/str2wire.h"
#include "gldns/gbuffer.h"
#include "gldns/pkthdr.h"
#include "context.h"
#include <ldns/util.h>
#include "util-internal.h"
#include "general.h"
int
static int
getdns_make_query_pkt_buf(getdns_context *context, const char *name,
uint16_t request_type, getdns_dict *extensions, uint8_t* buf, size_t* olen)
{
@ -196,9 +199,8 @@ getdns_make_query_pkt_buf(getdns_context *context, const char *name,
return 0;
}
/* Return a rough estimate for mallocs */
size_t
static size_t
getdns_get_query_pkt_size(getdns_context *context,
const char *name, uint16_t request_type, getdns_dict *extensions)
{
@ -241,24 +243,114 @@ getdns_get_query_pkt_size(getdns_context *context,
;
}
uint8_t *
getdns_make_query_pkt(getdns_context *context, const char *name,
uint16_t request_type, getdns_dict *extensions, size_t *pkt_len)
static void
stub_resolve_timeout_cb(void *userarg)
{
size_t query_pkt_sz = getdns_get_query_pkt_size(
context, name, request_type, extensions);
uint8_t *query_pkt = GETDNS_XMALLOC(context->mf, uint8_t, query_pkt_sz);
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_dns_req *dns_req = netreq->owner;
if (query_pkt) {
if (getdns_make_query_pkt_buf(context, name, request_type,
extensions, query_pkt, &query_pkt_sz)) {
GETDNS_FREE(context->mf, query_pkt);
return NULL;
}
}
*pkt_len = query_pkt_sz;
return query_pkt;
(void) getdns_context_request_timed_out(dns_req);
}
static void
stub_resolve_read_cb(void *userarg)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_dns_req *dns_req = netreq->owner;
static size_t pkt_buf_len = 4096;
size_t pkt_len = pkt_buf_len;
uint8_t pkt_buf[pkt_buf_len];
uint8_t *pkt = pkt_buf;
size_t read;
dns_req->loop->vmt->clear(dns_req->loop, &netreq->event);
read = recvfrom(netreq->udp_fd, pkt, pkt_len, 0, NULL, NULL);
if (read < GLDNS_HEADER_SIZE)
return; /* Not DNS */
if (GLDNS_ID_WIRE(pkt) != netreq->query_id)
return; /* Cache poisoning attempt ;) */
close(netreq->udp_fd);
netreq->state = NET_REQ_FINISHED;
ldns_wire2pkt(&(netreq->result), pkt, read);
/* Do the dnssec here */
netreq->secure = 0;
netreq->bogus = 0;
priv_getdns_check_dns_req_complete(dns_req);
}
getdns_return_t
priv_getdns_submit_stub_request(getdns_network_req *netreq)
{
getdns_dns_req *dns_req = netreq->owner;
static size_t pkt_buf_len = 4096;
uint8_t pkt_buf[pkt_buf_len];
uint8_t *pkt = pkt_buf;
size_t pkt_len;
size_t pkt_size_needed;
struct getdns_upstream *upstream;
pkt_size_needed = getdns_get_query_pkt_size(dns_req->context,
dns_req->name, netreq->request_type, dns_req->extensions);
if (pkt_size_needed > pkt_buf_len) {
pkt = GETDNS_XMALLOC(
dns_req->context->mf, uint8_t, pkt_size_needed);
pkt_len = pkt_size_needed;
} else
pkt_len = pkt_buf_len;
if (getdns_make_query_pkt_buf(dns_req->context, dns_req->name,
netreq->request_type, dns_req->extensions, pkt_buf, &pkt_len))
goto error;
netreq->query_id = ldns_get_random();
GLDNS_ID_SET(pkt, netreq->query_id);
upstream = &dns_req->upstreams->upstreams[dns_req->ns_index];
/* TODO: TCP */
if (dns_req->context->dns_transport != GETDNS_TRANSPORT_UDP_ONLY &&
dns_req->context->dns_transport !=
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP)
goto error;
if ((netreq->udp_fd = socket(
upstream->addr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1)
goto error;
if (pkt_len != sendto(netreq->udp_fd, pkt, pkt_len, 0,
(struct sockaddr *)&upstream->addr, upstream->addr_len)) {
close(netreq->udp_fd);
goto error;
}
netreq->event.userarg = netreq;
netreq->event.read_cb = stub_resolve_read_cb;
netreq->event.write_cb = NULL;
netreq->event.timeout_cb = stub_resolve_timeout_cb;
netreq->event.ev = NULL;
dns_req->loop->vmt->schedule(dns_req->loop,
netreq->udp_fd, dns_req->context->timeout, &netreq->event);
if (pkt_size_needed > pkt_buf_len)
GETDNS_FREE(dns_req->context->mf, pkt);
return GETDNS_RETURN_GOOD;
error:
if (pkt_size_needed > pkt_buf_len)
GETDNS_FREE(dns_req->context->mf, pkt);
return GETDNS_RETURN_GENERIC_ERROR;
}
/* stub.c */

View File

@ -35,17 +35,9 @@
#define STUB_H_
#include "getdns/getdns.h"
#include "gldns/gbuffer.h"
#include "types-internal.h"
getdns_return_t getdns_stub_dns_query_sync(getdns_context *context,
const char *name, uint16_t request_type,
getdns_dict *extensions, gldns_buffer *response);
int getdns_make_query_pkt_buf(getdns_context *context, const char *name,
uint16_t request_type, getdns_dict *extensions, uint8_t* buf, size_t* len);
size_t getdns_get_query_pkt_size(getdns_context *context,
const char *name, uint16_t request_type, getdns_dict *extensions);
uint8_t *getdns_make_query_pkt(getdns_context *context, const char *name,
uint16_t request_type, getdns_dict *extensions, size_t *pkt_len);
getdns_return_t priv_getdns_submit_stub_request(getdns_network_req *netreq);
#endif

View File

@ -42,7 +42,6 @@
#include "types-internal.h"
#include "util-internal.h"
#include "dnssec.h"
#include "ub_timed_resolve.h"
#include "stub.h"
#include "gldns/wire2str.h"
@ -123,7 +122,7 @@ getdns_general_sync(getdns_context *context, const char *name,
if ((r = getdns_sync_loop_init(context, &loop)))
return r;
if ((r = getdns_general_loop(context, &loop.loop.loop, name,
if ((r = priv_getdns_general_loop(context, &loop.loop.loop, name,
request_type, extensions, &loop, NULL, getdns_sync_cb))) {
getdns_sync_loop_cleanup(&loop);
@ -148,7 +147,7 @@ getdns_address_sync(getdns_context *context, const char *name,
if ((r = getdns_sync_loop_init(context, &loop)))
return r;
if ((r = getdns_address_loop(context, &loop.loop.loop, name,
if ((r = priv_getdns_address_loop(context, &loop.loop.loop, name,
extensions, &loop, NULL, getdns_sync_cb))) {
getdns_sync_loop_cleanup(&loop);
@ -173,7 +172,7 @@ getdns_hostname_sync(getdns_context *context, getdns_dict *address,
if ((r = getdns_sync_loop_init(context, &loop)))
return r;
if ((r = getdns_hostname_loop(context, &loop.loop.loop, address,
if ((r = priv_getdns_hostname_loop(context, &loop.loop.loop, address,
extensions, &loop, NULL, getdns_sync_cb))) {
getdns_sync_loop_cleanup(&loop);
@ -198,7 +197,7 @@ getdns_service_sync(getdns_context *context, const char *name,
if ((r = getdns_sync_loop_init(context, &loop)))
return r;
if ((r = getdns_service_loop(context, &loop.loop.loop, name,
if ((r = priv_getdns_service_loop(context, &loop.loop.loop, name,
extensions, &loop, NULL, getdns_sync_cb))) {
getdns_sync_loop_cleanup(&loop);

View File

@ -1,125 +0,0 @@
/**
*
* /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 */

View File

@ -1,44 +0,0 @@
/**
*
* /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 */