mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'features/gldns' into features/stub-functions
Conflicts: src/sync.c
This commit is contained in:
commit
ceb211dfec
|
@ -39,3 +39,4 @@ check_getdns_ev
|
|||
doc/*.3
|
||||
src/getdns/getdns.h
|
||||
*.log
|
||||
src/Doxyfile
|
||||
|
|
|
@ -100,6 +100,9 @@ clean:
|
|||
cd doc && $(MAKE) $@
|
||||
rm -f *.o
|
||||
|
||||
depend:
|
||||
cd src && $(MAKE) $@
|
||||
|
||||
distclean:
|
||||
cd src && $(MAKE) $@
|
||||
rmdir src 2>/dev/null || true
|
||||
|
|
|
@ -11700,6 +11700,21 @@ $as_echo "#define HAVE_ATTR_FORMAT 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
|
||||
if test "x$ac_cv_func_strlcpy" = xyes; then :
|
||||
$as_echo "#define HAVE_STRLCPY 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" strlcpy.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS strlcpy.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -404,6 +404,8 @@ if test $ac_cv_c_format_attribute = yes; then
|
|||
AC_DEFINE(HAVE_ATTR_FORMAT, 1, [Whether the C compiler accepts the "format" attribute])
|
||||
fi
|
||||
|
||||
AC_REPLACE_FUNCS(strlcpy)
|
||||
|
||||
AH_BOTTOM([
|
||||
/** Use on-board gldns */
|
||||
|
||||
|
|
|
@ -78,11 +78,15 @@ 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
|
||||
ub_timed_resolve.lo
|
||||
|
||||
GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
|
||||
str2wire.lo
|
||||
|
||||
LIBOBJDIR=
|
||||
LIBOBJS=@LIBOBJS@
|
||||
COMPAT_OBJ=$(LIBOBJS:.o=.lo)
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
.c.o:
|
||||
|
@ -91,7 +95,7 @@ GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
|
|||
.c.lo:
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(GLDNS_OBJ):
|
||||
$(GLDNS_OBJ) $(COMPAT_OBJ):
|
||||
@:
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
|
@ -130,8 +134,8 @@ libgetdns_ext_ev.la: libgetdns.la extension/libev.lo
|
|||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ extension/libev.lo ./.libs/libgetdns.la $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/extension/libev.symbols
|
||||
|
||||
|
||||
libgetdns.la: $(GETDNS_OBJ) $(GLDNS_OBJ)
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $(GETDNS_OBJ) $(GLDNS_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
|
||||
libgetdns.la: $(GETDNS_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ)
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $(GETDNS_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
|
||||
|
||||
|
||||
test: FORCE
|
||||
|
@ -185,21 +189,28 @@ Makefile: Makefile.in ../config.status
|
|||
configure.status: configure
|
||||
cd .. && ./config.status --recheck
|
||||
|
||||
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 | \
|
||||
sed -e 's?gldns/?$$(srcdir)/gldns/?g' \
|
||||
-e 's?compat/?$$(srcdir)/compat/?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 )
|
||||
|
||||
.PHONY: clean test example
|
||||
FORCE:
|
||||
|
||||
# Dependencies for gldns
|
||||
# ----------------------
|
||||
# Create with: gcc -MM -I. gldns/*.c|sed -e 's?gldns/?$(srcdir)/gldns/?g' -e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' >> Makefile.in
|
||||
|
||||
# Dependencies for gldns and compatibility functions
|
||||
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 \
|
||||
$(srcdir)/gldns/gbuffer.h
|
||||
parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c config.h $(srcdir)/gldns/parseutil.h
|
||||
rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h
|
||||
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h
|
||||
str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h
|
||||
wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/keyraw.h
|
||||
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* from openssh 4.3p2 compat/strlcpy.c */
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
|
||||
|
||||
#include <config.h>
|
||||
#ifndef HAVE_STRLCPY
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif /* !HAVE_STRLCPY */
|
|
@ -66,6 +66,9 @@
|
|||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
|
|
|
@ -78,6 +78,13 @@ static void set_ub_dnssec_allowed_skew(struct getdns_context*, uint32_t);
|
|||
static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*,
|
||||
uint16_t);
|
||||
|
||||
/* ldns helpers */
|
||||
static getdns_return_t set_ldns_dns_transport(struct getdns_context* context,
|
||||
getdns_transport_t value);
|
||||
static void set_ldns_edns_maximum_udp_payload_size(struct getdns_context*,
|
||||
uint16_t);
|
||||
static getdns_return_t set_ldns_nameservers(struct getdns_context*,
|
||||
struct getdns_list * upstreams);
|
||||
|
||||
/* Stuff to make it compile pedantically */
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
@ -487,6 +494,8 @@ getdns_context_create_with_extended_memory_functions(
|
|||
getdns_context_destroy(result);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
/* ldns context is initialised to NULL here and rebuilt later if needed */
|
||||
result->ldns_res = NULL;
|
||||
|
||||
*context = result;
|
||||
|
||||
|
@ -570,9 +579,11 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
getdns_list_destroy(context->dnssec_trust_anchors);
|
||||
getdns_list_destroy(context->upstream_list);
|
||||
|
||||
/* destroy the ub context */
|
||||
/* destroy the contexts */
|
||||
if (context->unbound_ctx)
|
||||
ub_ctx_delete(context->unbound_ctx);
|
||||
if (context->ldns_res)
|
||||
ldns_resolver_deep_free(context->ldns_res);
|
||||
|
||||
if (context->outbound_requests)
|
||||
GETDNS_FREE(context->my_mf, context->outbound_requests);
|
||||
|
@ -645,6 +656,41 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
rebuild_ldns_res(struct getdns_context* context) {
|
||||
getdns_return_t result;
|
||||
if (context->ldns_res != NULL) {
|
||||
/* cancel all requests and delete */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
ldns_resolver_deep_free(context->ldns_res);
|
||||
context->ldns_res=NULL;
|
||||
}
|
||||
/*Create LDNS resolver object. */
|
||||
context->ldns_res = ldns_resolver_new();
|
||||
if (context->ldns_res == NULL) {
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
/* TODO: ldns doesn't support this option so this will have to be taken
|
||||
account expliticly during the ldns validation
|
||||
* set_ldns_dnssec_allowed_skew();*/
|
||||
|
||||
/* This is all the settings required for stub operation in sync mode.
|
||||
* Will need additional work here when supporting async mode.*/
|
||||
set_ldns_edns_maximum_udp_payload_size(context,
|
||||
context->edns_maximum_udp_payload_size);
|
||||
result = set_ldns_dns_transport(context, context->dns_transport);
|
||||
if (result != GETDNS_RETURN_GOOD)
|
||||
return result;
|
||||
|
||||
/* We need to set up the upstream recursive servers from the context */
|
||||
result = set_ldns_nameservers(context, context->upstream_list);
|
||||
if (result != GETDNS_RETURN_GOOD)
|
||||
return result;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to dispatch the updated callback
|
||||
*/
|
||||
|
@ -742,6 +788,29 @@ set_ub_dns_transport(struct getdns_context* context,
|
|||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
set_ldns_dns_transport(struct getdns_context* context,
|
||||
getdns_transport_t value) {
|
||||
switch (value) {
|
||||
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||
/* ldns has fallback configured by default */
|
||||
ldns_resolver_set_usevc(context->ldns_res, 0);
|
||||
break;
|
||||
case GETDNS_TRANSPORT_UDP_ONLY:
|
||||
ldns_resolver_set_usevc(context->ldns_res, 0);
|
||||
ldns_resolver_set_fallback(context->ldns_res, false);
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||
ldns_resolver_set_usevc(context->ldns_res, 1);
|
||||
break;
|
||||
default:
|
||||
/* TODO GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN */
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_context_set_dns_transport
|
||||
*
|
||||
|
@ -1029,6 +1098,14 @@ set_ub_edns_maximum_udp_payload_size(struct getdns_context* context,
|
|||
/* max-udp-size */
|
||||
set_ub_number_opt(context, "max-udp-size:", value);
|
||||
}
|
||||
|
||||
static void
|
||||
set_ldns_edns_maximum_udp_payload_size(struct getdns_context* context,
|
||||
uint16_t value) {
|
||||
/* max-udp-size */
|
||||
ldns_resolver_set_edns_udp_size(context->ldns_res, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_context_set_edns_maximum_udp_payload_size
|
||||
*
|
||||
|
@ -1313,15 +1390,108 @@ ub_setup_stub(struct ub_ctx *ctx, struct getdns_list * upstreams)
|
|||
return r;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
set_ldns_nameservers(struct getdns_context *context,
|
||||
struct getdns_list * upstreams)
|
||||
{
|
||||
size_t i;
|
||||
size_t count;
|
||||
struct getdns_dict *dict;
|
||||
struct getdns_bindata *address_string;
|
||||
char *address_type = NULL;
|
||||
ldns_rdf* ns_rdf = NULL;
|
||||
getdns_return_t r;
|
||||
|
||||
r = getdns_list_get_length(upstreams, &count);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
return r;
|
||||
|
||||
if (count == 0 || context->ldns_res == NULL)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
|
||||
/* remove current list of nameservers from resolver */
|
||||
ldns_rdf *pop;
|
||||
while((pop = ldns_resolver_pop_nameserver(context->ldns_res))) {
|
||||
ldns_rdf_deep_free(pop);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
r = getdns_list_get_dict(upstreams, i, &dict);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
r = getdns_dict_get_bindata(dict, GETDNS_STR_ADDRESS_STRING,
|
||||
&address_string);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
r = getdns_dict_util_get_string(dict, GETDNS_STR_ADDRESS_TYPE,
|
||||
&address_type);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
/* TODO: PROBLEM! The upstream list is implemented such that there is both
|
||||
* an IP address and a port in the bindata for each nameserver. Unbound
|
||||
* can handle this but ldns cannot. ldns has a list of nameservers which
|
||||
* must be A or AAAA records and it has one port setting on the resolver.
|
||||
* TEMP SOLUTION: strip off any port and use the port of the last
|
||||
* nameserver in the list. Wrong, but this will support the test scripts
|
||||
* in the short term which rely on being able to set a port for a single
|
||||
* nameserver. */
|
||||
char *address_char = (char *)address_string->data;
|
||||
char *port_char = NULL;
|
||||
char *at_symbol_position = strchr(address_char, '@');
|
||||
if (at_symbol_position != NULL) {
|
||||
int ip_length = at_symbol_position - address_char;
|
||||
int port_length = strlen(address_char) - ip_length;
|
||||
address_char = (char*) malloc(ip_length + 1);
|
||||
memcpy(address_char, (char *)address_string->data, ip_length);
|
||||
address_char[ip_length] = '\0';
|
||||
port_char = (char*) malloc(port_length);
|
||||
memcpy(port_char, (char *)(address_string->data + ip_length + 1), port_length);
|
||||
port_char[port_length] = '\0';
|
||||
}
|
||||
|
||||
if (strncmp(GETDNS_STR_IPV4, address_type,
|
||||
strlen(GETDNS_STR_IPV4)) == 0) {
|
||||
ns_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
|
||||
address_char);
|
||||
} else if (strncmp(GETDNS_STR_IPV6, address_type,
|
||||
strlen(GETDNS_STR_IPV6)) == 0) {
|
||||
ns_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
|
||||
address_char);
|
||||
}
|
||||
if (ns_rdf == NULL)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
ldns_resolver_push_nameserver(context->ldns_res, ns_rdf);
|
||||
ldns_rdf_deep_free(ns_rdf);
|
||||
|
||||
if (at_symbol_position != NULL) {
|
||||
ldns_resolver_set_port(context->ldns_res, atoi(port_char));
|
||||
free(port_char);
|
||||
free(address_char);
|
||||
}
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_ns_dns_setup(struct getdns_context *context)
|
||||
{
|
||||
assert(context);
|
||||
getdns_return_t r;
|
||||
|
||||
switch (context->resolution_type) {
|
||||
case GETDNS_RESOLUTION_STUB:
|
||||
return ub_setup_stub(context->unbound_ctx,
|
||||
context->upstream_list);
|
||||
case GETDNS_RESOLUTION_STUB:
|
||||
/* Since we don't know if the resolution will be sync or async at this
|
||||
* point and we only support ldns in sync mode then we must set _both_
|
||||
* contexts up */
|
||||
/* We get away with just setting up ldns here here because sync mode
|
||||
* always hits this method because at the moment all sync calls use DNS
|
||||
* namespace */
|
||||
r = ub_setup_stub(context->unbound_ctx, context->upstream_list);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
return r;
|
||||
return rebuild_ldns_res(context);
|
||||
|
||||
case GETDNS_RESOLUTION_RECURSING:
|
||||
/* TODO: use the root servers via root hints file */
|
||||
|
@ -1365,6 +1535,8 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
|
|||
for (i = 0; i < context->namespace_count; i++) {
|
||||
switch (context->namespaces[i]) {
|
||||
case GETDNS_NAMESPACE_LOCALNAMES:
|
||||
/* TODO: Note to self! This must change once we have
|
||||
* proper namespace hanlding or asynch stub mode using ldns.*/
|
||||
(void) ub_ctx_hosts(context->unbound_ctx, NULL);
|
||||
break;
|
||||
|
||||
|
|
|
@ -96,9 +96,9 @@ struct getdns_context {
|
|||
struct mem_funcs mf;
|
||||
struct mem_funcs my_mf;
|
||||
|
||||
/* The underlying unbound contexts that do
|
||||
* the real work */
|
||||
/* The underlying contexts that do the real work */
|
||||
struct ub_ctx *unbound_ctx;
|
||||
ldns_resolver *ldns_res;
|
||||
int has_ta; /* No DNSSEC without trust anchor */
|
||||
int return_dnssec_status;
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
static getdns_return_t submit_request_sync(
|
||||
static getdns_return_t submit_request_sync_rec(
|
||||
getdns_dns_req* req, uint64_t *timeout)
|
||||
{
|
||||
struct ub_result* ub_res = NULL;
|
||||
|
@ -82,22 +82,54 @@ static getdns_return_t submit_request_sync(
|
|||
static getdns_return_t submit_request_sync_stub(
|
||||
getdns_dns_req* req, uint64_t *timeout)
|
||||
{
|
||||
getdns_network_req *netreq;
|
||||
uint8_t *pkt;
|
||||
size_t pkt_len;
|
||||
char *str;
|
||||
|
||||
for (netreq = req->first_req; netreq; netreq = netreq->next) {
|
||||
ldns_rdf *qname;
|
||||
getdns_network_req *netreq = req->first_req;
|
||||
uint16_t qflags = 0;
|
||||
struct timeval tv;
|
||||
|
||||
while (netreq) {
|
||||
pkt = getdns_make_query_pkt(req->context, req->name,
|
||||
netreq->request_type, req->extensions, &pkt_len);
|
||||
str = gldns_wire2str_pkt(pkt, pkt_len);
|
||||
fprintf(stderr, "%s\n", str);
|
||||
free(str);
|
||||
GETDNS_FREE(req->context->mf, pkt);
|
||||
|
||||
qname = ldns_dname_new_frm_str(req->name);
|
||||
qflags = qflags | LDNS_RD;
|
||||
/* TODO: Use timeout properly - create a ldns_timed_resolve function */
|
||||
/* timeout is in miliseconds, so map to seconds and microseconds */
|
||||
tv.tv_sec = *timeout / 1000;
|
||||
tv.tv_usec = (*timeout % 1000) * 1000;
|
||||
ldns_resolver_set_timeout(req->context->ldns_res, tv);
|
||||
netreq->result = ldns_resolver_query(
|
||||
req->context->ldns_res, qname, netreq->request_type,
|
||||
netreq->request_class, qflags);
|
||||
ldns_rdf_deep_free(qname);
|
||||
qname = NULL;
|
||||
|
||||
if (! netreq->result) {
|
||||
/* TODO: use better errors */
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
netreq = netreq->next;
|
||||
}
|
||||
return submit_request_sync(req, timeout);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t submit_request_sync(
|
||||
getdns_dns_req* req, struct getdns_context *context)
|
||||
{
|
||||
if (context->resolution_type == GETDNS_RESOLUTION_STUB) {
|
||||
return submit_request_sync_stub(req, &(context->timeout));
|
||||
} else {
|
||||
return submit_request_sync_rec(req, &(context->timeout));
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_general_sync(struct getdns_context *context,
|
||||
|
@ -134,9 +166,7 @@ getdns_general_sync(struct getdns_context *context,
|
|||
if (!req)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
response_status = ( context->resolution_type == GETDNS_RESOLUTION_STUB
|
||||
? submit_request_sync_stub : submit_request_sync )(req, &timeout);
|
||||
|
||||
response_status = submit_request_sync(req, context);
|
||||
if (response_status == GETDNS_RETURN_GOOD) {
|
||||
if (is_extension_set(req->extensions,
|
||||
"dnssec_return_validation_chain"))
|
||||
|
|
|
@ -103,26 +103,32 @@ void* run_transport_server(void* data) {
|
|||
n = read(conn, mesg, 65536);
|
||||
tcp_count++;
|
||||
}
|
||||
|
||||
ldns_wire2pkt(&query, mesg, n);
|
||||
ldns_resolver_send_pkt(&pkt, resolver, query);
|
||||
ldns_str2rdf_a(&answerfrom, "127.0.0.1");
|
||||
ldns_pkt_set_answerfrom(pkt, answerfrom);
|
||||
ldns_pkt_free(query);
|
||||
uint8_t* pkt_data;
|
||||
size_t pkt_len;
|
||||
ldns_pkt* answer = pkt;
|
||||
ldns_pkt2wire(&pkt_data, answer, &pkt_len);
|
||||
|
||||
ldns_buffer *send_buf;
|
||||
send_buf = ldns_buffer_new(LDNS_MIN_BUFLEN);
|
||||
ldns_pkt2buffer_wire(send_buf, pkt);
|
||||
|
||||
if (udp_count > 0) {
|
||||
sendto(udp, pkt_data, pkt_len, 0, (struct sockaddr *) &client_addr, sizeof (client_addr));
|
||||
sendto(udp, (void*)ldns_buffer_begin(send_buf), ldns_buffer_position(send_buf),
|
||||
0, (struct sockaddr *) &client_addr, sizeof (client_addr));
|
||||
} else if (conn > 0) {
|
||||
int wcount = write(conn, pkt_data, pkt_len);
|
||||
if (wcount != pkt_len) {
|
||||
/* For now ignore this */
|
||||
continue;
|
||||
}
|
||||
uint8_t *send_array;
|
||||
/* add length of packet */
|
||||
send_array = LDNS_XMALLOC(uint8_t, ldns_buffer_position(send_buf) + 2);
|
||||
if(!send_array) return 0;
|
||||
ldns_write_uint16(send_array, ldns_buffer_position(send_buf));
|
||||
memcpy(send_array + 2, ldns_buffer_begin(send_buf), ldns_buffer_position(send_buf));
|
||||
write(conn, (void*)send_array, ldns_buffer_position(send_buf) + 2);
|
||||
LDNS_FREE(send_array);
|
||||
}
|
||||
free(pkt_data);
|
||||
ldns_pkt_free(answer);
|
||||
LDNS_FREE(send_buf);
|
||||
ldns_pkt_free(pkt);
|
||||
} /* End of if */
|
||||
} /* end of while loop */
|
||||
close(udp);
|
||||
|
@ -210,7 +216,7 @@ START_TEST(getdns_transport_udp_sync) {
|
|||
|
||||
t_data.running = 0;
|
||||
pthread_join(thread, NULL);
|
||||
ck_assert_msg(t_data.udp_count == 1, "udp_count != 1");
|
||||
ck_assert_msg(t_data.udp_count >= 1, "udp_count !>= 1");
|
||||
ck_assert_msg(t_data.tcp_count == 0, "tcp_count != 0");
|
||||
|
||||
}
|
||||
|
@ -285,7 +291,7 @@ START_TEST(getdns_transport_tcp_sync) {
|
|||
t_data.running = 0;
|
||||
pthread_join(thread, NULL);
|
||||
ck_assert_msg(t_data.udp_count == 0, "udp_count != 0");
|
||||
ck_assert_msg(t_data.tcp_count == 1, "tcp_count != 1");
|
||||
ck_assert_msg(t_data.tcp_count >= 1, "tcp_count !>= 1");
|
||||
|
||||
}
|
||||
|
||||
|
@ -362,7 +368,7 @@ START_TEST(getdns_transport_udp_async) {
|
|||
|
||||
t_data.running = 0;
|
||||
pthread_join(thread, NULL);
|
||||
ck_assert_msg(t_data.udp_count == 1, "udp_count != 1");
|
||||
ck_assert_msg(t_data.udp_count >= 1, "udp_count !>= 1");
|
||||
ck_assert_msg(t_data.tcp_count == 0, "tcp_count != 0");
|
||||
|
||||
}
|
||||
|
@ -441,7 +447,7 @@ START_TEST(getdns_transport_tcp_async) {
|
|||
t_data.running = 0;
|
||||
pthread_join(thread, NULL);
|
||||
ck_assert_msg(t_data.udp_count == 0, "udp_count != 0");
|
||||
ck_assert_msg(t_data.tcp_count == 1, "tcp_count != 1");
|
||||
ck_assert_msg(t_data.tcp_count >= 1, "tcp_count !>= 1");
|
||||
|
||||
}
|
||||
|
||||
|
@ -454,6 +460,11 @@ Suite *
|
|||
getdns_transport_suite(void) {
|
||||
Suite *s = suite_create("getdns_transport()");
|
||||
|
||||
/* Note that the exact number of messages received depends on if a trust
|
||||
* anchor is configured so these tests just check that no messages are
|
||||
* received on the wrong transport and at least one is recieved on the
|
||||
* expected transport */
|
||||
|
||||
/* Positive test cases */
|
||||
TCase *tc_pos = tcase_create("Positive");
|
||||
tcase_set_timeout(tc_pos, 15.0);
|
||||
|
|
|
@ -81,7 +81,19 @@ main()
|
|||
}
|
||||
print_response(response);
|
||||
getdns_dict_destroy(response);
|
||||
|
||||
|
||||
/* Now switch to TCP and make sure everything works */
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
|
||||
|
||||
ret = getdns_general_sync(this_context, "www.google.com", GETDNS_RRTYPE_A,
|
||||
NULL, &response);
|
||||
if (ret != GETDNS_RETURN_GOOD || response == NULL) {
|
||||
fprintf(stderr, "General sync over TCP returned error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_response(response);
|
||||
getdns_dict_destroy(response);
|
||||
|
||||
/* Clean up */
|
||||
getdns_context_destroy(this_context);
|
||||
/* Assuming we get here, leave gracefully */
|
||||
|
|
Loading…
Reference in New Issue