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
60d1af78c5
163
src/context.c
163
src/context.c
|
@ -52,8 +52,15 @@
|
||||||
|
|
||||||
void *plain_mem_funcs_user_arg = MF_PLAIN;
|
void *plain_mem_funcs_user_arg = MF_PLAIN;
|
||||||
|
|
||||||
|
struct host_name_addr_type {
|
||||||
|
ldns_rdf * host_name;
|
||||||
|
ldns_rr_type addr_type;
|
||||||
|
};
|
||||||
|
|
||||||
/* Private functions */
|
/* Private functions */
|
||||||
getdns_return_t create_default_namespaces(struct getdns_context *context);
|
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 struct getdns_list *create_default_root_servers(void);
|
||||||
static getdns_return_t add_ip_str(struct getdns_dict *);
|
static getdns_return_t add_ip_str(struct getdns_dict *);
|
||||||
static struct getdns_dict *create_ipaddr_dict_from_rdf(struct getdns_context *,
|
static struct getdns_dict *create_ipaddr_dict_from_rdf(struct getdns_context *,
|
||||||
|
@ -63,6 +70,7 @@ static struct getdns_list *create_from_ldns_list(struct getdns_context *,
|
||||||
static getdns_return_t set_os_defaults(struct getdns_context *);
|
static getdns_return_t set_os_defaults(struct getdns_context *);
|
||||||
static int transaction_id_cmp(const void *, const void *);
|
static int transaction_id_cmp(const void *, const void *);
|
||||||
static int timeout_cmp(const void *, const void *);
|
static int timeout_cmp(const void *, const void *);
|
||||||
|
static int local_host_cmp(const void *, const void *);
|
||||||
static void dispatch_updated(struct getdns_context *, uint16_t);
|
static void dispatch_updated(struct getdns_context *, uint16_t);
|
||||||
static void cancel_dns_req(getdns_dns_req *);
|
static void cancel_dns_req(getdns_dns_req *);
|
||||||
static void cancel_outstanding_requests(struct getdns_context*, int);
|
static void cancel_outstanding_requests(struct getdns_context*, int);
|
||||||
|
@ -89,6 +97,16 @@ static getdns_return_t set_ldns_nameservers(struct getdns_context*,
|
||||||
/* Stuff to make it compile pedantically */
|
/* Stuff to make it compile pedantically */
|
||||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
#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.
|
* Helper to get default lookup namespaces.
|
||||||
* TODO: Determine from OS
|
* TODO: Determine from OS
|
||||||
|
@ -107,6 +125,59 @@ create_default_namespaces(struct getdns_context *context)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to get contents from hosts file
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
create_local_hosts(struct getdns_context *context)
|
||||||
|
{
|
||||||
|
|
||||||
|
ldns_rr_list * host_names = ldns_get_rr_list_hosts_frm_file(NULL);
|
||||||
|
if (host_names == NULL)
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
/* 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*/
|
||||||
|
for (int i = 0 ; i<ldns_rr_list_rr_count(host_names) ; i++) {
|
||||||
|
|
||||||
|
ldns_rr *rr = ldns_rr_list_rr(host_names, i);
|
||||||
|
ldns_rdf *owner = ldns_rdf_clone(ldns_rr_owner(rr));
|
||||||
|
|
||||||
|
/*Check to see if we already have an entry*/
|
||||||
|
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;
|
||||||
|
lh_key->host_name = owner;
|
||||||
|
lh_key->addr_type = ldns_rr_get_type(rr);
|
||||||
|
ldns_rbnode_t *result_node = ldns_rbtree_search(context->local_hosts, lh_key);
|
||||||
|
if (result_node) {
|
||||||
|
if (!ldns_rr_list_push_rr ((ldns_rr_list *)result_node->data, ldns_rr_clone(rr)))
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ldns_rr_list *address_list = ldns_rr_list_new ();
|
||||||
|
if (!ldns_rr_list_push_rr (address_list, ldns_rr_clone(rr)))
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
|
ldns_rbnode_t *node = GETDNS_MALLOC(context->my_mf, ldns_rbnode_t);
|
||||||
|
if (!node) {
|
||||||
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
}
|
||||||
|
node->key = lh_key;
|
||||||
|
node->data = address_list;
|
||||||
|
if (!ldns_rbtree_insert(context->local_hosts, 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.
|
* Helper to get the default root servers.
|
||||||
* TODO: Implement
|
* TODO: Implement
|
||||||
|
@ -385,6 +456,27 @@ timeout_cmp(const void *to1, const void *to2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
local_host_cmp(const void *id1, const void *id2)
|
||||||
|
{
|
||||||
|
if (id1 == NULL && id2 == NULL) {
|
||||||
|
return 0;
|
||||||
|
} else if (id1 == NULL && id2 != NULL) {
|
||||||
|
return 1;
|
||||||
|
} else if (id1 != NULL && id2 == NULL) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
const struct host_name_addr_type *hn1 = (const struct host_name_addr_type*) id1;
|
||||||
|
const struct host_name_addr_type *hn2 = (const struct host_name_addr_type*) id2;
|
||||||
|
if ((ldns_rr_type) hn1->addr_type < (ldns_rr_type) hn2->addr_type)
|
||||||
|
return -1;
|
||||||
|
if ((ldns_rr_type) hn1->addr_type > (ldns_rr_type) hn2->addr_type)
|
||||||
|
return 1;
|
||||||
|
return (ldns_rdf_compare((const ldns_rdf *) hn1->host_name,
|
||||||
|
(const ldns_rdf *) hn2->host_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ldns_rbtree_t*
|
static ldns_rbtree_t*
|
||||||
create_ldns_rbtree(getdns_context * context,
|
create_ldns_rbtree(getdns_context * context,
|
||||||
int(*cmpf)(const void *, const void *)) {
|
int(*cmpf)(const void *, const void *)) {
|
||||||
|
@ -444,6 +536,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
result->outbound_requests = create_ldns_rbtree(result, transaction_id_cmp);
|
result->outbound_requests = create_ldns_rbtree(result, transaction_id_cmp);
|
||||||
result->timeouts_by_time = create_ldns_rbtree(result, timeout_cmp);
|
result->timeouts_by_time = create_ldns_rbtree(result, timeout_cmp);
|
||||||
result->timeouts_by_id = create_ldns_rbtree(result, transaction_id_cmp);
|
result->timeouts_by_id = create_ldns_rbtree(result, transaction_id_cmp);
|
||||||
|
result->local_hosts = create_ldns_rbtree(result, local_host_cmp);
|
||||||
|
|
||||||
|
|
||||||
result->resolution_type = GETDNS_RESOLUTION_RECURSING;
|
result->resolution_type = GETDNS_RESOLUTION_RECURSING;
|
||||||
|
@ -484,7 +577,8 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||||
if (!result->outbound_requests ||
|
if (!result->outbound_requests ||
|
||||||
!result->timeouts_by_id ||
|
!result->timeouts_by_id ||
|
||||||
!result->timeouts_by_time) {
|
!result->timeouts_by_time ||
|
||||||
|
!result->local_hosts) {
|
||||||
getdns_context_destroy(result);
|
getdns_context_destroy(result);
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -495,7 +589,12 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
/* ldns context is initialised to NULL here and rebuilt later if needed */
|
/* ldns context is initialised to NULL here and rebuilt later if needed */
|
||||||
result->ldns_res = NULL;
|
result->ldns_res = NULL;
|
||||||
|
|
||||||
|
if(create_local_hosts(result) != GETDNS_RETURN_GOOD) {
|
||||||
|
getdns_context_destroy(result);
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
*context = result;
|
*context = result;
|
||||||
|
|
||||||
|
@ -591,6 +690,11 @@ getdns_context_destroy(struct getdns_context *context)
|
||||||
GETDNS_FREE(context->my_mf, context->timeouts_by_id);
|
GETDNS_FREE(context->my_mf, context->timeouts_by_id);
|
||||||
if (context->timeouts_by_time)
|
if (context->timeouts_by_time)
|
||||||
GETDNS_FREE(context->my_mf, context->timeouts_by_time);
|
GETDNS_FREE(context->my_mf, context->timeouts_by_time);
|
||||||
|
if (context->local_hosts) {
|
||||||
|
ldns_traverse_postorder(context->local_hosts,
|
||||||
|
destroy_local_host, context);
|
||||||
|
GETDNS_FREE(context->my_mf, context->local_hosts);
|
||||||
|
}
|
||||||
|
|
||||||
GETDNS_FREE(context->my_mf, context);
|
GETDNS_FREE(context->my_mf, context);
|
||||||
} /* getdns_context_destroy */
|
} /* getdns_context_destroy */
|
||||||
|
@ -2023,4 +2127,59 @@ getdns_context_set_use_threads(getdns_context* context, int use_threads) {
|
||||||
return r == 0 ? GETDNS_RETURN_GOOD : GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return r == 0 ? GETDNS_RETURN_GOOD : GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_local_namespace_resolve(getdns_dns_req* req,
|
||||||
|
struct getdns_dict **response,
|
||||||
|
struct getdns_context *context)
|
||||||
|
{
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (netreq->request_type != GETDNS_RRTYPE_A &&
|
||||||
|
netreq->request_type != GETDNS_RRTYPE_AAAA) {
|
||||||
|
netreq = netreq->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Do the lookup*/
|
||||||
|
ldns_rdf *query_name = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, req->name);
|
||||||
|
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) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ldns_rdf_deep_free(query_name);
|
||||||
|
netreq = netreq->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* context.c */
|
/* context.c */
|
||||||
|
|
|
@ -99,6 +99,8 @@ struct getdns_context {
|
||||||
/* The underlying contexts that do the real work */
|
/* The underlying contexts that do the real work */
|
||||||
struct ub_ctx *unbound_ctx;
|
struct ub_ctx *unbound_ctx;
|
||||||
ldns_resolver *ldns_res;
|
ldns_resolver *ldns_res;
|
||||||
|
/* A tree to hold local host information*/
|
||||||
|
struct ldns_rbtree_t *local_hosts;
|
||||||
int has_ta; /* No DNSSEC without trust anchor */
|
int has_ta; /* No DNSSEC without trust anchor */
|
||||||
int return_dnssec_status;
|
int return_dnssec_status;
|
||||||
|
|
||||||
|
@ -183,6 +185,11 @@ getdns_return_t getdns_context_schedule_timeout(struct getdns_context* context,
|
||||||
getdns_return_t getdns_context_clear_timeout(struct getdns_context* context,
|
getdns_return_t getdns_context_clear_timeout(struct getdns_context* context,
|
||||||
getdns_transaction_t id);
|
getdns_transaction_t id);
|
||||||
|
|
||||||
|
/* 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);
|
int filechg_check(struct getdns_context *context, struct filechg *fchg);
|
||||||
|
|
||||||
#endif /* _GETDNS_CONTEXT_H_ */
|
#endif /* _GETDNS_CONTEXT_H_ */
|
||||||
|
|
155
src/sync.c
155
src/sync.c
|
@ -107,8 +107,12 @@ static getdns_return_t submit_request_sync_stub(
|
||||||
tv.tv_usec = (*timeout % 1000) * 1000;
|
tv.tv_usec = (*timeout % 1000) * 1000;
|
||||||
ldns_resolver_set_timeout(req->context->ldns_res, tv);
|
ldns_resolver_set_timeout(req->context->ldns_res, tv);
|
||||||
netreq->result = ldns_resolver_query(
|
netreq->result = ldns_resolver_query(
|
||||||
req->context->ldns_res, qname, netreq->request_type,
|
req->context->ldns_res, qname, netreq->request_type,
|
||||||
netreq->request_class, qflags);
|
netreq->request_class, qflags);
|
||||||
|
/*TODO: The rec unbound case always sends DO=1 and then
|
||||||
|
getdns_apply_network_result sets these values...*/
|
||||||
|
// netreq->secure = ;
|
||||||
|
// netreq->bogus = ;
|
||||||
ldns_rdf_deep_free(qname);
|
ldns_rdf_deep_free(qname);
|
||||||
qname = NULL;
|
qname = NULL;
|
||||||
|
|
||||||
|
@ -116,6 +120,7 @@ static getdns_return_t submit_request_sync_stub(
|
||||||
/* TODO: use better errors */
|
/* TODO: use better errors */
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
netreq = netreq->next;
|
netreq = netreq->next;
|
||||||
}
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
@ -131,6 +136,94 @@ static getdns_return_t submit_request_sync(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_general_sync_ns(struct getdns_context *context,
|
||||||
|
const char *name,
|
||||||
|
uint16_t request_type,
|
||||||
|
struct getdns_dict *extensions,
|
||||||
|
struct getdns_dict **response,
|
||||||
|
bool usenamespaces)
|
||||||
|
{
|
||||||
|
getdns_dns_req *req;
|
||||||
|
getdns_return_t response_status;
|
||||||
|
uint64_t timeout;
|
||||||
|
|
||||||
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
RETURN_IF_NULL(response, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
RETURN_IF_NULL(name, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
timeout = context->timeout;
|
||||||
|
response_status = validate_dname(name);
|
||||||
|
if (response_status != GETDNS_RETURN_GOOD)
|
||||||
|
return response_status;
|
||||||
|
|
||||||
|
response_status = validate_extensions(extensions);
|
||||||
|
if (response_status != GETDNS_RETURN_GOOD)
|
||||||
|
return response_status;
|
||||||
|
|
||||||
|
/* Set up the context assuming we won't use the specified namespaces.
|
||||||
|
This is (currently) identical to setting up a pure DNS namespace */
|
||||||
|
response_status = getdns_context_prepare_for_resolution(context, 0);
|
||||||
|
if (response_status != GETDNS_RETURN_GOOD)
|
||||||
|
return response_status;
|
||||||
|
|
||||||
|
/* create the request */
|
||||||
|
req = dns_req_new(context, name, request_type, extensions);
|
||||||
|
if (!req)
|
||||||
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
|
||||||
|
/* resolve using the appropriate namespace*/
|
||||||
|
if (!usenamespaces) {
|
||||||
|
response_status = submit_request_sync(req, context);
|
||||||
|
} else {
|
||||||
|
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,
|
||||||
|
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;
|
||||||
|
|
||||||
|
default:
|
||||||
|
response_status = GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* 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"))
|
||||||
|
*response = priv_getdns_get_validation_chain_sync(req, &timeout);
|
||||||
|
else
|
||||||
|
*response = create_getdns_response(req);
|
||||||
|
|
||||||
|
} else if (response_status == GETDNS_RESPSTATUS_ALL_TIMEOUT) {
|
||||||
|
*response = create_getdns_response(req);
|
||||||
|
response_status = GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_req_free(req);
|
||||||
|
return response_status;
|
||||||
|
}
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_general_sync(struct getdns_context *context,
|
getdns_general_sync(struct getdns_context *context,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
@ -138,49 +231,9 @@ getdns_general_sync(struct getdns_context *context,
|
||||||
struct getdns_dict *extensions,
|
struct getdns_dict *extensions,
|
||||||
struct getdns_dict **response)
|
struct getdns_dict **response)
|
||||||
{
|
{
|
||||||
getdns_dns_req *req;
|
/* general, so without dns lookup (no namespaces) */;
|
||||||
getdns_return_t response_status;
|
return getdns_general_sync_ns(context, name, request_type,
|
||||||
uint64_t timeout;
|
extensions, response, false);
|
||||||
|
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
|
||||||
RETURN_IF_NULL(response, GETDNS_RETURN_INVALID_PARAMETER);
|
|
||||||
RETURN_IF_NULL(name, GETDNS_RETURN_INVALID_PARAMETER);
|
|
||||||
|
|
||||||
timeout = context->timeout;
|
|
||||||
response_status = validate_dname(name);
|
|
||||||
if (response_status != GETDNS_RETURN_GOOD)
|
|
||||||
return response_status;
|
|
||||||
|
|
||||||
response_status = validate_extensions(extensions);
|
|
||||||
if (response_status != GETDNS_RETURN_GOOD)
|
|
||||||
return response_status;
|
|
||||||
|
|
||||||
/* general, so without dns lookup (no namespaces) */;
|
|
||||||
response_status = getdns_context_prepare_for_resolution(context, 0);
|
|
||||||
if (response_status != GETDNS_RETURN_GOOD)
|
|
||||||
return response_status;
|
|
||||||
|
|
||||||
/* for each netreq we call ub_ctx_resolve */
|
|
||||||
/* request state */
|
|
||||||
req = dns_req_new(context, name, request_type, extensions);
|
|
||||||
if (!req)
|
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
|
||||||
|
|
||||||
response_status = submit_request_sync(req, context);
|
|
||||||
if (response_status == GETDNS_RETURN_GOOD) {
|
|
||||||
if (is_extension_set(req->extensions,
|
|
||||||
"dnssec_return_validation_chain"))
|
|
||||||
*response = priv_getdns_get_validation_chain_sync(req, &timeout);
|
|
||||||
else
|
|
||||||
*response = create_getdns_response(req);
|
|
||||||
|
|
||||||
} else if (response_status == GETDNS_RESPSTATUS_ALL_TIMEOUT) {
|
|
||||||
*response = create_getdns_response(req);
|
|
||||||
response_status = GETDNS_RETURN_GOOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_req_free(req);
|
|
||||||
return response_status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
|
@ -198,8 +251,8 @@ getdns_address_sync(struct getdns_context *context,
|
||||||
GETDNS_STR_EXTENSION_RETURN_BOTH_V4_AND_V6, GETDNS_EXTENSION_TRUE);
|
GETDNS_STR_EXTENSION_RETURN_BOTH_V4_AND_V6, GETDNS_EXTENSION_TRUE);
|
||||||
|
|
||||||
getdns_return_t result =
|
getdns_return_t result =
|
||||||
getdns_general_sync(context, name, GETDNS_RRTYPE_A,
|
getdns_general_sync_ns(context, name, GETDNS_RRTYPE_A,
|
||||||
extensions, response);
|
extensions, response, true);
|
||||||
if (cleanup_extensions) {
|
if (cleanup_extensions) {
|
||||||
getdns_dict_destroy(extensions);
|
getdns_dict_destroy(extensions);
|
||||||
}
|
}
|
||||||
|
@ -239,8 +292,8 @@ getdns_hostname_sync(struct getdns_context *context,
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
if ((name = reverse_address(address_data)) == NULL)
|
if ((name = reverse_address(address_data)) == NULL)
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
retval = getdns_general_sync(context, name, req_type, extensions,
|
retval = getdns_general_sync_ns(context, name, req_type, extensions,
|
||||||
response);
|
response, true);
|
||||||
free(name);
|
free(name);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -252,8 +305,8 @@ getdns_service_sync(struct getdns_context *context,
|
||||||
struct getdns_dict ** response)
|
struct getdns_dict ** response)
|
||||||
{
|
{
|
||||||
|
|
||||||
return getdns_general_sync(context, name, GETDNS_RRTYPE_SRV,
|
return getdns_general_sync_ns(context, name, GETDNS_RRTYPE_SRV,
|
||||||
extensions, response);
|
extensions, response, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ CC=@CC@
|
||||||
CFLAGS=@CFLAGS@ -Wall -I.. -I$(srcdir)/.. -I$(srcdir) -std=c99 $(cflags)
|
CFLAGS=@CFLAGS@ -Wall -I.. -I$(srcdir)/.. -I$(srcdir) -std=c99 $(cflags)
|
||||||
LDFLAGS=@LDFLAGS@ -L..
|
LDFLAGS=@LDFLAGS@ -L..
|
||||||
LDLIBS=-lgetdns @LIBS@ -lcheck -lm -lrt
|
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
|
.SUFFIXES: .c .o .a .lo .h
|
||||||
|
|
||||||
|
@ -78,6 +78,9 @@ tests_dict: tests_dict.lo testmessages.lo
|
||||||
tests_list: tests_list.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
|
$(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
|
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
|
$(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),
|
ASSERT_RC(getdns_address_sync(context, "localhost", NULL, &response),
|
||||||
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
|
GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()");
|
||||||
|
|
||||||
EXTRACT_RESPONSE;
|
EXTRACT_LOCAL_RESPONSE;
|
||||||
|
|
||||||
assert_noerror( &ex_response);
|
/* TODO: create reduced forms of these tests for local responses*/
|
||||||
assert_address_in_answer(&ex_response, TRUE, TRUE);
|
//assert_noerror( &ex_response);
|
||||||
|
//assert_address_in_answer(&ex_response, TRUE, TRUE);
|
||||||
|
|
||||||
|
|
||||||
CONTEXT_DESTROY;
|
CONTEXT_DESTROY;
|
||||||
|
|
|
@ -103,6 +103,25 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
|
||||||
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
|
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
|
* assert_noerror asserts that the rcode is 0
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -142,6 +142,14 @@
|
||||||
//
|
//
|
||||||
// FUNCTION DECLARATIONS
|
// 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
|
* extract_response extracts all of the various information
|
||||||
|
@ -149,6 +157,12 @@
|
||||||
*/
|
*/
|
||||||
void extract_response(struct getdns_dict *response, struct extracted_response *ex_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.
|
* 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;
|
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
|
* reverse an IP address for PTR lookup
|
||||||
* @param address_data IP address to reverse
|
* @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_dns_req;
|
||||||
struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request);
|
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);
|
char *reverse_address(struct getdns_bindata *address_data);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue