mirror of https://github.com/getdnsapi/getdns.git
Embed netreqs in dns_reqs and wire_data in netreqs
TODO: make sure the wire_data buffer is filled with the response
This commit is contained in:
parent
f9a0974e5a
commit
3f046cf573
|
@ -1389,9 +1389,9 @@ getdns_context_set_memory_functions(struct getdns_context *context,
|
||||||
static void
|
static void
|
||||||
cancel_dns_req(getdns_dns_req *req)
|
cancel_dns_req(getdns_dns_req *req)
|
||||||
{
|
{
|
||||||
getdns_network_req *netreq;
|
getdns_network_req *netreq, **netreq_p;
|
||||||
|
|
||||||
for (netreq = req->first_req; netreq; netreq = netreq->next)
|
for (netreq_p = req->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||||
if (netreq->unbound_id != -1) {
|
if (netreq->unbound_id != -1) {
|
||||||
ub_cancel(req->context->unbound_ctx,
|
ub_cancel(req->context->unbound_ctx,
|
||||||
netreq->unbound_id);
|
netreq->unbound_id);
|
||||||
|
@ -1921,12 +1921,12 @@ getdns_context_local_namespace_resolve(
|
||||||
ldns_rr_list *result_list = NULL;
|
ldns_rr_list *result_list = NULL;
|
||||||
host_name_addrs *hnas;
|
host_name_addrs *hnas;
|
||||||
ldns_rdf *query_name;
|
ldns_rdf *query_name;
|
||||||
int ipv4 = dnsreq->first_req->request_type == GETDNS_RRTYPE_A ||
|
int ipv4 = dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A ||
|
||||||
(dnsreq->first_req->next &&
|
(dnsreq->netreqs[1] &&
|
||||||
dnsreq->first_req->next->request_type == GETDNS_RRTYPE_A);
|
dnsreq->netreqs[1]->request_type == GETDNS_RRTYPE_A);
|
||||||
int ipv6 = dnsreq->first_req->request_type == GETDNS_RRTYPE_AAAA ||
|
int ipv6 = dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA ||
|
||||||
(dnsreq->first_req->next &&
|
(dnsreq->netreqs[1] &&
|
||||||
dnsreq->first_req->next->request_type == GETDNS_RRTYPE_AAAA);
|
dnsreq->netreqs[1]->request_type == GETDNS_RRTYPE_AAAA);
|
||||||
|
|
||||||
if (!ipv4 && !ipv6)
|
if (!ipv4 && !ipv6)
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
|
@ -272,7 +272,7 @@ static void destroy_chain(struct validation_chain *chain)
|
||||||
static void
|
static void
|
||||||
getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
||||||
{
|
{
|
||||||
getdns_network_req *netreq = dns_req->first_req;
|
getdns_network_req **netreq_p, *netreq;
|
||||||
struct validation_chain *chain = create_chain(dns_req, timeout);
|
struct validation_chain *chain = create_chain(dns_req, timeout);
|
||||||
|
|
||||||
if (! chain) {
|
if (! chain) {
|
||||||
|
@ -280,7 +280,7 @@ getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
||||||
dns_req, create_getdns_response(dns_req));
|
dns_req, create_getdns_response(dns_req));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (netreq) {
|
for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) {
|
||||||
size_t i;
|
size_t i;
|
||||||
ldns_rr_list *answer = ldns_pkt_answer(netreq->result);
|
ldns_rr_list *answer = ldns_pkt_answer(netreq->result);
|
||||||
ldns_rr_list *authority = ldns_pkt_authority(netreq->result);
|
ldns_rr_list *authority = ldns_pkt_authority(netreq->result);
|
||||||
|
@ -296,7 +296,6 @@ getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
||||||
launch_chain_link_lookup(chain,
|
launch_chain_link_lookup(chain,
|
||||||
ldns_rdf2str(ldns_rr_rdf(rr, 7)));
|
ldns_rdf2str(ldns_rr_rdf(rr, 7)));
|
||||||
}
|
}
|
||||||
netreq = netreq->next;
|
|
||||||
}
|
}
|
||||||
callback_on_complete_chain(chain);
|
callback_on_complete_chain(chain);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,10 +81,10 @@ handle_network_request_error(getdns_network_req * netreq, int err)
|
||||||
void
|
void
|
||||||
priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
||||||
{
|
{
|
||||||
getdns_network_req *netreq;
|
getdns_network_req **netreq_p, *netreq;
|
||||||
int results_found = 0;
|
int results_found = 0;
|
||||||
|
|
||||||
for (netreq = dns_req->first_req; netreq; netreq = netreq->next)
|
for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||||
if (netreq->state != NET_REQ_FINISHED &&
|
if (netreq->state != NET_REQ_FINISHED &&
|
||||||
netreq->state != NET_REQ_CANCELED)
|
netreq->state != NET_REQ_CANCELED)
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +168,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
getdns_callback_t callbackfn, int usenamespaces)
|
getdns_callback_t callbackfn, int usenamespaces)
|
||||||
{
|
{
|
||||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||||
getdns_network_req *netreq;
|
getdns_network_req *netreq, **netreq_p;
|
||||||
getdns_dns_req *req;
|
getdns_dns_req *req;
|
||||||
getdns_dict *localnames_response;
|
getdns_dict *localnames_response;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -201,7 +201,9 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
|
|
||||||
if (!usenamespaces)
|
if (!usenamespaces)
|
||||||
/* issue all network requests */
|
/* issue all network requests */
|
||||||
for (netreq = req->first_req; !r && netreq; netreq = netreq->next)
|
for ( netreq_p = req->netreqs
|
||||||
|
; !r && (netreq = *netreq_p)
|
||||||
|
; netreq_p++)
|
||||||
r = submit_network_request(netreq);
|
r = submit_network_request(netreq);
|
||||||
|
|
||||||
else for (i = 0; i < context->namespace_count; i++) {
|
else for (i = 0; i < context->namespace_count; i++) {
|
||||||
|
@ -221,11 +223,10 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
if this means we go onto the next namespace instead
|
if this means we go onto the next namespace instead
|
||||||
of returning */
|
of returning */
|
||||||
r = GETDNS_RETURN_GOOD;
|
r = GETDNS_RETURN_GOOD;
|
||||||
netreq = req->first_req;
|
for ( netreq_p = req->netreqs
|
||||||
while (!r && netreq) {
|
; !r && (netreq = *netreq_p)
|
||||||
|
; netreq_p++)
|
||||||
r = submit_network_request(netreq);
|
r = submit_network_request(netreq);
|
||||||
netreq = netreq->next;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
r = GETDNS_RETURN_BAD_CONTEXT;
|
r = GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
|
|
@ -38,31 +38,24 @@
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
#include "gldns/rrdef.h"
|
#include "gldns/rrdef.h"
|
||||||
|
|
||||||
void
|
static void
|
||||||
network_req_free(getdns_network_req * net_req)
|
network_req_cleanup(getdns_network_req *net_req)
|
||||||
{
|
{
|
||||||
if (!net_req) {
|
assert(net_req);
|
||||||
return;
|
|
||||||
}
|
if (net_req->result)
|
||||||
if (net_req->result) {
|
|
||||||
ldns_pkt_free(net_req->result);
|
ldns_pkt_free(net_req->result);
|
||||||
}
|
|
||||||
GETDNS_FREE(net_req->owner->my_mf, net_req);
|
if (net_req->response && net_req->response != net_req->wire_data)
|
||||||
|
GETDNS_FREE(net_req->owner->my_mf, net_req->response);
|
||||||
}
|
}
|
||||||
|
|
||||||
getdns_network_req *
|
static void
|
||||||
network_req_new(getdns_dns_req * owner,
|
network_req_init(getdns_network_req *net_req,
|
||||||
uint16_t request_type,
|
getdns_dns_req *owner, uint16_t request_type,
|
||||||
uint16_t request_class, struct getdns_dict *extensions)
|
uint16_t request_class, size_t wire_data_sz)
|
||||||
{
|
{
|
||||||
|
|
||||||
getdns_network_req *net_req = GETDNS_MALLOC( owner->my_mf
|
|
||||||
, getdns_network_req);
|
|
||||||
if (!net_req) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
net_req->result = NULL;
|
net_req->result = NULL;
|
||||||
net_req->next = NULL;
|
|
||||||
|
|
||||||
net_req->request_type = request_type;
|
net_req->request_type = request_type;
|
||||||
net_req->request_class = request_class;
|
net_req->request_class = request_class;
|
||||||
|
@ -70,8 +63,6 @@ network_req_new(getdns_dns_req * owner,
|
||||||
net_req->state = NET_REQ_NOT_SENT;
|
net_req->state = NET_REQ_NOT_SENT;
|
||||||
net_req->owner = owner;
|
net_req->owner = owner;
|
||||||
|
|
||||||
/* TODO: records and other extensions */
|
|
||||||
|
|
||||||
net_req->upstream = NULL;
|
net_req->upstream = NULL;
|
||||||
net_req->fd = -1;
|
net_req->fd = -1;
|
||||||
memset(&net_req->event, 0, sizeof(net_req->event));
|
memset(&net_req->event, 0, sizeof(net_req->event));
|
||||||
|
@ -79,16 +70,18 @@ network_req_new(getdns_dns_req * owner,
|
||||||
net_req->query_id = 0;
|
net_req->query_id = 0;
|
||||||
net_req->max_udp_payload_size = 0;
|
net_req->max_udp_payload_size = 0;
|
||||||
net_req->write_queue_tail = NULL;
|
net_req->write_queue_tail = NULL;
|
||||||
return net_req;
|
|
||||||
|
net_req->wire_data_sz = wire_data_sz;
|
||||||
|
net_req->response = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_req_free(getdns_dns_req * req)
|
dns_req_free(getdns_dns_req * req)
|
||||||
{
|
{
|
||||||
|
getdns_network_req **net_req;
|
||||||
if (!req) {
|
if (!req) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getdns_network_req *net_req = NULL;
|
|
||||||
|
|
||||||
/* free extensions */
|
/* free extensions */
|
||||||
getdns_dict_destroy(req->extensions);
|
getdns_dict_destroy(req->extensions);
|
||||||
|
@ -96,14 +89,11 @@ dns_req_free(getdns_dns_req * req)
|
||||||
if (req->upstreams && --req->upstreams->referenced == 0)
|
if (req->upstreams && --req->upstreams->referenced == 0)
|
||||||
GETDNS_FREE(req->upstreams->mf, req->upstreams);
|
GETDNS_FREE(req->upstreams->mf, req->upstreams);
|
||||||
|
|
||||||
/* free network requests */
|
/* cleanup network requests */
|
||||||
net_req = req->first_req;
|
for (net_req = req->netreqs; *net_req; net_req++)
|
||||||
while (net_req) {
|
network_req_cleanup(*net_req);
|
||||||
getdns_network_req *next = net_req->next;
|
|
||||||
network_req_free(net_req);
|
|
||||||
net_req = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* clear timeout event */
|
||||||
if (req->timeout.timeout_cb) {
|
if (req->timeout.timeout_cb) {
|
||||||
req->loop->vmt->clear(req->loop, &req->timeout);
|
req->loop->vmt->clear(req->loop, &req->timeout);
|
||||||
req->timeout.timeout_cb = NULL;
|
req->timeout.timeout_cb = NULL;
|
||||||
|
@ -116,25 +106,47 @@ dns_req_free(getdns_dns_req * req)
|
||||||
|
|
||||||
/* create a new dns req to be submitted */
|
/* create a new dns req to be submitted */
|
||||||
getdns_dns_req *
|
getdns_dns_req *
|
||||||
dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
|
dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, struct getdns_dict *extensions)
|
const char *name, uint16_t request_type, getdns_dict *extensions)
|
||||||
{
|
{
|
||||||
|
|
||||||
getdns_dns_req *result = NULL;
|
getdns_dns_req *result = NULL;
|
||||||
getdns_network_req *req = NULL;
|
|
||||||
uint32_t klass = GLDNS_RR_CLASS_IN;
|
uint32_t klass = GLDNS_RR_CLASS_IN;
|
||||||
|
size_t edns_maximum_udp_payload_size =
|
||||||
|
getdns_get_maximum_udp_payload_size(context, extensions, NULL);
|
||||||
|
int a_aaaa_query =
|
||||||
|
is_extension_set(extensions, "return_both_v4_and_v6") &&
|
||||||
|
( request_type == GETDNS_RRTYPE_A ||
|
||||||
|
request_type == GETDNS_RRTYPE_AAAA );
|
||||||
|
/* Reserve for the buffer at least one more byte
|
||||||
|
* (to test for udp overflow) (hence the + 1),
|
||||||
|
* And align on the 8 byte boundry (hence the (x + 7) / 8 * 8)
|
||||||
|
*/
|
||||||
|
size_t netreq_sz = ( sizeof(getdns_network_req)
|
||||||
|
+ edns_maximum_udp_payload_size + 1 + 7) / 8 * 8;
|
||||||
|
size_t dnsreq_base_sz = ( sizeof(getdns_dns_req)
|
||||||
|
+ (a_aaaa_query ? 3 : 2)
|
||||||
|
* sizeof(getdns_network_req *));
|
||||||
|
uint8_t *region;
|
||||||
|
|
||||||
result = GETDNS_MALLOC(context->mf, getdns_dns_req);
|
if (! (region = GETDNS_XMALLOC(context->mf, uint8_t,
|
||||||
if (result == NULL) {
|
dnsreq_base_sz + (a_aaaa_query ? 2 : 1) * netreq_sz)))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
result = (getdns_dns_req *)region;
|
||||||
|
result->netreqs[0] = (getdns_network_req *)(region + dnsreq_base_sz);
|
||||||
|
if (a_aaaa_query) {
|
||||||
|
result->netreqs[1] = (getdns_network_req *)
|
||||||
|
(region + dnsreq_base_sz + netreq_sz);
|
||||||
|
result->netreqs[2] = NULL;
|
||||||
|
} else
|
||||||
|
result->netreqs[1] = NULL;
|
||||||
|
|
||||||
result->my_mf = context->mf;
|
result->my_mf = context->mf;
|
||||||
result->name = getdns_strdup(&(result->my_mf), name);
|
result->name = getdns_strdup(&(result->my_mf), name);
|
||||||
result->context = context;
|
result->context = context;
|
||||||
result->loop = loop;
|
result->loop = loop;
|
||||||
result->canceled = 0;
|
result->canceled = 0;
|
||||||
result->current_req = NULL;
|
|
||||||
result->first_req = NULL;
|
|
||||||
result->trans_id = (uint64_t)(((intptr_t) result) ^ ldns_get_random());
|
result->trans_id = (uint64_t)(((intptr_t) result) ^ ldns_get_random());
|
||||||
|
|
||||||
getdns_dict_copy(extensions, &result->extensions);
|
getdns_dict_copy(extensions, &result->extensions);
|
||||||
|
@ -152,32 +164,14 @@ dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
|
||||||
if (result->upstreams)
|
if (result->upstreams)
|
||||||
result->upstreams->referenced++;
|
result->upstreams->referenced++;
|
||||||
|
|
||||||
/* create the requests */
|
network_req_init(result->netreqs[0], result, request_type,
|
||||||
req = network_req_new(result, request_type, klass, extensions);
|
klass, netreq_sz - sizeof(getdns_network_req));
|
||||||
if (!req) {
|
|
||||||
dns_req_free(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result->current_req = req;
|
if (a_aaaa_query)
|
||||||
result->first_req = req;
|
network_req_init(result->netreqs[1], result,
|
||||||
|
( request_type == GETDNS_RRTYPE_A
|
||||||
/* tack on A or AAAA if needed */
|
? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ),
|
||||||
if (is_extension_set(extensions, "return_both_v4_and_v6") &&
|
klass, netreq_sz - sizeof(getdns_network_req));
|
||||||
(request_type == GETDNS_RRTYPE_A ||
|
|
||||||
request_type == GETDNS_RRTYPE_AAAA)) {
|
|
||||||
|
|
||||||
uint16_t next_req_type = (request_type == GETDNS_RRTYPE_A) ?
|
|
||||||
GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A;
|
|
||||||
getdns_network_req *next_req = network_req_new(result,
|
|
||||||
next_req_type, LDNS_RR_CLASS_IN, extensions);
|
|
||||||
|
|
||||||
if (!next_req) {
|
|
||||||
dns_req_free(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
req->next = next_req;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,6 @@ getdns_make_query_pkt_buf(const getdns_network_req *netreq, uint8_t *buf,
|
||||||
if (len < 11)
|
if (len < 11)
|
||||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
*omax_udp_payload_size = edns_maximum_udp_payload_size;
|
|
||||||
buf[0] = 0; /* dname for . */
|
buf[0] = 0; /* dname for . */
|
||||||
gldns_write_uint16(buf + 1, GLDNS_RR_TYPE_OPT);
|
gldns_write_uint16(buf + 1, GLDNS_RR_TYPE_OPT);
|
||||||
gldns_write_uint16(buf + 3,
|
gldns_write_uint16(buf + 3,
|
||||||
|
|
|
@ -191,9 +191,6 @@ typedef struct getdns_network_req
|
||||||
int secure;
|
int secure;
|
||||||
int bogus;
|
int bogus;
|
||||||
|
|
||||||
/* next request to issue after this one */
|
|
||||||
struct getdns_network_req *next;
|
|
||||||
|
|
||||||
/* For stub resolving */
|
/* For stub resolving */
|
||||||
struct getdns_upstream *upstream;
|
struct getdns_upstream *upstream;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -206,6 +203,14 @@ typedef struct getdns_network_req
|
||||||
/* Network requests scheduled to write after me */
|
/* Network requests scheduled to write after me */
|
||||||
struct getdns_network_req *write_queue_tail;
|
struct getdns_network_req *write_queue_tail;
|
||||||
|
|
||||||
|
/* When more space is needed for the wire_data response than is
|
||||||
|
* available in wire_data[], it will be allocated seperately.
|
||||||
|
* response will then not point to wire_data anymore.
|
||||||
|
*/
|
||||||
|
uint8_t *response;
|
||||||
|
size_t wire_data_sz;
|
||||||
|
uint8_t wire_data[];
|
||||||
|
|
||||||
} getdns_network_req;
|
} getdns_network_req;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,12 +227,6 @@ typedef struct getdns_dns_req {
|
||||||
/* canceled flag */
|
/* canceled flag */
|
||||||
int canceled;
|
int canceled;
|
||||||
|
|
||||||
/* current network request */
|
|
||||||
struct getdns_network_req *current_req;
|
|
||||||
|
|
||||||
/* first request in list */
|
|
||||||
struct getdns_network_req *first_req;
|
|
||||||
|
|
||||||
/* context that owns the request */
|
/* context that owns the request */
|
||||||
struct getdns_context *context;
|
struct getdns_context *context;
|
||||||
|
|
||||||
|
@ -256,6 +255,16 @@ typedef struct getdns_dns_req {
|
||||||
/* Stuff for stub resolving */
|
/* Stuff for stub resolving */
|
||||||
struct getdns_upstreams *upstreams;
|
struct getdns_upstreams *upstreams;
|
||||||
|
|
||||||
|
/* network requests for this dns request.
|
||||||
|
* The array is terminated with NULL.
|
||||||
|
*
|
||||||
|
* Memory for these netreqs has been allocated by the same malloc
|
||||||
|
* operation that reserved space for this getdns_dns_req.
|
||||||
|
* They will thus be freed as part of the desctruction of this struct,
|
||||||
|
* and do not need to be freed seperately.
|
||||||
|
*/
|
||||||
|
getdns_network_req *netreqs[];
|
||||||
|
|
||||||
} getdns_dns_req;
|
} getdns_dns_req;
|
||||||
|
|
||||||
#define GETDNS_XMALLOC(obj, type, count) \
|
#define GETDNS_XMALLOC(obj, type, count) \
|
||||||
|
@ -294,13 +303,6 @@ typedef struct getdns_dns_req {
|
||||||
|
|
||||||
/* utility methods */
|
/* utility methods */
|
||||||
|
|
||||||
/* network request utilities */
|
|
||||||
void network_req_free(getdns_network_req * net_req);
|
|
||||||
|
|
||||||
getdns_network_req *network_req_new(getdns_dns_req * owner,
|
|
||||||
uint16_t request_type,
|
|
||||||
uint16_t request_class, struct getdns_dict *extensions);
|
|
||||||
|
|
||||||
/* dns request utils */
|
/* dns request utils */
|
||||||
getdns_dns_req *dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
getdns_dns_req *dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions);
|
const char *name, uint16_t request_type, getdns_dict *extensions);
|
||||||
|
|
|
@ -544,7 +544,7 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
struct getdns_list *just_addrs = NULL;
|
struct getdns_list *just_addrs = NULL;
|
||||||
struct getdns_list *replies_tree = getdns_list_create_with_context(
|
struct getdns_list *replies_tree = getdns_list_create_with_context(
|
||||||
completed_request->context);
|
completed_request->context);
|
||||||
getdns_network_req *netreq;
|
getdns_network_req *netreq, **netreq_p;
|
||||||
char *canonical_name = NULL;
|
char *canonical_name = NULL;
|
||||||
getdns_return_t r = 0;
|
getdns_return_t r = 0;
|
||||||
int nreplies = 0, nanswers = 0, nsecure = 0, ninsecure = 0, nbogus = 0;
|
int nreplies = 0, nanswers = 0, nsecure = 0, ninsecure = 0, nbogus = 0;
|
||||||
|
@ -562,13 +562,11 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
completed_request->extensions, "dnssec_return_status") ||
|
completed_request->extensions, "dnssec_return_status") ||
|
||||||
completed_request->return_dnssec_status == GETDNS_EXTENSION_TRUE;
|
completed_request->return_dnssec_status == GETDNS_EXTENSION_TRUE;
|
||||||
|
|
||||||
if (completed_request->first_req &&
|
if (completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_A ||
|
||||||
(completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
|
completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA)
|
||||||
completed_request->first_req->request_class ==
|
|
||||||
GETDNS_RRTYPE_AAAA)) {
|
|
||||||
just_addrs = getdns_list_create_with_context(
|
just_addrs = getdns_list_create_with_context(
|
||||||
completed_request->context);
|
completed_request->context);
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
canonical_name = get_canonical_name(completed_request->name);
|
canonical_name = get_canonical_name(completed_request->name);
|
||||||
r = getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM,
|
r = getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM,
|
||||||
|
@ -584,9 +582,9 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( netreq = completed_request->first_req
|
for ( netreq_p = completed_request->netreqs
|
||||||
; netreq && r == GETDNS_RETURN_GOOD
|
; ! r && (netreq = *netreq_p)
|
||||||
; netreq = netreq->next ) {
|
; netreq_p++) {
|
||||||
|
|
||||||
if (! netreq->result)
|
if (! netreq->result)
|
||||||
continue;
|
continue;
|
||||||
|
@ -959,7 +957,7 @@ validate_dname(const char* dname) {
|
||||||
} /* validate_dname */
|
} /* validate_dname */
|
||||||
|
|
||||||
int
|
int
|
||||||
is_extension_set(struct getdns_dict *extensions, const char *extension)
|
is_extension_set(getdns_dict *extensions, const char *extension)
|
||||||
{
|
{
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
@ -971,4 +969,76 @@ is_extension_set(struct getdns_dict *extensions, const char *extension)
|
||||||
return r == GETDNS_RETURN_GOOD && value == GETDNS_EXTENSION_TRUE;
|
return r == GETDNS_RETURN_GOOD && value == GETDNS_EXTENSION_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
getdns_get_maximum_udp_payload_size(getdns_context *context,
|
||||||
|
getdns_dict *extensions, getdns_upstream *upstream)
|
||||||
|
{
|
||||||
|
int dnssec_return_status
|
||||||
|
= is_extension_set(extensions, "dnssec_return_status");
|
||||||
|
int dnssec_return_only_secure
|
||||||
|
= is_extension_set(extensions, "dnssec_return_only_secure");
|
||||||
|
int dnssec_return_validation_chain
|
||||||
|
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
||||||
|
int dnssec_extension_set = dnssec_return_status
|
||||||
|
|| dnssec_return_only_secure || dnssec_return_validation_chain;
|
||||||
|
|
||||||
|
uint32_t edns_do_bit;
|
||||||
|
int edns_maximum_udp_payload_size;
|
||||||
|
uint32_t get_edns_maximum_udp_payload_size;
|
||||||
|
uint32_t edns_extended_rcode;
|
||||||
|
uint32_t edns_version;
|
||||||
|
|
||||||
|
getdns_dict *add_opt_parameters;
|
||||||
|
int have_add_opt_parameters;
|
||||||
|
|
||||||
|
getdns_list *options;
|
||||||
|
size_t noptions = 0;
|
||||||
|
|
||||||
|
int with_opt;
|
||||||
|
|
||||||
|
have_add_opt_parameters = getdns_dict_get_dict(extensions,
|
||||||
|
"add_opt_parameters", &add_opt_parameters) == GETDNS_RETURN_GOOD;
|
||||||
|
|
||||||
|
if (dnssec_extension_set) {
|
||||||
|
edns_maximum_udp_payload_size =
|
||||||
|
( upstream && upstream->addr.ss_family == AF_INET6 )
|
||||||
|
? 1232 : 1432;
|
||||||
|
edns_extended_rcode = 0;
|
||||||
|
edns_version = 0;
|
||||||
|
edns_do_bit = 1;
|
||||||
|
} else {
|
||||||
|
edns_maximum_udp_payload_size =
|
||||||
|
context->edns_maximum_udp_payload_size;
|
||||||
|
edns_extended_rcode = context->edns_extended_rcode;
|
||||||
|
edns_version = context->edns_version;
|
||||||
|
edns_do_bit = context->edns_do_bit;
|
||||||
|
|
||||||
|
if (have_add_opt_parameters) {
|
||||||
|
if (!getdns_dict_get_int(add_opt_parameters,
|
||||||
|
"maximum_udp_payload_size",
|
||||||
|
&get_edns_maximum_udp_payload_size))
|
||||||
|
edns_maximum_udp_payload_size =
|
||||||
|
get_edns_maximum_udp_payload_size;
|
||||||
|
(void) getdns_dict_get_int(add_opt_parameters,
|
||||||
|
"extended_rcode", &edns_extended_rcode);
|
||||||
|
(void) getdns_dict_get_int(add_opt_parameters,
|
||||||
|
"version", &edns_version);
|
||||||
|
(void) getdns_dict_get_int(add_opt_parameters,
|
||||||
|
"do_bit", &edns_do_bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (have_add_opt_parameters && getdns_dict_get_list(
|
||||||
|
add_opt_parameters, "options", &options) == GETDNS_RETURN_GOOD)
|
||||||
|
(void) getdns_list_get_length(options, &noptions);
|
||||||
|
|
||||||
|
with_opt = edns_do_bit != 0 || edns_maximum_udp_payload_size != -1 ||
|
||||||
|
edns_extended_rcode != 0 || edns_version != 0 || noptions;
|
||||||
|
|
||||||
|
return ! with_opt ? 512
|
||||||
|
: edns_maximum_udp_payload_size == -1 ?
|
||||||
|
(upstream && upstream->addr.ss_family==AF_INET6 ) ? 1232 : 1432
|
||||||
|
: edns_maximum_udp_payload_size > 512 ?
|
||||||
|
edns_maximum_udp_payload_size : 512;
|
||||||
|
}
|
||||||
|
|
||||||
/* util-internal.c */
|
/* util-internal.c */
|
||||||
|
|
|
@ -147,7 +147,10 @@ create_list_from_rr_list(struct getdns_context *context, ldns_rr_list * rr_list)
|
||||||
* @param extension name of extension to check
|
* @param extension name of extension to check
|
||||||
* @return int with value 1 if set to GETDNS_EXTENSION_TRUE and 0 otherwise
|
* @return int with value 1 if set to GETDNS_EXTENSION_TRUE and 0 otherwise
|
||||||
*/
|
*/
|
||||||
int is_extension_set(struct getdns_dict *extensions, const char *extension);
|
int is_extension_set(getdns_dict *extensions, const char *extension);
|
||||||
|
|
||||||
|
size_t getdns_get_maximum_udp_payload_size(getdns_context *context,
|
||||||
|
getdns_dict *extensions, getdns_upstream *upstream);
|
||||||
|
|
||||||
#define DEBUG_ON(...) do { \
|
#define DEBUG_ON(...) do { \
|
||||||
struct timeval tv; \
|
struct timeval tv; \
|
||||||
|
|
Loading…
Reference in New Issue