First query append

This commit is contained in:
Willem Toorop 2015-12-29 17:34:14 +01:00
parent 54498cd556
commit 89b6c04d4f
7 changed files with 129 additions and 88 deletions

View File

@ -104,7 +104,7 @@ getdns_port_str_array[] = {
GETDNS_STR_PORT_DNS_OVER_TLS GETDNS_STR_PORT_DNS_OVER_TLS
}; };
static uint8_t no_suffixes[] = { 0, 0 }; static const uint8_t no_suffixes[] = { 1, 0 };
/* Private functions */ /* Private functions */
static getdns_return_t create_default_namespaces(struct getdns_context *context); static getdns_return_t create_default_namespaces(struct getdns_context *context);
@ -1181,7 +1181,7 @@ getdns_context_destroy(struct getdns_context *context)
unlink(context->root_servers_fn); unlink(context->root_servers_fn);
if (context->suffixes && context->suffixes != no_suffixes) if (context->suffixes && context->suffixes != no_suffixes)
GETDNS_FREE(context->mf, context->suffixes); GETDNS_FREE(context->mf, (void *)context->suffixes);
if (context->trust_anchors && if (context->trust_anchors &&
context->trust_anchors != context->trust_anchors_spc) context->trust_anchors != context->trust_anchors_spc)
@ -1830,7 +1830,7 @@ getdns_context_set_suffix(getdns_context *context, getdns_list *value)
if (value == NULL) { if (value == NULL) {
if (context->suffixes && context->suffixes != no_suffixes) if (context->suffixes && context->suffixes != no_suffixes)
GETDNS_FREE(context->mf, context->suffixes); GETDNS_FREE(context->mf, (void *)context->suffixes);
context->suffixes = no_suffixes; context->suffixes = no_suffixes;
context->suffixes_len = sizeof(no_suffixes); context->suffixes_len = sizeof(no_suffixes);
@ -1890,7 +1890,7 @@ getdns_context_set_suffix(getdns_context *context, getdns_list *value)
return r; return r;
} }
if (context->suffixes && context->suffixes != no_suffixes) if (context->suffixes && context->suffixes != no_suffixes)
GETDNS_FREE(context->mf, context->suffixes); GETDNS_FREE(context->mf, (void *)context->suffixes);
context->suffixes = suffixes; context->suffixes = suffixes;
context->suffixes_len = suffixes_len; context->suffixes_len = suffixes_len;
@ -3248,7 +3248,7 @@ getdns_return_t
getdns_context_get_suffix(getdns_context *context, getdns_list **value) getdns_context_get_suffix(getdns_context *context, getdns_list **value)
{ {
size_t dname_len; size_t dname_len;
uint8_t *dname; const uint8_t *dname;
char name[1024]; char name[1024];
getdns_return_t r = GETDNS_RETURN_GOOD; getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_list *list; getdns_list *list;
@ -3263,7 +3263,7 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value)
dname_len = context->suffixes[0]; dname_len = context->suffixes[0];
dname = context->suffixes + 1; dname = context->suffixes + 1;
while (dname_len && *dname) { while (dname_len && *dname) {
if (! gldns_wire2str_dname_buf( if (! gldns_wire2str_dname_buf((UNCONST_UINT8_p)
dname, dname_len, name, sizeof(name))) { dname, dname_len, name, sizeof(name))) {
r = GETDNS_RETURN_GENERIC_ERROR; r = GETDNS_RETURN_GENERIC_ERROR;
break; break;

View File

@ -183,7 +183,7 @@ struct getdns_context {
* length bytes contains the length of the following dname. * length bytes contains the length of the following dname.
* The last dname should be the zero byte. * The last dname should be the zero byte.
*/ */
uint8_t *suffixes; const uint8_t *suffixes;
/* Length of all suffixes in the suffix buffer */ /* Length of all suffixes in the suffix buffer */
size_t suffixes_len; size_t suffixes_len;
uint8_t *trust_anchors; uint8_t *trust_anchors;

View File

@ -3269,7 +3269,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
, netreq->response, netreq->response_len , netreq->response, netreq->response_len
, netreq->owner->name , netreq->owner->name
, netreq->request_type , netreq->request_type
, netreq->request_class , netreq->owner->request_class
, netreq , netreq
); );
} }

View File

@ -173,7 +173,7 @@ _getdns_submit_netreq(getdns_network_req *netreq)
#ifdef HAVE_LIBUNBOUND #ifdef HAVE_LIBUNBOUND
return ub_resolve_async(dns_req->context->unbound_ctx, return ub_resolve_async(dns_req->context->unbound_ctx,
name, netreq->request_type, netreq->request_class, name, netreq->request_type, netreq->owner->request_class,
netreq, ub_resolve_callback, &(netreq->unbound_id)) ? netreq, ub_resolve_callback, &(netreq->unbound_id)) ?
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD; GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
#else #else

View File

@ -112,15 +112,13 @@ network_req_cleanup(getdns_network_req *net_req)
static int static int
network_req_init(getdns_network_req *net_req, getdns_dns_req *owner, network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
const char *name, uint16_t request_type, uint16_t request_class, uint16_t request_type, int dnssec_extension_set, int with_opt,
int dnssec_extension_set, int with_opt,
int edns_maximum_udp_payload_size, int edns_maximum_udp_payload_size,
uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit, uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit,
uint16_t opt_options_size, size_t noptions, getdns_list *options, uint16_t opt_options_size, size_t noptions, getdns_list *options,
size_t wire_data_sz, size_t max_query_sz) size_t wire_data_sz, size_t max_query_sz)
{ {
uint8_t *buf; uint8_t *buf;
size_t dname_len;
getdns_dict *option; getdns_dict *option;
uint32_t option_code; uint32_t option_code;
getdns_bindata *option_data; getdns_bindata *option_data;
@ -128,7 +126,6 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
int r = 0; int r = 0;
net_req->request_type = request_type; net_req->request_type = request_type;
net_req->request_class = request_class;
net_req->unbound_id = -1; net_req->unbound_id = -1;
net_req->state = NET_REQ_NOT_SENT; net_req->state = NET_REQ_NOT_SENT;
net_req->owner = owner; net_req->owner = owner;
@ -161,7 +158,12 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
net_req->debug_udp = 0; net_req->debug_udp = 0;
net_req->wire_data_sz = wire_data_sz; net_req->wire_data_sz = wire_data_sz;
if (max_query_sz) { if (max_query_sz == 0) {
net_req->query = NULL;
net_req->opt = NULL;
net_req->response = net_req->wire_data;
return r;
}
/* first two bytes will contain query length (for tcp) */ /* first two bytes will contain query length (for tcp) */
buf = net_req->query = net_req->wire_data + 2; buf = net_req->query = net_req->wire_data + 2;
@ -176,16 +178,11 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
gldns_write_uint16(buf + GLDNS_ARCOUNT_OFF, with_opt ? 1 : 0); gldns_write_uint16(buf + GLDNS_ARCOUNT_OFF, with_opt ? 1 : 0);
buf += GLDNS_HEADER_SIZE; buf += GLDNS_HEADER_SIZE;
dname_len = max_query_sz - GLDNS_HEADER_SIZE; memcpy(buf, owner->name, owner->name_len);
if ((r = gldns_str2wire_dname_buf(name, buf, &dname_len))) { buf += owner->name_len;
net_req->opt = NULL;
return r;
}
buf += dname_len;
gldns_write_uint16(buf, request_type); gldns_write_uint16(buf, request_type);
gldns_write_uint16(buf + 2, request_class); gldns_write_uint16(buf + 2, owner->request_class);
buf += 4; buf += 4;
if (with_opt) { if (with_opt) {
@ -220,13 +217,10 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
} }
} else } else
net_req->opt = NULL; net_req->opt = NULL;
net_req->response = buf; net_req->response = buf;
gldns_write_uint16(net_req->wire_data, net_req->response - net_req->query); gldns_write_uint16(net_req->wire_data, net_req->response - net_req->query);
} else {
net_req->query = NULL;
net_req->opt = NULL;
net_req->response = net_req->wire_data;
}
return r; return r;
} }
@ -583,6 +577,8 @@ _getdns_dns_req_free(getdns_dns_req * req)
GETDNS_FREE(req->my_mf, req); GETDNS_FREE(req->my_mf, req);
} }
static const uint8_t no_suffixes[] = { 1, 0 };
/* create a new dns req to be submitted */ /* create a new dns req to be submitted */
getdns_dns_req * getdns_dns_req *
_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
@ -647,7 +643,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
* And align on the 8 byte boundry (hence the (x + 7) / 8 * 8) * And align on the 8 byte boundry (hence the (x + 7) / 8 * 8)
*/ */
size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz; size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz;
uint8_t *region; uint8_t *region, *suffixes;
if (extensions == dnssec_ok_checking_disabled || if (extensions == dnssec_ok_checking_disabled ||
extensions == dnssec_ok_checking_disabled_roadblock_avoidance || extensions == dnssec_ok_checking_disabled_roadblock_avoidance ||
@ -719,7 +715,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
; ;
} }
max_query_sz = ( GLDNS_HEADER_SIZE max_query_sz = ( GLDNS_HEADER_SIZE
+ strlen(name) + 1 + 4 /* dname always smaller then strlen(name) + 1 */ + 256 + 4 /* dname maximum 255 bytes (256 with mdns)*/
+ 12 + opt_options_size /* space needed for OPT (if needed) */ + 12 + opt_options_size /* space needed for OPT (if needed) */
+ MAXIMUM_UPSTREAM_OPTION_SPACE + MAXIMUM_UPSTREAM_OPTION_SPACE
+ MAXIMUM_TSIG_SPACE + MAXIMUM_TSIG_SPACE
@ -734,6 +730,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
+ max_query_sz + max_response_sz + 7 ) / 8 * 8; + max_query_sz + max_response_sz + 7 ) / 8 * 8;
dnsreq_base_sz = (( sizeof(getdns_dns_req) dnsreq_base_sz = (( sizeof(getdns_dns_req)
+ (a_aaaa_query ? 3 : 2) * sizeof(getdns_network_req*) + (a_aaaa_query ? 3 : 2) * sizeof(getdns_network_req*)
+ context->suffixes_len
) + 7) / 8 * 8; ) + 7) / 8 * 8;
if (! (region = GETDNS_XMALLOC(context->mf, uint8_t, if (! (region = GETDNS_XMALLOC(context->mf, uint8_t,
@ -751,11 +748,51 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
result->my_mf = context->mf; result->my_mf = context->mf;
suffixes = region + dnsreq_base_sz - context->suffixes_len;
assert(context->suffixes);
assert(context->suffixes_len);
memcpy(suffixes, context->suffixes, context->suffixes_len);
result->append_name = context->append_name;
if (!strlen(name) || name[strlen(name)-1] == '.' ||
result->append_name == GETDNS_APPEND_NAME_NEVER) {
/* Absolute query string, no appending */
result->suffix_len = no_suffixes[0];
result->suffix = no_suffixes + 1;
result->suffix_appended = 1;
} else {
result->suffix_len = suffixes[0];
result->suffix = suffixes + 1;
result->suffix_appended = 0;
}
result->name_len = sizeof(result->name); result->name_len = sizeof(result->name);
if (gldns_str2wire_dname_buf(name, result->name, &result->name_len)) { if (gldns_str2wire_dname_buf(name, result->name, &result->name_len)) {
GETDNS_FREE(result->my_mf, result); GETDNS_FREE(result->my_mf, result);
return NULL; return NULL;
} }
if (result->append_name == GETDNS_APPEND_NAME_ALWAYS) {
for (
; result->suffix_len > 1 && *result->suffix
; result->suffix += result->suffix_len
, result->suffix_len = *result->suffix++) {
if (result->suffix_len + result->name_len - 1 <
sizeof(result->name)) {
memcpy(result->name + result->name_len - 1,
result->suffix, result->suffix_len);
result->name_len += result->suffix_len - 1;
result->suffix_appended = 1;
break;
}
}
} else if (result->append_name ==
GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE &&
result->name[result->name[0]+1] != 0) {
/* We have multiple labels, no appending */
result->suffix_len = no_suffixes[0];
result->suffix = no_suffixes + 1;
result->suffix_appended = 1;
}
result->context = context; result->context = context;
result->loop = loop; result->loop = loop;
result->canceled = 0; result->canceled = 0;
@ -781,23 +818,23 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
/* check the specify_class extension */ /* check the specify_class extension */
(void) getdns_dict_get_int(extensions, "specify_class", &klass); (void) getdns_dict_get_int(extensions, "specify_class", &klass);
result->request_class = klass;
result->upstreams = context->upstreams; result->upstreams = context->upstreams;
if (result->upstreams) if (result->upstreams)
result->upstreams->referenced++; result->upstreams->referenced++;
network_req_init(result->netreqs[0], result, network_req_init(result->netreqs[0], result,
name, request_type, klass, request_type, dnssec_extension_set, with_opt,
dnssec_extension_set, with_opt,
edns_maximum_udp_payload_size, edns_maximum_udp_payload_size,
edns_extended_rcode, edns_version, edns_do_bit, edns_extended_rcode, edns_version, edns_do_bit,
opt_options_size, noptions, options, opt_options_size, noptions, options,
netreq_sz - sizeof(getdns_network_req), max_query_sz); netreq_sz - sizeof(getdns_network_req), max_query_sz);
if (a_aaaa_query) if (a_aaaa_query)
network_req_init(result->netreqs[1], result, name, network_req_init(result->netreqs[1], result,
( request_type == GETDNS_RRTYPE_A ( request_type == GETDNS_RRTYPE_A
? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ), klass, ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ),
dnssec_extension_set, with_opt, dnssec_extension_set, with_opt,
edns_maximum_udp_payload_size, edns_maximum_udp_payload_size,
edns_extended_rcode, edns_version, edns_do_bit, edns_extended_rcode, edns_version, edns_do_bit,

View File

@ -203,9 +203,6 @@ typedef struct getdns_network_req
/* request type */ /* request type */
uint16_t request_type; uint16_t request_type;
/* request class */
uint16_t request_class;
/* dnssec status */ /* dnssec status */
int dnssec_status; int dnssec_status;
@ -282,6 +279,13 @@ typedef struct getdns_dns_req {
uint8_t name[256]; uint8_t name[256];
size_t name_len; size_t name_len;
getdns_append_name_t append_name;
const uint8_t *suffix;
size_t suffix_len;
int suffix_appended;
uint16_t request_class;
/* canceled flag */ /* canceled flag */
int canceled; int canceled;

View File

@ -1035,7 +1035,7 @@ getdns_apply_network_result(getdns_network_req* netreq,
, netreq->request_type); , netreq->request_type);
gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
+ netreq->owner->name_len + 2 + netreq->owner->name_len + 2
, netreq->request_class); , netreq->owner->request_class);
netreq->response_len = GLDNS_HEADER_SIZE + netreq->owner->name_len + 4; netreq->response_len = GLDNS_HEADER_SIZE + netreq->owner->name_len + 4;