mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Applied patch from Daisuke HIGASHI for rrset-roundrobin and
minimal-responses features. git-svn-id: file:///svn/unbound/trunk@2658 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
279f409636
commit
cf147df593
14 changed files with 1668 additions and 1479 deletions
|
|
@ -18,3 +18,4 @@ cz.nic - sponsoring 'summer of code' development by Zdenek and Marek.
|
||||||
Brett Carr - windows beta testing.
|
Brett Carr - windows beta testing.
|
||||||
Luca Bruno - patch for windows support in libunbound hosts and resolvconf().
|
Luca Bruno - patch for windows support in libunbound hosts and resolvconf().
|
||||||
Tom Hendrikx - contributed split-itar.sh a useful script to 5011-track ITAR.
|
Tom Hendrikx - contributed split-itar.sh a useful script to 5011-track ITAR.
|
||||||
|
Daisuke HIGASHI - patch for rrset-roundrobin and minimal-responses.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
10 April 2012: Wouter
|
||||||
|
- Applied patch from Daisuke HIGASHI for rrset-roundrobin and
|
||||||
|
minimal-responses features.
|
||||||
|
|
||||||
5 April 2012: Wouter
|
5 April 2012: Wouter
|
||||||
- fix bug #443: --with-chroot-dir not honoured by configure.
|
- fix bug #443: --with-chroot-dir not honoured by configure.
|
||||||
- fix bug #444: setusercontext was called too late (thanks Bjorn
|
- fix bug #444: setusercontext was called too late (thanks Bjorn
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,13 @@ server:
|
||||||
# if yes, perform key lookups adjacent to normal lookups.
|
# if yes, perform key lookups adjacent to normal lookups.
|
||||||
# prefetch-key: no
|
# prefetch-key: no
|
||||||
|
|
||||||
|
# if yes, Unbound rotates RRSet order in response.
|
||||||
|
# rrset-roundrobin: no
|
||||||
|
|
||||||
|
# if yes, Unbound doesn't insert authority/additional sections
|
||||||
|
# into response messages when those sections are not required.
|
||||||
|
# minimal-responses: no
|
||||||
|
|
||||||
# module configuration of the server. A string with identifiers
|
# module configuration of the server. A string with identifiers
|
||||||
# separated by spaces. "iterator" or "validator iterator"
|
# separated by spaces. "iterator" or "validator iterator"
|
||||||
# module-config: "validator iterator"
|
# module-config: "validator iterator"
|
||||||
|
|
|
||||||
|
|
@ -570,6 +570,18 @@ If yes, fetch the DNSKEYs earlier in the validation process, when a DS
|
||||||
record is encountered. This lowers the latency of requests. It does use
|
record is encountered. This lowers the latency of requests. It does use
|
||||||
a little more CPU. Also if the cache is set to 0, it is no use. Default is no.
|
a little more CPU. Also if the cache is set to 0, it is no use. Default is no.
|
||||||
.TP
|
.TP
|
||||||
|
.B rrset-roundrobin: \fI<yes or no>
|
||||||
|
If yes, Unbound rotates RRSet order in response (the random number is taken
|
||||||
|
from the query ID, for speed and thread safety). Default is no.
|
||||||
|
.TP
|
||||||
|
.B minimal-responses: \fI<yes or no>
|
||||||
|
If yes, Unbound doesn't insert authority/additional sections into response
|
||||||
|
messages when those sections are not required. This reduces response
|
||||||
|
size significantly, and may avoid TCP fallback for some responses.
|
||||||
|
This may cause a slight speedup. The default is no, because the DNS
|
||||||
|
protocol RFCs mandate these sections, and the additional content could
|
||||||
|
be of use and save roundtrips for clients.
|
||||||
|
.TP
|
||||||
.B module\-config: \fI<"module names">
|
.B module\-config: \fI<"module names">
|
||||||
Module configuration, a list of module names separated by spaces, surround
|
Module configuration, a list of module names separated by spaces, surround
|
||||||
the string with quotes (""). The modules can be validator, iterator.
|
the string with quotes (""). The modules can be validator, iterator.
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,8 @@ config_create(void)
|
||||||
cfg->remote_control_enable = 0;
|
cfg->remote_control_enable = 0;
|
||||||
cfg->control_ifs = NULL;
|
cfg->control_ifs = NULL;
|
||||||
cfg->control_port = UNBOUND_CONTROL_PORT;
|
cfg->control_port = UNBOUND_CONTROL_PORT;
|
||||||
|
cfg->minimal_responses = 0;
|
||||||
|
cfg->rrset_roundrobin = 0;
|
||||||
if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key")))
|
if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key")))
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
if(!(cfg->server_cert_file = strdup(RUN_DIR"/unbound_server.pem")))
|
if(!(cfg->server_cert_file = strdup(RUN_DIR"/unbound_server.pem")))
|
||||||
|
|
@ -399,6 +401,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
else S_MEMSIZE("key-cache-size:", key_cache_size)
|
else S_MEMSIZE("key-cache-size:", key_cache_size)
|
||||||
else S_POW2("key-cache-slabs:", key_cache_slabs)
|
else S_POW2("key-cache-slabs:", key_cache_slabs)
|
||||||
else S_MEMSIZE("neg-cache-size:", neg_cache_size)
|
else S_MEMSIZE("neg-cache-size:", neg_cache_size)
|
||||||
|
else S_YNO("minimal-responses:", minimal_responses)
|
||||||
|
else S_YNO("rrset-roundrobin:", rrset_roundrobin)
|
||||||
else S_STRLIST("local-data:", local_data)
|
else S_STRLIST("local-data:", local_data)
|
||||||
else S_YNO("control-enable:", remote_control_enable)
|
else S_YNO("control-enable:", remote_control_enable)
|
||||||
else S_STRLIST("control-interface:", control_ifs)
|
else S_STRLIST("control-interface:", control_ifs)
|
||||||
|
|
@ -651,6 +655,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||||
else O_LST(opt, "control-interface", control_ifs)
|
else O_LST(opt, "control-interface", control_ifs)
|
||||||
else O_LST(opt, "domain-insecure", domain_insecure)
|
else O_LST(opt, "domain-insecure", domain_insecure)
|
||||||
else O_UNS(opt, "val-override-date", val_date_override)
|
else O_UNS(opt, "val-override-date", val_date_override)
|
||||||
|
else O_YNO(opt, "minimal-responses", minimal_responses)
|
||||||
|
else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
|
||||||
/* not here:
|
/* not here:
|
||||||
* outgoing-permit, outgoing-avoid - have list of ports
|
* outgoing-permit, outgoing-avoid - have list of ports
|
||||||
* local-zone - zones and nodefault variables
|
* local-zone - zones and nodefault variables
|
||||||
|
|
@ -1079,6 +1085,8 @@ config_apply(struct config_file* config)
|
||||||
MAX_TTL = (uint32_t)config->max_ttl;
|
MAX_TTL = (uint32_t)config->max_ttl;
|
||||||
MIN_TTL = (uint32_t)config->min_ttl;
|
MIN_TTL = (uint32_t)config->min_ttl;
|
||||||
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
|
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
|
||||||
|
MINIMAL_RESPONSES = config->minimal_responses;
|
||||||
|
RRSET_ROUNDROBIN = config->rrset_roundrobin;
|
||||||
log_set_time_asc(config->log_time_ascii);
|
log_set_time_asc(config->log_time_ascii);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,12 @@ struct config_file {
|
||||||
|
|
||||||
/** daemonize, i.e. fork into the background. */
|
/** daemonize, i.e. fork into the background. */
|
||||||
int do_daemonize;
|
int do_daemonize;
|
||||||
|
|
||||||
|
/* minimal response when positive answer */
|
||||||
|
int minimal_responses;
|
||||||
|
|
||||||
|
/* RRSet roundrobin */
|
||||||
|
int rrset_roundrobin;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
1983
util/configlexer.c
1983
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -241,6 +241,8 @@ control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_FILE) }
|
||||||
python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) }
|
python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) }
|
||||||
python{COLON} { YDVAR(0, VAR_PYTHON) }
|
python{COLON} { YDVAR(0, VAR_PYTHON) }
|
||||||
domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) }
|
domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) }
|
||||||
|
minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) }
|
||||||
|
rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) }
|
||||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||||
|
|
||||||
/* Quoted strings. Strip leading and ending quotes */
|
/* Quoted strings. Strip leading and ending quotes */
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -161,7 +161,9 @@
|
||||||
VAR_SSL_SERVICE_PEM = 379,
|
VAR_SSL_SERVICE_PEM = 379,
|
||||||
VAR_SSL_PORT = 380,
|
VAR_SSL_PORT = 380,
|
||||||
VAR_FORWARD_FIRST = 381,
|
VAR_FORWARD_FIRST = 381,
|
||||||
VAR_STUB_FIRST = 382
|
VAR_STUB_FIRST = 382,
|
||||||
|
VAR_MINIMAL_RESPONSES = 383,
|
||||||
|
VAR_RRSET_ROUNDROBIN = 384
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
|
|
@ -290,6 +292,8 @@
|
||||||
#define VAR_SSL_PORT 380
|
#define VAR_SSL_PORT 380
|
||||||
#define VAR_FORWARD_FIRST 381
|
#define VAR_FORWARD_FIRST 381
|
||||||
#define VAR_STUB_FIRST 382
|
#define VAR_STUB_FIRST 382
|
||||||
|
#define VAR_MINIMAL_RESPONSES 383
|
||||||
|
#define VAR_RRSET_ROUNDROBIN 384
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -306,7 +310,7 @@ typedef union YYSTYPE
|
||||||
|
|
||||||
|
|
||||||
/* Line 2068 of yacc.c */
|
/* Line 2068 of yacc.c */
|
||||||
#line 310 "util/configparser.h"
|
#line 314 "util/configparser.h"
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_HARDEN_BELOW_NXDOMAIN
|
%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_HARDEN_BELOW_NXDOMAIN
|
||||||
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
|
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
|
||||||
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
|
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
|
||||||
%token VAR_STUB_FIRST
|
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
|
||||||
|
|
||||||
%%
|
%%
|
||||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||||
|
|
@ -160,7 +160,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||||
server_edns_buffer_size | server_prefetch | server_prefetch_key |
|
server_edns_buffer_size | server_prefetch | server_prefetch_key |
|
||||||
server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
|
server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
|
||||||
server_log_queries | server_tcp_upstream | server_ssl_upstream |
|
server_log_queries | server_tcp_upstream | server_ssl_upstream |
|
||||||
server_ssl_service_key | server_ssl_service_pem | server_ssl_port
|
server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
|
||||||
|
server_minimal_responses | server_rrset_roundrobin
|
||||||
;
|
;
|
||||||
stubstart: VAR_STUB_ZONE
|
stubstart: VAR_STUB_ZONE
|
||||||
{
|
{
|
||||||
|
|
@ -1096,6 +1097,26 @@ server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(server_minimal_responses:%s)\n", $2));
|
||||||
|
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||||
|
yyerror("expected yes or no.");
|
||||||
|
else cfg_parser->cfg->minimal_responses =
|
||||||
|
(strcmp($2, "yes")==0);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(server_rrset_roundrobin:%s)\n", $2));
|
||||||
|
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||||
|
yyerror("expected yes or no.");
|
||||||
|
else cfg_parser->cfg->rrset_roundrobin =
|
||||||
|
(strcmp($2, "yes")==0);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
stub_name: VAR_NAME STRING_ARG
|
stub_name: VAR_NAME STRING_ARG
|
||||||
{
|
{
|
||||||
OUTYY(("P(name:%s)\n", $2));
|
OUTYY(("P(name:%s)\n", $2));
|
||||||
|
|
|
||||||
|
|
@ -443,9 +443,9 @@ static int
|
||||||
packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
|
packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
|
||||||
uint16_t* num_rrs, uint32_t timenow, struct regional* region,
|
uint16_t* num_rrs, uint32_t timenow, struct regional* region,
|
||||||
int do_data, int do_sig, struct compress_tree_node** tree,
|
int do_data, int do_sig, struct compress_tree_node** tree,
|
||||||
ldns_pkt_section s, uint16_t qtype, int dnssec)
|
ldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
|
||||||
{
|
{
|
||||||
size_t i, owner_pos;
|
size_t i, j, owner_pos;
|
||||||
int r, owner_labs;
|
int r, owner_labs;
|
||||||
uint16_t owner_ptr = 0;
|
uint16_t owner_ptr = 0;
|
||||||
struct packed_rrset_data* data = (struct packed_rrset_data*)
|
struct packed_rrset_data* data = (struct packed_rrset_data*)
|
||||||
|
|
@ -461,26 +461,28 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt,
|
||||||
if(do_data) {
|
if(do_data) {
|
||||||
const ldns_rr_descriptor* c = type_rdata_compressable(key);
|
const ldns_rr_descriptor* c = type_rdata_compressable(key);
|
||||||
for(i=0; i<data->count; i++) {
|
for(i=0; i<data->count; i++) {
|
||||||
|
/* rrset roundrobin */
|
||||||
|
j = (i + rr_offset) % data->count;
|
||||||
if((r=compress_owner(key, pkt, region, tree,
|
if((r=compress_owner(key, pkt, region, tree,
|
||||||
owner_pos, &owner_ptr, owner_labs))
|
owner_pos, &owner_ptr, owner_labs))
|
||||||
!= RETVAL_OK)
|
!= RETVAL_OK)
|
||||||
return r;
|
return r;
|
||||||
ldns_buffer_write(pkt, &key->rk.type, 2);
|
ldns_buffer_write(pkt, &key->rk.type, 2);
|
||||||
ldns_buffer_write(pkt, &key->rk.rrset_class, 2);
|
ldns_buffer_write(pkt, &key->rk.rrset_class, 2);
|
||||||
if(data->rr_ttl[i] < timenow)
|
if(data->rr_ttl[j] < timenow)
|
||||||
ldns_buffer_write_u32(pkt, 0);
|
ldns_buffer_write_u32(pkt, 0);
|
||||||
else ldns_buffer_write_u32(pkt,
|
else ldns_buffer_write_u32(pkt,
|
||||||
data->rr_ttl[i]-timenow);
|
data->rr_ttl[j]-timenow);
|
||||||
if(c) {
|
if(c) {
|
||||||
if((r=compress_rdata(pkt, data->rr_data[i],
|
if((r=compress_rdata(pkt, data->rr_data[j],
|
||||||
data->rr_len[i], region, tree, c))
|
data->rr_len[j], region, tree, c))
|
||||||
!= RETVAL_OK)
|
!= RETVAL_OK)
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
if(ldns_buffer_remaining(pkt) < data->rr_len[i])
|
if(ldns_buffer_remaining(pkt) < data->rr_len[j])
|
||||||
return RETVAL_TRUNC;
|
return RETVAL_TRUNC;
|
||||||
ldns_buffer_write(pkt, data->rr_data[i],
|
ldns_buffer_write(pkt, data->rr_data[j],
|
||||||
data->rr_len[i]);
|
data->rr_len[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -528,7 +530,7 @@ static int
|
||||||
insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||||
ldns_buffer* pkt, size_t rrsets_before, uint32_t timenow,
|
ldns_buffer* pkt, size_t rrsets_before, uint32_t timenow,
|
||||||
struct regional* region, struct compress_tree_node** tree,
|
struct regional* region, struct compress_tree_node** tree,
|
||||||
ldns_pkt_section s, uint16_t qtype, int dnssec)
|
ldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
size_t i, setstart;
|
size_t i, setstart;
|
||||||
|
|
@ -540,7 +542,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||||
setstart = ldns_buffer_position(pkt);
|
setstart = ldns_buffer_position(pkt);
|
||||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||||
pkt, num_rrs, timenow, region, 1, 1, tree,
|
pkt, num_rrs, timenow, region, 1, 1, tree,
|
||||||
s, qtype, dnssec))
|
s, qtype, dnssec, rr_offset))
|
||||||
!= RETVAL_OK) {
|
!= RETVAL_OK) {
|
||||||
/* Bad, but if due to size must set TC bit */
|
/* Bad, but if due to size must set TC bit */
|
||||||
/* trim off the rrset neatly. */
|
/* trim off the rrset neatly. */
|
||||||
|
|
@ -553,7 +555,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||||
setstart = ldns_buffer_position(pkt);
|
setstart = ldns_buffer_position(pkt);
|
||||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||||
pkt, num_rrs, timenow, region, 1, 0, tree,
|
pkt, num_rrs, timenow, region, 1, 0, tree,
|
||||||
s, qtype, dnssec))
|
s, qtype, dnssec, rr_offset))
|
||||||
!= RETVAL_OK) {
|
!= RETVAL_OK) {
|
||||||
ldns_buffer_set_position(pkt, setstart);
|
ldns_buffer_set_position(pkt, setstart);
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -564,7 +566,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||||
setstart = ldns_buffer_position(pkt);
|
setstart = ldns_buffer_position(pkt);
|
||||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||||
pkt, num_rrs, timenow, region, 0, 1, tree,
|
pkt, num_rrs, timenow, region, 0, 1, tree,
|
||||||
s, qtype, dnssec))
|
s, qtype, dnssec, rr_offset))
|
||||||
!= RETVAL_OK) {
|
!= RETVAL_OK) {
|
||||||
ldns_buffer_set_position(pkt, setstart);
|
ldns_buffer_set_position(pkt, setstart);
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -595,6 +597,31 @@ insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
|
||||||
return RETVAL_OK;
|
return RETVAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
positive_answer(struct reply_info* rep, uint16_t qtype) {
|
||||||
|
size_t i;
|
||||||
|
if (FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i=0;i<rep->an_numrrsets; i++) {
|
||||||
|
if(ntohs(rep->rrsets[i]->rk.type) == qtype) {
|
||||||
|
/* in case it is a wildcard with DNSSEC, there will
|
||||||
|
* be NSEC/NSEC3 records in the authority section
|
||||||
|
* that we cannot remove */
|
||||||
|
for(i=rep->an_numrrsets; i<rep->an_numrrsets+
|
||||||
|
rep->ns_numrrsets; i++) {
|
||||||
|
if(ntohs(rep->rrsets[i]->rk.type) ==
|
||||||
|
LDNS_RR_TYPE_NSEC ||
|
||||||
|
ntohs(rep->rrsets[i]->rk.type) ==
|
||||||
|
LDNS_RR_TYPE_NSEC3)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||||
uint16_t id, uint16_t flags, ldns_buffer* buffer, uint32_t timenow,
|
uint16_t id, uint16_t flags, ldns_buffer* buffer, uint32_t timenow,
|
||||||
|
|
@ -603,6 +630,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||||
uint16_t ancount=0, nscount=0, arcount=0;
|
uint16_t ancount=0, nscount=0, arcount=0;
|
||||||
struct compress_tree_node* tree = 0;
|
struct compress_tree_node* tree = 0;
|
||||||
int r;
|
int r;
|
||||||
|
size_t rr_offset;
|
||||||
|
|
||||||
ldns_buffer_clear(buffer);
|
ldns_buffer_clear(buffer);
|
||||||
if(udpsize < ldns_buffer_limit(buffer))
|
if(udpsize < ldns_buffer_limit(buffer))
|
||||||
|
|
@ -630,11 +658,13 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* roundrobin offset. using query id for random number */
|
||||||
|
rr_offset = RRSET_ROUNDROBIN?id:0;
|
||||||
|
|
||||||
/* insert answer section */
|
/* insert answer section */
|
||||||
if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
|
if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
|
||||||
0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
|
0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
|
||||||
dnssec)) != RETVAL_OK) {
|
dnssec, rr_offset)) != RETVAL_OK) {
|
||||||
if(r == RETVAL_TRUNC) {
|
if(r == RETVAL_TRUNC) {
|
||||||
/* create truncated message */
|
/* create truncated message */
|
||||||
ldns_buffer_write_u16_at(buffer, 6, ancount);
|
ldns_buffer_write_u16_at(buffer, 6, ancount);
|
||||||
|
|
@ -646,35 +676,42 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||||
}
|
}
|
||||||
ldns_buffer_write_u16_at(buffer, 6, ancount);
|
ldns_buffer_write_u16_at(buffer, 6, ancount);
|
||||||
|
|
||||||
/* insert auth section */
|
/* if response is positive answer, auth/add sections are not required */
|
||||||
if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
|
if( ! (MINIMAL_RESPONSES && positive_answer(rep, qinfo->qtype)) ) {
|
||||||
rep->an_numrrsets, timenow, region, &tree,
|
/* insert auth section */
|
||||||
LDNS_SECTION_AUTHORITY, qinfo->qtype, dnssec)) != RETVAL_OK) {
|
if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
|
||||||
if(r == RETVAL_TRUNC) {
|
rep->an_numrrsets, timenow, region, &tree,
|
||||||
/* create truncated message */
|
LDNS_SECTION_AUTHORITY, qinfo->qtype,
|
||||||
ldns_buffer_write_u16_at(buffer, 8, nscount);
|
dnssec, rr_offset)) != RETVAL_OK) {
|
||||||
LDNS_TC_SET(ldns_buffer_begin(buffer));
|
if(r == RETVAL_TRUNC) {
|
||||||
ldns_buffer_flip(buffer);
|
/* create truncated message */
|
||||||
return 1;
|
ldns_buffer_write_u16_at(buffer, 8, nscount);
|
||||||
|
LDNS_TC_SET(ldns_buffer_begin(buffer));
|
||||||
|
ldns_buffer_flip(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
ldns_buffer_write_u16_at(buffer, 8, nscount);
|
||||||
}
|
|
||||||
ldns_buffer_write_u16_at(buffer, 8, nscount);
|
|
||||||
|
|
||||||
/* insert add section */
|
/* insert add section */
|
||||||
if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
|
if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
|
||||||
rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
|
rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
|
||||||
&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
|
&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
|
||||||
dnssec)) != RETVAL_OK) {
|
dnssec, rr_offset)) != RETVAL_OK) {
|
||||||
if(r == RETVAL_TRUNC) {
|
if(r == RETVAL_TRUNC) {
|
||||||
/* no need to set TC bit, this is the additional */
|
/* no need to set TC bit, this is the additional */
|
||||||
ldns_buffer_write_u16_at(buffer, 10, arcount);
|
ldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||||
ldns_buffer_flip(buffer);
|
ldns_buffer_flip(buffer);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
ldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||||
|
} else {
|
||||||
|
ldns_buffer_write_u16_at(buffer, 8, nscount);
|
||||||
|
ldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||||
}
|
}
|
||||||
ldns_buffer_write_u16_at(buffer, 10, arcount);
|
|
||||||
ldns_buffer_flip(buffer);
|
ldns_buffer_flip(buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,12 @@
|
||||||
/** default value for EDNS ADVERTISED size */
|
/** default value for EDNS ADVERTISED size */
|
||||||
uint16_t EDNS_ADVERTISED_SIZE = 4096;
|
uint16_t EDNS_ADVERTISED_SIZE = 4096;
|
||||||
|
|
||||||
|
/** minimal responses when positive answer: default is no */
|
||||||
|
int MINIMAL_RESPONSES = 0;
|
||||||
|
|
||||||
|
/** rrset order roundrobin: default is no */
|
||||||
|
int RRSET_ROUNDROBIN = 0;
|
||||||
|
|
||||||
/* returns true is string addr is an ip6 specced address */
|
/* returns true is string addr is an ip6 specced address */
|
||||||
int
|
int
|
||||||
str_is_ip6(const char* str)
|
str_is_ip6(const char* str)
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,12 @@ extern uint16_t EDNS_ADVERTISED_SIZE;
|
||||||
/** DNSKEY secure entry point, KSK flag */
|
/** DNSKEY secure entry point, KSK flag */
|
||||||
#define DNSKEY_BIT_SEP 0x0001
|
#define DNSKEY_BIT_SEP 0x0001
|
||||||
|
|
||||||
|
/** minimal responses when positive answer */
|
||||||
|
extern int MINIMAL_RESPONSES;
|
||||||
|
|
||||||
|
/** rrset order roundrobin */
|
||||||
|
extern int RRSET_ROUNDROBIN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if string is ip4 or ip6.
|
* See if string is ip4 or ip6.
|
||||||
* @param str: IP specification.
|
* @param str: IP specification.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue