mirror of https://github.com/getdnsapi/getdns.git
Second pass at implementing per query namespaces!
This commit is contained in:
parent
050506341c
commit
d9addba883
102
src/context.c
102
src/context.c
|
@ -60,6 +60,7 @@ struct host_name_addr_type {
|
|||
/* Private functions */
|
||||
getdns_return_t create_default_namespaces(struct getdns_context *context);
|
||||
getdns_return_t create_local_hosts(struct getdns_context *context);
|
||||
getdns_return_t destroy_local_hosts(struct getdns_context *context);
|
||||
static struct getdns_list *create_default_root_servers(void);
|
||||
static getdns_return_t add_ip_str(struct getdns_dict *);
|
||||
static struct getdns_dict *create_ipaddr_dict_from_rdf(struct getdns_context *,
|
||||
|
@ -96,6 +97,16 @@ static getdns_return_t set_ldns_nameservers(struct getdns_context*,
|
|||
/* Stuff to make it compile pedantically */
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
static void destroy_local_host(ldns_rbnode_t * node, void *arg)
|
||||
{
|
||||
struct getdns_context *context = (struct getdns_context *) arg;
|
||||
|
||||
struct host_name_addr_type *lh = (struct host_name_addr_type *) node->key;
|
||||
ldns_rdf_free(lh->host_name);
|
||||
ldns_rr_list_deep_free((ldns_rr_list *)node->data);
|
||||
GETDNS_FREE(context->mf, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get default lookup namespaces.
|
||||
* TODO: Determine from OS
|
||||
|
@ -125,9 +136,6 @@ create_local_hosts(struct getdns_context *context)
|
|||
if (host_names == NULL)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
/*TODO: free up memory on error paths*/
|
||||
//ldns_rr_list_print(stderr, host_names);
|
||||
|
||||
/* We have a 1:1 list of name -> ip address where there is an
|
||||
underlying many to many relationship. Need to create a lookup of
|
||||
(unique name + A/AAAA)-> list of IPV4/IPv6 ip addresses*/
|
||||
|
@ -155,22 +163,21 @@ create_local_hosts(struct getdns_context *context)
|
|||
|
||||
ldns_rbnode_t *node = GETDNS_MALLOC(context->my_mf, ldns_rbnode_t);
|
||||
if (!node) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
node->key = lh_key;
|
||||
node->data = address_list;
|
||||
if (!ldns_rbtree_insert(context->local_hosts, node)) {
|
||||
/* free the node */
|
||||
GETDNS_FREE(context->my_mf, node);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ldns_rr_list_deep_free(host_names);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to get the default root servers.
|
||||
* TODO: Implement
|
||||
|
@ -684,7 +691,8 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
if (context->timeouts_by_time)
|
||||
GETDNS_FREE(context->my_mf, context->timeouts_by_time);
|
||||
if (context->local_hosts) {
|
||||
/*TODO: deep free of this tree*/
|
||||
ldns_traverse_postorder(context->local_hosts,
|
||||
destroy_local_host, context);
|
||||
GETDNS_FREE(context->my_mf, context->local_hosts);
|
||||
}
|
||||
|
||||
|
@ -2121,74 +2129,56 @@ getdns_context_set_use_threads(getdns_context* context, int use_threads) {
|
|||
|
||||
getdns_return_t
|
||||
getdns_context_local_namespace_resolve(getdns_dns_req* req,
|
||||
struct getdns_dict **response,
|
||||
struct getdns_context *context)
|
||||
{
|
||||
|
||||
/* NOTE: This only returns GETDNS_RETURN_GOOD if it finds answers for all the
|
||||
netreq that it tries */
|
||||
/*TODO: free memory on error paths*/
|
||||
ldns_rr_list *result_list = NULL;
|
||||
struct host_name_addr_type *lh_key =
|
||||
GETDNS_MALLOC(context->my_mf, struct host_name_addr_type);
|
||||
if (lh_key == NULL)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
getdns_network_req *netreq = req->first_req;
|
||||
while (netreq) {
|
||||
/*This request may have already been answered by another namespace*/
|
||||
if (netreq->result) {
|
||||
if (netreq->request_type != GETDNS_RRTYPE_A &&
|
||||
netreq->request_type != GETDNS_RRTYPE_AAAA) {
|
||||
netreq = netreq->next;
|
||||
continue;
|
||||
}
|
||||
if (netreq->request_type != GETDNS_RRTYPE_A && netreq->request_type != GETDNS_RRTYPE_AAAA)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
/*Do the lookup*/
|
||||
ldns_rdf *query_name = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, req->name);
|
||||
struct host_name_addr_type *lh_key =
|
||||
GETDNS_MALLOC(context->my_mf, struct host_name_addr_type);
|
||||
if (lh_key == NULL)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
if (!query_name) {
|
||||
GETDNS_FREE(context->my_mf, lh_key);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
lh_key->host_name = query_name;
|
||||
lh_key->addr_type = netreq->request_type;
|
||||
ldns_rbnode_t *result_node = ldns_rbtree_search(context->local_hosts, lh_key);
|
||||
if (!result_node) {
|
||||
ldns_rdf_deep_free(query_name);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
if (result_node) {
|
||||
if (result_list == NULL)
|
||||
result_list =
|
||||
ldns_rr_list_clone((ldns_rr_list *)result_node->data);
|
||||
else {
|
||||
if (!ldns_rr_list_cat(result_list, (ldns_rr_list *)result_node->data)) {
|
||||
GETDNS_FREE(context->my_mf, lh_key);
|
||||
ldns_rdf_deep_free(query_name);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Fabricate the result packet*/
|
||||
ldns_pkt *answer_pkt;
|
||||
ldns_rr *question_rr;
|
||||
ldns_rr_list *answer_qr;
|
||||
ldns_rr_list *answer_an;
|
||||
ldns_rr_list *answer_ns;
|
||||
ldns_rr_list *answer_ad;
|
||||
|
||||
question_rr = ldns_rr_new_frm_type(netreq->request_type);
|
||||
ldns_rr_set_class(question_rr, netreq->request_class);
|
||||
ldns_rr_set_owner(question_rr, query_name);
|
||||
ldns_rr_set_rd_count (question_rr, (size_t)0);
|
||||
answer_qr = ldns_rr_list_new();
|
||||
if (!ldns_rr_list_push_rr (answer_qr, question_rr)) {
|
||||
ldns_rdf_deep_free(query_name);
|
||||
ldns_rr_free(question_rr);
|
||||
ldns_rr_list_deep_free(answer_qr);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
answer_an = ldns_rr_list_clone((ldns_rr_list *)result_node->data);
|
||||
answer_ns = ldns_rr_list_new();
|
||||
answer_ad = ldns_rr_list_new();
|
||||
|
||||
answer_pkt = ldns_pkt_new();
|
||||
ldns_pkt_set_qr(answer_pkt, 1);
|
||||
ldns_pkt_set_aa(answer_pkt, 1);
|
||||
|
||||
ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_QUESTION, answer_qr);
|
||||
ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ANSWER, answer_an);
|
||||
ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_AUTHORITY, answer_ns);
|
||||
ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ADDITIONAL, answer_ad);
|
||||
|
||||
netreq->result = answer_pkt;
|
||||
ldns_rdf_deep_free(query_name);
|
||||
netreq = netreq->next;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
GETDNS_FREE(context->my_mf, lh_key);
|
||||
if (result_list == NULL)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
*response = create_getdns_response_from_rr_list(req, result_list);
|
||||
return response ? GETDNS_RETURN_GOOD : GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ getdns_return_t getdns_context_clear_timeout(struct getdns_context* context,
|
|||
|
||||
/* perform name resolution in /etc/hosts */
|
||||
getdns_return_t getdns_context_local_namespace_resolve(getdns_dns_req* req,
|
||||
struct getdns_dict **response,
|
||||
struct getdns_context *context);
|
||||
|
||||
int filechg_check(struct getdns_context *context, struct filechg *fchg);
|
||||
|
|
28
src/sync.c
28
src/sync.c
|
@ -56,11 +56,6 @@ static getdns_return_t submit_request_sync_rec(
|
|||
getdns_network_req *netreq = req->first_req;
|
||||
|
||||
while (netreq) {
|
||||
/*This request may have already been answered by another namespace*/
|
||||
if (netreq->result) {
|
||||
netreq = netreq->next;
|
||||
continue;
|
||||
}
|
||||
int r = ub_timed_resolve(req->context->unbound_ctx,
|
||||
req->name,
|
||||
netreq->request_type,
|
||||
|
@ -90,11 +85,6 @@ static getdns_return_t submit_request_sync_stub(
|
|||
struct timeval tv;
|
||||
|
||||
while (netreq) {
|
||||
/*This request may have already been answered by another namespace*/
|
||||
if (netreq->result) {
|
||||
netreq = netreq->next;
|
||||
continue;
|
||||
}
|
||||
qname = ldns_dname_new_frm_str(req->name);
|
||||
qflags = qflags | LDNS_RD;
|
||||
/* TODO: Use timeout properly - create a ldns_timed_resolve function */
|
||||
|
@ -168,9 +158,6 @@ getdns_general_sync_ns(struct getdns_context *context,
|
|||
if (!req)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
/*TODO: Would be tidier to loop over the netreq here trying each namespace
|
||||
rather then trying each namespace...*/
|
||||
|
||||
/* resolve using the appropriate namespace*/
|
||||
if (!usenamespaces) {
|
||||
response_status = submit_request_sync(req, context);
|
||||
|
@ -178,10 +165,20 @@ getdns_general_sync_ns(struct getdns_context *context,
|
|||
for (int i = 0; i < context->namespace_count; i++) {
|
||||
switch (context->namespaces[i]) {
|
||||
case GETDNS_NAMESPACE_LOCALNAMES:
|
||||
response_status = getdns_context_local_namespace_resolve(req, context);
|
||||
response_status = getdns_context_local_namespace_resolve(req,
|
||||
response,
|
||||
context);
|
||||
/* For a local lookup the response is populated directly*/
|
||||
if (response_status == GETDNS_RETURN_GOOD) {
|
||||
dns_req_free(req);
|
||||
return response_status;
|
||||
}
|
||||
break;
|
||||
|
||||
case GETDNS_NAMESPACE_DNS:
|
||||
/* TODO: We will get a good return code here even if the name is
|
||||
not found (NXDOMAIN). We should consider if this means we
|
||||
go onto the next namespace instead of returning*/
|
||||
response_status = submit_request_sync(req, context);
|
||||
break;
|
||||
|
||||
|
@ -189,13 +186,14 @@ getdns_general_sync_ns(struct getdns_context *context,
|
|||
response_status = GETDNS_RETURN_BAD_CONTEXT;
|
||||
break;
|
||||
}
|
||||
/* If we have all good responses break out the for loop as we are done,
|
||||
/* If we have a good response break out the for loop as we are done,
|
||||
but if we don't then give the next namespace a try*/
|
||||
if (response_status == GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only get here if the response came from the DNS namespace*/
|
||||
if (response_status == GETDNS_RETURN_GOOD) {
|
||||
if (is_extension_set(req->extensions,
|
||||
"dnssec_return_validation_chain"))
|
||||
|
|
|
@ -58,7 +58,7 @@ CC=@CC@
|
|||
CFLAGS=@CFLAGS@ -Wall -I.. -I$(srcdir)/.. -I$(srcdir) -std=c99 $(cflags)
|
||||
LDFLAGS=@LDFLAGS@ -L..
|
||||
LDLIBS=-lgetdns @LIBS@ -lcheck -lm -lrt
|
||||
PROGRAMS=tests_dict tests_list tests_stub_async tests_stub_sync check_getdns tests_dnssec $(CHECK_EV_PROG) $(CHECK_EVENT_PROG) $(CHECK_UV_PROG)
|
||||
PROGRAMS=tests_dict tests_list tests_namespaces tests_stub_async tests_stub_sync check_getdns tests_dnssec $(CHECK_EV_PROG) $(CHECK_EVENT_PROG) $(CHECK_UV_PROG)
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
|
@ -78,6 +78,9 @@ tests_dict: tests_dict.lo testmessages.lo
|
|||
tests_list: tests_list.lo testmessages.lo
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_list.lo testmessages.lo
|
||||
|
||||
tests_namespaces: tests_namespaces.lo
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_namespaces.lo
|
||||
|
||||
tests_stub_async: tests_stub_async.lo testmessages.lo
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_stub_async.lo testmessages.lo
|
||||
|
||||
|
|
|
@ -130,10 +130,11 @@
|
|||
ASSERT_RC(getdns_address_sync(context, "localhost", NULL, &response),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
|
||||
|
||||
EXTRACT_RESPONSE;
|
||||
EXTRACT_LOCAL_RESPONSE;
|
||||
|
||||
assert_noerror( &ex_response);
|
||||
assert_address_in_answer(&ex_response, TRUE, TRUE);
|
||||
/* TODO: create reduced forms of these tests for local responses*/
|
||||
//assert_noerror( &ex_response);
|
||||
//assert_address_in_answer(&ex_response, TRUE, TRUE);
|
||||
|
||||
|
||||
CONTEXT_DESTROY;
|
||||
|
|
|
@ -103,6 +103,25 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
|
|||
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
|
||||
}
|
||||
|
||||
/*
|
||||
* extract_response extracts all of the various information
|
||||
* a test may want to look at from the response.
|
||||
*/
|
||||
void extract_local_response(struct getdns_dict *response, struct extracted_response *ex_response)
|
||||
{
|
||||
ck_assert_msg(response != NULL, "Response should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"top canonical_name\"");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_list(response, "just_address_answers", &ex_response->just_address_answers),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\"");
|
||||
ck_assert_msg(ex_response->just_address_answers != NULL, "just_address_answers should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
|
||||
}
|
||||
|
||||
/*
|
||||
* assert_noerror asserts that the rcode is 0
|
||||
*/
|
||||
|
|
|
@ -143,12 +143,26 @@
|
|||
// FUNCTION DECLARATIONS
|
||||
//
|
||||
|
||||
#define EXTRACT_LOCAL_RESPONSE \
|
||||
struct extracted_response ex_response; \
|
||||
extract_local_response(response, &ex_response);
|
||||
|
||||
//
|
||||
// FUNCTION DECLARATIONS
|
||||
//
|
||||
|
||||
/*
|
||||
* extract_response extracts all of the various information
|
||||
* a test may want to look at from the response.
|
||||
*/
|
||||
void extract_response(struct getdns_dict *response, struct extracted_response *ex_response);
|
||||
|
||||
/*
|
||||
* extract__local_response extracts all of the various information
|
||||
* a test may want to look at from the response for a minimal, local.
|
||||
*/
|
||||
void extract_local_response(struct getdns_dict *response, struct extracted_response *ex_response);
|
||||
|
||||
/*
|
||||
* assert_noerror asserts that the rcode is 0.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* \file
|
||||
* unit tests for getdns_dict helper routines, these should be used to
|
||||
* perform regression tests, output must be unchanged from canonical output
|
||||
* stored with the sources
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "testmessages.h"
|
||||
#include "getdns/getdns.h"
|
||||
|
||||
static void
|
||||
print_response(struct getdns_dict * response)
|
||||
{
|
||||
char *dict_str = getdns_pretty_print_dict(response);
|
||||
if (dict_str) {
|
||||
fprintf(stdout, "The packet %s\n", dict_str);
|
||||
free(dict_str);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
|
||||
/* First up, use the default settings on a general and non-general call */
|
||||
|
||||
/* The namespaces used are per query depending on the type of method called.
|
||||
But note that namespaces can only be changed before the first query.*/
|
||||
|
||||
/* Create the DNS context for this call */
|
||||
struct getdns_context *this_context = NULL;
|
||||
getdns_return_t context_create_return =
|
||||
getdns_context_create(&this_context, 1);
|
||||
if (context_create_return != GETDNS_RETURN_GOOD) {
|
||||
fprintf(stderr, "Trying to create the context failed: %d",
|
||||
context_create_return);
|
||||
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||
}
|
||||
getdns_context_set_resolution_type(this_context, GETDNS_RESOLUTION_STUB);
|
||||
|
||||
/* This will return a response with only the just_address_answers part
|
||||
as the current implementaiton uses [LOCALNAMES, DNS]*/
|
||||
struct getdns_dict *response = NULL;
|
||||
getdns_return_t ret =
|
||||
getdns_address_sync(this_context, "localhost", NULL, &response);
|
||||
|
||||
if (ret != GETDNS_RETURN_GOOD || response == NULL) {
|
||||
fprintf(stderr, "Address sync returned error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_response(response);
|
||||
getdns_dict_destroy(response);
|
||||
|
||||
/* This should fall back to a full DNS lookup*/
|
||||
ret = getdns_address_sync(this_context, "www.google.com", NULL, &response);
|
||||
|
||||
if (ret != GETDNS_RETURN_GOOD || response == NULL) {
|
||||
fprintf(stderr, "Address sync returned error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_response(response);
|
||||
getdns_dict_destroy(response);
|
||||
|
||||
/* This should return a full DNS reply as the general lookups don't use
|
||||
the namespaces, they just do pure DNS*/
|
||||
ret = getdns_general_sync(this_context, "localhost", 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);
|
||||
|
||||
|
||||
/* Secondly, specify the namespace and see what happens*/
|
||||
|
||||
/* Create the DNS context for this call */
|
||||
struct getdns_context *next_context = NULL;
|
||||
context_create_return = getdns_context_create(&next_context, 1);
|
||||
if (context_create_return != GETDNS_RETURN_GOOD) {
|
||||
fprintf(stderr, "Trying to create the context failed: %d",
|
||||
context_create_return);
|
||||
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||
}
|
||||
getdns_context_set_resolution_type(next_context, GETDNS_RESOLUTION_STUB);
|
||||
|
||||
getdns_namespace_t namespace_arr[2] = {GETDNS_NAMESPACE_DNS, GETDNS_NAMESPACE_LOCALNAMES};
|
||||
getdns_context_set_namespaces(next_context, 2,namespace_arr);
|
||||
|
||||
/* This will return a full DNS reply*/
|
||||
ret = getdns_address_sync(next_context, "localhost", NULL, &response);
|
||||
|
||||
if (ret != GETDNS_RETURN_GOOD || response == NULL) {
|
||||
fprintf(stderr, "Address sync returned error.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_response(response);
|
||||
getdns_dict_destroy(response);
|
||||
|
||||
/* Clean up */
|
||||
getdns_context_destroy(next_context);
|
||||
|
||||
/* Assuming we get here, leave gracefully */
|
||||
exit(EXIT_SUCCESS);
|
||||
} /* main */
|
||||
|
||||
/* tests_stub_sync.c */
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
The packet {
|
||||
"canonical_name": <bindata of "localhost.">,
|
||||
"just_address_answers":
|
||||
[
|
||||
{
|
||||
"address_data": <bindata for 127.0.0.1>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for ::1>,
|
||||
"address_type": <bindata of "IPv6">
|
||||
}
|
||||
],
|
||||
"replies_full": [],
|
||||
"replies_tree": [],
|
||||
"status": GETDNS_RESPSTATUS_GOOD
|
||||
}
|
||||
The packet {
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"canonical_name": <bindata of "www.google.com.">,
|
||||
"just_address_answers":
|
||||
[
|
||||
{
|
||||
"address_data": <bindata for 74.125.24.104>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for 74.125.24.103>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for 74.125.24.105>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for 74.125.24.99>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for 74.125.24.147>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for 74.125.24.106>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for 2a00:1450:400b:c02::63>,
|
||||
"address_type": <bindata of "IPv6">
|
||||
}
|
||||
],
|
||||
"replies_full":
|
||||
[
|
||||
<bindata for \022\129\128\000\001\000\006\000\000\000\001\003www\006google\003com\000\000\001\000\001\003www\006google\003com\000\000\001\000\001\000\000\001,\000\004J}\024h\003www\006google\003com\000\000\001\000\001\000\000\001,\000\004J}\024g\003www\006google\003com\000\000\001\000\001\000\000\001,\000\004J}\024i\003www\006google\003com\000\000\001\000\001\000\000\001,\000\004J}\024c\003www\006google\003com\000\000\001\000\001\000\000\001,\000\004J}\024\147\003www\006google\003com\000\000\001\000\001\000\000\001,\000\004J}\024j\000\000\)\016\000\000.>,
|
||||
<bindata of 0xe4e98180000100010000000103777777...>
|
||||
],
|
||||
"replies_tree":
|
||||
[
|
||||
{
|
||||
"additional": [],
|
||||
"answer":
|
||||
[
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 74.125.24.104>,
|
||||
"rdata_raw": <bindata of 0x4a7d1868>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
},
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 74.125.24.103>,
|
||||
"rdata_raw": <bindata of 0x4a7d1867>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
},
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 74.125.24.105>,
|
||||
"rdata_raw": <bindata of 0x4a7d1869>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
},
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 74.125.24.99>,
|
||||
"rdata_raw": <bindata of 0x4a7d1863>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
},
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 74.125.24.147>,
|
||||
"rdata_raw": <bindata of 0x4a7d1893>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
},
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 74.125.24.106>,
|
||||
"rdata_raw": <bindata of 0x4a7d186a>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
}
|
||||
],
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"authority": [],
|
||||
"canonical_name": <bindata of "www.google.com.">,
|
||||
"header":
|
||||
{
|
||||
"aa": 0,
|
||||
"ad": 0,
|
||||
"ancount": 6,
|
||||
"arcount": 0,
|
||||
"cd": 0,
|
||||
"id": 55574,
|
||||
"nscount": 0,
|
||||
"opcode": GETDNS_OPCODE_QUERY,
|
||||
"qdcount": 1,
|
||||
"qr": 1,
|
||||
"ra": 1,
|
||||
"rcode": GETDNS_RCODE_NOERROR,
|
||||
"rd": 1,
|
||||
"tc": 0,
|
||||
"z": 0
|
||||
},
|
||||
"question":
|
||||
{
|
||||
"qclass": GETDNS_RRCLASS_IN,
|
||||
"qname": <bindata for www.google.com.>,
|
||||
"qtype": GETDNS_RRTYPE_A
|
||||
}
|
||||
},
|
||||
{
|
||||
"additional": [],
|
||||
"answer":
|
||||
[
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for www.google.com.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv6_address": <bindata for 2a00:1450:400b:c02::63>,
|
||||
"rdata_raw": <bindata of 0x2a001450400b0c020000000000000063>
|
||||
},
|
||||
"ttl": 300,
|
||||
"type": GETDNS_RRTYPE_AAAA
|
||||
}
|
||||
],
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"authority": [],
|
||||
"canonical_name": <bindata of "www.google.com.">,
|
||||
"header":
|
||||
{
|
||||
"aa": 0,
|
||||
"ad": 0,
|
||||
"ancount": 1,
|
||||
"arcount": 0,
|
||||
"cd": 0,
|
||||
"id": 58601,
|
||||
"nscount": 0,
|
||||
"opcode": GETDNS_OPCODE_QUERY,
|
||||
"qdcount": 1,
|
||||
"qr": 1,
|
||||
"ra": 1,
|
||||
"rcode": GETDNS_RCODE_NOERROR,
|
||||
"rd": 1,
|
||||
"tc": 0,
|
||||
"z": 0
|
||||
},
|
||||
"question":
|
||||
{
|
||||
"qclass": GETDNS_RRCLASS_IN,
|
||||
"qname": <bindata for www.google.com.>,
|
||||
"qtype": GETDNS_RRTYPE_AAAA
|
||||
}
|
||||
}
|
||||
],
|
||||
"status": GETDNS_RESPSTATUS_GOOD
|
||||
}
|
||||
The packet {
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"canonical_name": <bindata of "localhost.">,
|
||||
"just_address_answers":
|
||||
[
|
||||
{
|
||||
"address_data": <bindata for 127.0.0.1>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
}
|
||||
],
|
||||
"replies_full":
|
||||
[
|
||||
<bindata of 0x55bf85800001000100000001096c6f63...>
|
||||
],
|
||||
"replies_tree":
|
||||
[
|
||||
{
|
||||
"additional": [],
|
||||
"answer":
|
||||
[
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for localhost.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 127.0.0.1>,
|
||||
"rdata_raw": <bindata of 0x7f000001>
|
||||
},
|
||||
"ttl": 86400,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
}
|
||||
],
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"authority": [],
|
||||
"canonical_name": <bindata of "localhost.">,
|
||||
"header":
|
||||
{
|
||||
"aa": 1,
|
||||
"ad": 0,
|
||||
"ancount": 1,
|
||||
"arcount": 0,
|
||||
"cd": 0,
|
||||
"id": 21951,
|
||||
"nscount": 0,
|
||||
"opcode": GETDNS_OPCODE_QUERY,
|
||||
"qdcount": 1,
|
||||
"qr": 1,
|
||||
"ra": 1,
|
||||
"rcode": GETDNS_RCODE_NOERROR,
|
||||
"rd": 1,
|
||||
"tc": 0,
|
||||
"z": 0
|
||||
},
|
||||
"question":
|
||||
{
|
||||
"qclass": GETDNS_RRCLASS_IN,
|
||||
"qname": <bindata for localhost.>,
|
||||
"qtype": GETDNS_RRTYPE_A
|
||||
}
|
||||
}
|
||||
],
|
||||
"status": GETDNS_RESPSTATUS_GOOD
|
||||
}
|
||||
The packet {
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"canonical_name": <bindata of "localhost.">,
|
||||
"just_address_answers":
|
||||
[
|
||||
{
|
||||
"address_data": <bindata for 127.0.0.1>,
|
||||
"address_type": <bindata of "IPv4">
|
||||
},
|
||||
{
|
||||
"address_data": <bindata for ::1>,
|
||||
"address_type": <bindata of "IPv6">
|
||||
}
|
||||
],
|
||||
"replies_full":
|
||||
[
|
||||
<bindata of 0x8cbe85800001000100000001096c6f63...>,
|
||||
<bindata of 0xa65485800001000100000001096c6f63...>
|
||||
],
|
||||
"replies_tree":
|
||||
[
|
||||
{
|
||||
"additional": [],
|
||||
"answer":
|
||||
[
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for localhost.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv4_address": <bindata for 127.0.0.1>,
|
||||
"rdata_raw": <bindata of 0x7f000001>
|
||||
},
|
||||
"ttl": 86400,
|
||||
"type": GETDNS_RRTYPE_A
|
||||
}
|
||||
],
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"authority": [],
|
||||
"canonical_name": <bindata of "localhost.">,
|
||||
"header":
|
||||
{
|
||||
"aa": 1,
|
||||
"ad": 0,
|
||||
"ancount": 1,
|
||||
"arcount": 0,
|
||||
"cd": 0,
|
||||
"id": 36030,
|
||||
"nscount": 0,
|
||||
"opcode": GETDNS_OPCODE_QUERY,
|
||||
"qdcount": 1,
|
||||
"qr": 1,
|
||||
"ra": 1,
|
||||
"rcode": GETDNS_RCODE_NOERROR,
|
||||
"rd": 1,
|
||||
"tc": 0,
|
||||
"z": 0
|
||||
},
|
||||
"question":
|
||||
{
|
||||
"qclass": GETDNS_RRCLASS_IN,
|
||||
"qname": <bindata for localhost.>,
|
||||
"qtype": GETDNS_RRTYPE_A
|
||||
}
|
||||
},
|
||||
{
|
||||
"additional": [],
|
||||
"answer":
|
||||
[
|
||||
{
|
||||
"class": GETDNS_RRCLASS_IN,
|
||||
"name": <bindata for localhost.>,
|
||||
"rdata":
|
||||
{
|
||||
"ipv6_address": <bindata for ::1>,
|
||||
"rdata_raw": <bindata of 0x00000000000000000000000000000001>
|
||||
},
|
||||
"ttl": 10800,
|
||||
"type": GETDNS_RRTYPE_AAAA
|
||||
}
|
||||
],
|
||||
"answer_type": GETDNS_NAMETYPE_DNS,
|
||||
"authority": [],
|
||||
"canonical_name": <bindata of "localhost.">,
|
||||
"header":
|
||||
{
|
||||
"aa": 1,
|
||||
"ad": 0,
|
||||
"ancount": 1,
|
||||
"arcount": 0,
|
||||
"cd": 0,
|
||||
"id": 42580,
|
||||
"nscount": 0,
|
||||
"opcode": GETDNS_OPCODE_QUERY,
|
||||
"qdcount": 1,
|
||||
"qr": 1,
|
||||
"ra": 1,
|
||||
"rcode": GETDNS_RCODE_NOERROR,
|
||||
"rd": 1,
|
||||
"tc": 0,
|
||||
"z": 0
|
||||
},
|
||||
"question":
|
||||
{
|
||||
"qclass": GETDNS_RRCLASS_IN,
|
||||
"qname": <bindata for localhost.>,
|
||||
"qtype": GETDNS_RRTYPE_AAAA
|
||||
}
|
||||
}
|
||||
],
|
||||
"status": GETDNS_RESPSTATUS_GOOD
|
||||
}
|
|
@ -709,6 +709,80 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*This method can be used when e.g. a local lookup has been performed and the
|
||||
result is simply a list of addresses (not a DNS packet)*/
|
||||
struct getdns_dict *
|
||||
create_getdns_response_from_rr_list(struct getdns_dns_req * completed_request,
|
||||
ldns_rr_list * response_list)
|
||||
{
|
||||
struct getdns_dict *result = getdns_dict_create_with_context(completed_request->context);
|
||||
struct getdns_list *replies_full = getdns_list_create_with_context(
|
||||
completed_request->context);
|
||||
struct getdns_list *replies_tree = getdns_list_create_with_context(
|
||||
completed_request->context);
|
||||
struct getdns_list *just_addrs = NULL;
|
||||
char *canonical_name = NULL;
|
||||
getdns_return_t r = 0;
|
||||
|
||||
/* NOTE: With DNS packet, we ignore any DNSSEC related extensions since we
|
||||
don't populate the replies full or tree at all*/
|
||||
|
||||
just_addrs = getdns_list_create_with_context(completed_request->context);
|
||||
|
||||
do {
|
||||
canonical_name = get_canonical_name(completed_request->name);
|
||||
r = getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM,
|
||||
canonical_name);
|
||||
free(canonical_name);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* For local lookups we don't set an answer_type as there isn't a
|
||||
suitable one*/
|
||||
|
||||
r = add_only_addresses(just_addrs, response_list);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
r = getdns_dict_set_list(result, GETDNS_STR_KEY_REPLIES_TREE,
|
||||
replies_tree);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
r = getdns_dict_set_list(result, GETDNS_STR_KEY_REPLIES_FULL,
|
||||
replies_full);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
r = getdns_dict_set_list(result, GETDNS_STR_KEY_JUST_ADDRS,
|
||||
just_addrs);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
break;
|
||||
}
|
||||
|
||||
r = getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
|
||||
GETDNS_RESPSTATUS_GOOD);
|
||||
} while (0);
|
||||
|
||||
/* cleanup */
|
||||
getdns_list_destroy(replies_tree);
|
||||
getdns_list_destroy(replies_full);
|
||||
getdns_list_destroy(just_addrs);
|
||||
|
||||
if (r != 0) {
|
||||
getdns_dict_destroy(result);
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reverse an IP address for PTR lookup
|
||||
* @param address_data IP address to reverse
|
||||
|
|
|
@ -102,6 +102,8 @@ getdns_return_t sockaddr_to_dict(struct getdns_context *context,
|
|||
|
||||
struct getdns_dns_req;
|
||||
struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request);
|
||||
struct getdns_dict *create_getdns_response_from_rr_list(struct getdns_dns_req * completed_request,
|
||||
ldns_rr_list * response_list);
|
||||
|
||||
char *reverse_address(struct getdns_bindata *address_data);
|
||||
|
||||
|
|
Loading…
Reference in New Issue