diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2015-11-05 21:29:04 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2015-11-05 21:29:04 +0000 |
commit | 2c9246e430eb5b8a8623d625325924d48b15b50f (patch) | |
tree | 4ff1e25f5117bae2d186ad3ffe1d2a23c8b8085e /usr.sbin/unbound/util | |
parent | 4c321c9c54f5a79362b54b8a1764f473305e54c6 (diff) |
merge
Diffstat (limited to 'usr.sbin/unbound/util')
-rw-r--r-- | usr.sbin/unbound/util/config_file.c | 12 | ||||
-rw-r--r-- | usr.sbin/unbound/util/config_file.h | 4 | ||||
-rw-r--r-- | usr.sbin/unbound/util/configlexer.lex | 163 | ||||
-rw-r--r-- | usr.sbin/unbound/util/configparser.y | 407 | ||||
-rw-r--r-- | usr.sbin/unbound/util/data/msgencode.c | 381 | ||||
-rw-r--r-- | usr.sbin/unbound/util/iana_ports.inc | 128 | ||||
-rw-r--r-- | usr.sbin/unbound/util/net_help.c | 23 |
7 files changed, 887 insertions, 231 deletions
diff --git a/usr.sbin/unbound/util/config_file.c b/usr.sbin/unbound/util/config_file.c index 5d31301fa00..db328f3307b 100644 --- a/usr.sbin/unbound/util/config_file.c +++ b/usr.sbin/unbound/util/config_file.c @@ -70,6 +70,8 @@ uid_t cfg_uid = (uid_t)-1; /** from cfg username, after daemonise setup performed */ gid_t cfg_gid = (gid_t)-1; +/** for debug allow small timeout values for fast rollovers */ +int autr_permit_small_holddown = 0; /** global config during parsing */ struct config_parser_state* cfg_parser = 0; @@ -98,7 +100,7 @@ config_create(void) cfg->tcp_upstream = 0; cfg->ssl_service_key = NULL; cfg->ssl_service_pem = NULL; - cfg->ssl_port = 443; + cfg->ssl_port = 853; cfg->ssl_upstream = 0; cfg->use_syslog = 1; cfg->log_time_ascii = 0; @@ -172,7 +174,7 @@ config_create(void) cfg->harden_dnssec_stripped = 1; cfg->harden_below_nxdomain = 0; cfg->harden_referral_path = 0; - cfg->harden_algo_downgrade = 1; + cfg->harden_algo_downgrade = 0; cfg->use_caps_bits_for_id = 0; cfg->caps_whitelist = NULL; cfg->private_address = NULL; @@ -200,6 +202,7 @@ config_create(void) cfg->add_holddown = 30*24*3600; cfg->del_holddown = 30*24*3600; cfg->keep_missing = 366*24*3600; /* one year plus a little leeway */ + cfg->permit_small_holddown = 0; cfg->key_cache_size = 4 * 1024 * 1024; cfg->key_cache_slabs = 4; cfg->neg_cache_size = 1 * 1024 * 1024; @@ -444,6 +447,9 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_UNSIGNED_OR_ZERO("add-holddown:", add_holddown) else S_UNSIGNED_OR_ZERO("del-holddown:", del_holddown) else S_UNSIGNED_OR_ZERO("keep-missing:", keep_missing) + else if(strcmp(opt, "permit-small-holddown:") == 0) + { IS_YES_OR_NO; cfg->permit_small_holddown = (strcmp(val, "yes") == 0); + autr_permit_small_holddown = cfg->permit_small_holddown; } else S_MEMSIZE("key-cache-size:", key_cache_size) else S_POW2("key-cache-slabs:", key_cache_slabs) else S_MEMSIZE("neg-cache-size:", neg_cache_size) @@ -705,6 +711,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_UNS(opt, "add-holddown", add_holddown) else O_UNS(opt, "del-holddown", del_holddown) else O_UNS(opt, "keep-missing", keep_missing) + else O_YNO(opt, "permit-small-holddown", permit_small_holddown) else O_MEM(opt, "key-cache-size", key_cache_size) else O_DEC(opt, "key-cache-slabs", key_cache_slabs) else O_MEM(opt, "neg-cache-size", neg_cache_size) @@ -1243,6 +1250,7 @@ config_apply(struct config_file* config) MINIMAL_RESPONSES = config->minimal_responses; RRSET_ROUNDROBIN = config->rrset_roundrobin; log_set_time_asc(config->log_time_ascii); + autr_permit_small_holddown = config->permit_small_holddown; } void config_lookup_uid(struct config_file* cfg) diff --git a/usr.sbin/unbound/util/config_file.h b/usr.sbin/unbound/util/config_file.h index 1c3c31dcf13..99b15e06ebc 100644 --- a/usr.sbin/unbound/util/config_file.h +++ b/usr.sbin/unbound/util/config_file.h @@ -269,6 +269,8 @@ struct config_file { unsigned int del_holddown; /** autotrust keep_missing time, in seconds. 0 is forever. */ unsigned int keep_missing; + /** permit small holddown values, allowing 5011 rollover very fast */ + int permit_small_holddown; /** size of the key cache */ size_t key_cache_size; @@ -368,6 +370,8 @@ struct config_file { extern uid_t cfg_uid; /** from cfg username, after daemonise setup performed */ extern gid_t cfg_gid; +/** debug and enable small timeouts */ +extern int autr_permit_small_holddown; /** * Stub config options diff --git a/usr.sbin/unbound/util/configlexer.lex b/usr.sbin/unbound/util/configlexer.lex index 2661ffdf1ba..ba728622c15 100644 --- a/usr.sbin/unbound/util/configlexer.lex +++ b/usr.sbin/unbound/util/configlexer.lex @@ -7,10 +7,12 @@ * See LICENSE for the license. * */ - #include <ctype.h> #include <string.h> #include <strings.h> +#ifdef HAVE_GLOB_H +# include <glob.h> +#endif #include "util/config_file.h" #include "util/configparser.h" @@ -36,52 +38,131 @@ void ub_c_error(const char *message); struct inc_state { char* filename; int line; + YY_BUFFER_STATE buffer; + struct inc_state* next; }; -static struct inc_state parse_stack[MAXINCLUDES]; -static YY_BUFFER_STATE include_stack[MAXINCLUDES]; -static int config_include_stack_ptr = 0; +static struct inc_state* config_include_stack = NULL; +static int inc_depth = 0; static int inc_prev = 0; static int num_args = 0; +void init_cfg_parse(void) +{ + config_include_stack = NULL; + inc_depth = 0; + inc_prev = 0; + num_args = 0; +} + static void config_start_include(const char* filename) { FILE *input; + struct inc_state* s; + char* nm; + if(inc_depth++ > 100000) { + ub_c_error_msg("too many include files"); + return; + } if(strlen(filename) == 0) { ub_c_error_msg("empty include file name"); return; } - if(config_include_stack_ptr >= MAXINCLUDES) { - ub_c_error_msg("includes nested too deeply, skipped (>%d)", MAXINCLUDES); + s = (struct inc_state*)malloc(sizeof(*s)); + if(!s) { + ub_c_error_msg("include %s: malloc failure", filename); return; } if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot, strlen(cfg_parser->chroot)) == 0) { filename += strlen(cfg_parser->chroot); } + nm = strdup(filename); + if(!nm) { + ub_c_error_msg("include %s: strdup failure", filename); + free(s); + return; + } input = fopen(filename, "r"); if(!input) { ub_c_error_msg("cannot open include file '%s': %s", filename, strerror(errno)); + free(s); + free(nm); return; } - LEXOUT(("switch_to_include_file(%s) ", filename)); - parse_stack[config_include_stack_ptr].filename = cfg_parser->filename; - parse_stack[config_include_stack_ptr].line = cfg_parser->line; - include_stack[config_include_stack_ptr] = YY_CURRENT_BUFFER; - cfg_parser->filename = strdup(filename); + LEXOUT(("switch_to_include_file(%s)\n", filename)); + s->filename = cfg_parser->filename; + s->line = cfg_parser->line; + s->buffer = YY_CURRENT_BUFFER; + s->next = config_include_stack; + config_include_stack = s; + cfg_parser->filename = nm; cfg_parser->line = 1; yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); - ++config_include_stack_ptr; +} + +static void config_start_include_glob(const char* filename) +{ + + /* check for wildcards */ +#ifdef HAVE_GLOB + glob_t g; + size_t i; + int r, flags; + if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && + !strchr(filename, '{') && !strchr(filename, '~'))) { + flags = 0 +#ifdef GLOB_ERR + | GLOB_ERR +#endif +#ifdef GLOB_NOSORT + | GLOB_NOSORT +#endif +#ifdef GLOB_BRACE + | GLOB_BRACE +#endif +#ifdef GLOB_TILDE + | GLOB_TILDE +#endif + ; + memset(&g, 0, sizeof(g)); + if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot, + strlen(cfg_parser->chroot)) == 0) { + filename += strlen(cfg_parser->chroot); + } + r = glob(filename, flags, NULL, &g); + if(r) { + /* some error */ + globfree(&g); + if(r == GLOB_NOMATCH) + return; /* no matches for pattern */ + config_start_include(filename); /* let original deal with it */ + return; + } + /* process files found, if any */ + for(i=0; i<(size_t)g.gl_pathc; i++) { + config_start_include(g.gl_pathv[i]); + } + globfree(&g); + return; + } +#endif /* HAVE_GLOB */ + + config_start_include(filename); } static void config_end_include(void) { - --config_include_stack_ptr; + struct inc_state* s = config_include_stack; + --inc_depth; + if(!s) return; free(cfg_parser->filename); - cfg_parser->filename = parse_stack[config_include_stack_ptr].filename; - cfg_parser->line = parse_stack[config_include_stack_ptr].line; + cfg_parser->filename = s->filename; + cfg_parser->line = s->line; yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(include_stack[config_include_stack_ptr]); + yy_switch_to_buffer(s->buffer); + config_include_stack = s->next; + free(s); } #ifndef yy_set_bol /* compat definition, for flex 2.4.6 */ @@ -143,10 +224,13 @@ ssl-service-pem{COLON} { YDVAR(1, VAR_SSL_SERVICE_PEM) } ssl-port{COLON} { YDVAR(1, VAR_SSL_PORT) } do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) } interface{COLON} { YDVAR(1, VAR_INTERFACE) } +ip-address{COLON} { YDVAR(1, VAR_INTERFACE) } outgoing-interface{COLON} { YDVAR(1, VAR_OUTGOING_INTERFACE) } interface-automatic{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC) } so-rcvbuf{COLON} { YDVAR(1, VAR_SO_RCVBUF) } so-sndbuf{COLON} { YDVAR(1, VAR_SO_SNDBUF) } +so-reuseport{COLON} { YDVAR(1, VAR_SO_REUSEPORT) } +ip-transparent{COLON} { YDVAR(1, VAR_IP_TRANSPARENT) } chroot{COLON} { YDVAR(1, VAR_CHROOT) } username{COLON} { YDVAR(1, VAR_USERNAME) } directory{COLON} { YDVAR(1, VAR_DIRECTORY) } @@ -160,14 +244,17 @@ msg-cache-slabs{COLON} { YDVAR(1, VAR_MSG_CACHE_SLABS) } rrset-cache-size{COLON} { YDVAR(1, VAR_RRSET_CACHE_SIZE) } rrset-cache-slabs{COLON} { YDVAR(1, VAR_RRSET_CACHE_SLABS) } cache-max-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_TTL) } +cache-max-negative-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_NEGATIVE_TTL) } cache-min-ttl{COLON} { YDVAR(1, VAR_CACHE_MIN_TTL) } infra-host-ttl{COLON} { YDVAR(1, VAR_INFRA_HOST_TTL) } infra-lame-ttl{COLON} { YDVAR(1, VAR_INFRA_LAME_TTL) } infra-cache-slabs{COLON} { YDVAR(1, VAR_INFRA_CACHE_SLABS) } infra-cache-numhosts{COLON} { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) } infra-cache-lame-size{COLON} { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) } +infra-cache-min-rtt{COLON} { YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) } num-queries-per-thread{COLON} { YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) } jostle-timeout{COLON} { YDVAR(1, VAR_JOSTLE_TIMEOUT) } +delay-close{COLON} { YDVAR(1, VAR_DELAY_CLOSE) } target-fetch-policy{COLON} { YDVAR(1, VAR_TARGET_FETCH_POLICY) } harden-short-bufsize{COLON} { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) } harden-large-queries{COLON} { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) } @@ -175,7 +262,9 @@ harden-glue{COLON} { YDVAR(1, VAR_HARDEN_GLUE) } harden-dnssec-stripped{COLON} { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) } harden-below-nxdomain{COLON} { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) } harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } +harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) } use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) } +caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) } unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } @@ -186,9 +275,11 @@ name{COLON} { YDVAR(1, VAR_NAME) } stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) } stub-host{COLON} { YDVAR(1, VAR_STUB_HOST) } stub-prime{COLON} { YDVAR(1, VAR_STUB_PRIME) } +stub-first{COLON} { YDVAR(1, VAR_STUB_FIRST) } forward-zone{COLON} { YDVAR(0, VAR_FORWARD_ZONE) } forward-addr{COLON} { YDVAR(1, VAR_FORWARD_ADDR) } forward-host{COLON} { YDVAR(1, VAR_FORWARD_HOST) } +forward-first{COLON} { YDVAR(1, VAR_FORWARD_FIRST) } do-not-query-address{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) } do-not-query-localhost{COLON} { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) } access-control{COLON} { YDVAR(2, VAR_ACCESS_CONTROL) } @@ -219,12 +310,14 @@ val-nsec3-keysize-iterations{COLON} { add-holddown{COLON} { YDVAR(1, VAR_ADD_HOLDDOWN) } del-holddown{COLON} { YDVAR(1, VAR_DEL_HOLDDOWN) } keep-missing{COLON} { YDVAR(1, VAR_KEEP_MISSING) } +permit-small-holddown{COLON} { YDVAR(1, VAR_PERMIT_SMALL_HOLDDOWN) } use-syslog{COLON} { YDVAR(1, VAR_USE_SYSLOG) } log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) } log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) } local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) } local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) } local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) } +unblock-lan-zones{COLON} { YDVAR(1, VAR_UNBLOCK_LAN_ZONES) } statistics-interval{COLON} { YDVAR(1, VAR_STATISTICS_INTERVAL) } statistics-cumulative{COLON} { YDVAR(1, VAR_STATISTICS_CUMULATIVE) } extended-statistics{COLON} { YDVAR(1, VAR_EXTENDED_STATISTICS) } @@ -232,6 +325,7 @@ remote-control{COLON} { YDVAR(0, VAR_REMOTE_CONTROL) } control-enable{COLON} { YDVAR(1, VAR_CONTROL_ENABLE) } control-interface{COLON} { YDVAR(1, VAR_CONTROL_INTERFACE) } control-port{COLON} { YDVAR(1, VAR_CONTROL_PORT) } +control-use-cert{COLON} { YDVAR(1, VAR_CONTROL_USE_CERT) } server-key-file{COLON} { YDVAR(1, VAR_SERVER_KEY_FILE) } server-cert-file{COLON} { YDVAR(1, VAR_SERVER_CERT_FILE) } control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) } @@ -239,6 +333,36 @@ control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_FILE) } python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) } python{COLON} { YDVAR(0, VAR_PYTHON) } domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) } +minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) } +rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) } +max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) } +dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) } +dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) } +dnstap{COLON} { YDVAR(0, VAR_DNSTAP) } +dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) } +dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } +dnstap-send-identity{COLON} { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } +dnstap-send-version{COLON} { YDVAR(1, VAR_DNSTAP_SEND_VERSION) } +dnstap-identity{COLON} { YDVAR(1, VAR_DNSTAP_IDENTITY) } +dnstap-version{COLON} { YDVAR(1, VAR_DNSTAP_VERSION) } +dnstap-log-resolver-query-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) } +dnstap-log-resolver-response-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) } +dnstap-log-client-query-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) } +dnstap-log-client-response-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) } +dnstap-log-forwarder-query-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } +dnstap-log-forwarder-response-messages{COLON} { + YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } +ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) } +ratelimit-slabs{COLON} { YDVAR(1, VAR_RATELIMIT_SLABS) } +ratelimit-size{COLON} { YDVAR(1, VAR_RATELIMIT_SIZE) } +ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } +ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } +ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) } <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } /* Quoted strings. Strip leading and ending quotes */ @@ -295,7 +419,7 @@ domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) } <include>\" { LEXOUT(("IQS ")); BEGIN(include_quoted); } <include>{UNQUOTEDLETTER}* { LEXOUT(("Iunquotedstr(%s) ", yytext)); - config_start_include(yytext); + config_start_include_glob(yytext); BEGIN(inc_prev); } <include_quoted><<EOF>> { @@ -308,12 +432,13 @@ domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) } <include_quoted>\" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; - config_start_include(yytext); + config_start_include_glob(yytext); BEGIN(inc_prev); } <INITIAL,val><<EOF>> { + LEXOUT(("LEXEOF ")); yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ - if (config_include_stack_ptr == 0) { + if (!config_include_stack) { yyterminate(); } else { fclose(yyin); diff --git a/usr.sbin/unbound/util/configparser.y b/usr.sbin/unbound/util/configparser.y index 09f77c5782f..d6db3c86f7d 100644 --- a/usr.sbin/unbound/util/configparser.y +++ b/usr.sbin/unbound/util/configparser.y @@ -23,16 +23,16 @@ * 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 THE REGENTS OR CONTRIBUTORS 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. + * "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 THE COPYRIGHT + * HOLDER OR CONTRIBUTORS 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. */ %{ @@ -95,21 +95,39 @@ extern struct config_parser_state* cfg_parser; %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE +%token VAR_CONTROL_USE_CERT %token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT %token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII %token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN %token VAR_VAL_SIG_SKEW_MAX VAR_CACHE_MIN_TTL VAR_VAL_LOG_LEVEL %token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN %token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH -%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_HARDEN_BELOW_NXDOMAIN +%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN %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 +%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST +%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN +%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES +%token VAR_INFRA_CACHE_MIN_RTT +%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL +%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH +%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION +%token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION +%token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES +%token VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES +%token VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES +%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES +%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES +%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES +%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT +%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE +%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR +%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvar: serverstart contents_server | stubstart contents_stub | forwardstart contents_forward | pythonstart contents_py | - rcstart contents_rc + rcstart contents_rc | dtstart contents_dt ; /* server: declaration */ @@ -159,7 +177,16 @@ content_server: server_num_threads | server_verbosity | server_port | server_edns_buffer_size | server_prefetch | server_prefetch_key | server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag | 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 | server_max_udp_size | + server_so_reuseport | server_delay_close | server_unblock_lan_zones | + server_dns64_prefix | server_dns64_synthall | + server_infra_cache_min_rtt | server_harden_algo_downgrade | + server_ip_transparent | server_ratelimit | server_ratelimit_slabs | + server_ratelimit_size | server_ratelimit_for_domain | + server_ratelimit_below_domain | server_ratelimit_factor | + server_caps_whitelist | server_cache_max_negative_ttl | + server_permit_small_holddown ; stubstart: VAR_STUB_ZONE { @@ -175,7 +202,7 @@ stubstart: VAR_STUB_ZONE ; contents_stub: contents_stub content_stub | ; -content_stub: stub_name | stub_host | stub_addr | stub_prime +content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first ; forwardstart: VAR_FORWARD_ZONE { @@ -191,7 +218,7 @@ forwardstart: VAR_FORWARD_ZONE ; contents_forward: contents_forward content_forward | ; -content_forward: forward_name | forward_host | forward_addr +content_forward: forward_name | forward_host | forward_addr | forward_first ; server_num_threads: VAR_NUM_THREADS STRING_ARG { @@ -592,6 +619,26 @@ server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG free($2); } ; +server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG + { + OUTYY(("P(server_so_reuseport:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->so_reuseport = + (strcmp($2, "yes")==0); + free($2); + } + ; +server_ip_transparent: VAR_IP_TRANSPARENT STRING_ARG + { + OUTYY(("P(server_ip_transparent:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->ip_transparent = + (strcmp($2, "yes")==0); + free($2); + } + ; server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG { OUTYY(("P(server_edns_buffer_size:%s)\n", $2)); @@ -655,6 +702,25 @@ server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG free($2); } ; +server_delay_close: VAR_DELAY_CLOSE STRING_ARG + { + OUTYY(("P(server_delay_close:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->delay_close = atoi($2); + free($2); + } + ; +server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG + { + OUTYY(("P(server_unblock_lan_zones:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->unblock_lan_zones = + (strcmp($2, "yes")==0); + free($2); + } + ; server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG { OUTYY(("P(server_rrset_cache_size:%s)\n", $2)); @@ -723,6 +789,15 @@ server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG free($2); } ; +server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG + { + OUTYY(("P(server_infra_cache_min_rtt:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->infra_cache_min_rtt = atoi($2); + free($2); + } + ; server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG { OUTYY(("P(server_target_fetch_policy:%s)\n", $2)); @@ -790,6 +865,16 @@ server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG free($2); } ; +server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG + { + OUTYY(("P(server_harden_algo_downgrade:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->harden_algo_downgrade = + (strcmp($2, "yes")==0); + free($2); + } + ; server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG { OUTYY(("P(server_use_caps_for_id:%s)\n", $2)); @@ -800,6 +885,13 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG free($2); } ; +server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG + { + OUTYY(("P(server_caps_whitelist:%s)\n", $2)); + if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2)) + yyerror("out of memory"); + } + ; server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG { OUTYY(("P(server_private_address:%s)\n", $2)); @@ -862,9 +954,12 @@ server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG { OUTYY(("P(server_access_control:%s %s)\n", $2, $3)); if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 && + strcmp($3, "deny_non_local")!=0 && + strcmp($3, "refuse_non_local")!=0 && strcmp($3, "allow")!=0 && strcmp($3, "allow_snoop")!=0) { - yyerror("expected deny, refuse, allow or allow_snoop " + yyerror("expected deny, refuse, deny_non_local, " + "refuse_non_local, allow or allow_snoop " "in access control action"); } else { if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3)) @@ -932,6 +1027,15 @@ server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG free($2); } ; +server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG + { + OUTYY(("P(server_cache_max_negative_ttl:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->max_negative_ttl = atoi($2); + free($2); + } + ; server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG { OUTYY(("P(server_cache_min_ttl:%s)\n", $2)); @@ -1022,6 +1126,15 @@ server_keep_missing: VAR_KEEP_MISSING STRING_ARG free($2); } ; +server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG + { + OUTYY(("P(server_permit_small_holddown:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->permit_small_holddown = + (strcmp($2, "yes")==0); + free($2); + } server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG { OUTYY(("P(server_key_cache_size:%s)\n", $2)); @@ -1057,10 +1170,12 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 && strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0 - && strcmp($3, "typetransparent")!=0) + && strcmp($3, "typetransparent")!=0 && + strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " - "typetransparent or nodefault"); + "typetransparent, inform, inform_deny " + "or nodefault"); else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, $2)) @@ -1095,6 +1210,114 @@ 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); + } + ; +server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG + { + OUTYY(("P(server_max_udp_size:%s)\n", $2)); + cfg_parser->cfg->max_udp_size = atoi($2); + free($2); + } + ; +server_dns64_prefix: VAR_DNS64_PREFIX STRING_ARG + { + OUTYY(("P(dns64_prefix:%s)\n", $2)); + free(cfg_parser->cfg->dns64_prefix); + cfg_parser->cfg->dns64_prefix = $2; + } + ; +server_dns64_synthall: VAR_DNS64_SYNTHALL STRING_ARG + { + OUTYY(("P(server_dns64_synthall:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dns64_synthall = (strcmp($2, "yes")==0); + free($2); + } + ; +server_ratelimit: VAR_RATELIMIT STRING_ARG + { + OUTYY(("P(server_ratelimit:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->ratelimit = atoi($2); + free($2); + } + ; +server_ratelimit_size: VAR_RATELIMIT_SIZE STRING_ARG + { + OUTYY(("P(server_ratelimit_size:%s)\n", $2)); + if(!cfg_parse_memsize($2, &cfg_parser->cfg->ratelimit_size)) + yyerror("memory size expected"); + free($2); + } + ; +server_ratelimit_slabs: VAR_RATELIMIT_SLABS STRING_ARG + { + OUTYY(("P(server_ratelimit_slabs:%s)\n", $2)); + if(atoi($2) == 0) + yyerror("number expected"); + else { + cfg_parser->cfg->ratelimit_slabs = atoi($2); + if(!is_pow2(cfg_parser->cfg->ratelimit_slabs)) + yyerror("must be a power of 2"); + } + free($2); + } + ; +server_ratelimit_for_domain: VAR_RATELIMIT_FOR_DOMAIN STRING_ARG STRING_ARG + { + OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", $2, $3)); + if(atoi($3) == 0 && strcmp($3, "0") != 0) { + yyerror("number expected"); + } else { + if(!cfg_str2list_insert(&cfg_parser->cfg-> + ratelimit_for_domain, $2, $3)) + fatal_exit("out of memory adding " + "ratelimit-for-domain"); + } + } + ; +server_ratelimit_below_domain: VAR_RATELIMIT_BELOW_DOMAIN STRING_ARG STRING_ARG + { + OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", $2, $3)); + if(atoi($3) == 0 && strcmp($3, "0") != 0) { + yyerror("number expected"); + } else { + if(!cfg_str2list_insert(&cfg_parser->cfg-> + ratelimit_below_domain, $2, $3)) + fatal_exit("out of memory adding " + "ratelimit-below-domain"); + } + } + ; +server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG + { + OUTYY(("P(server_ratelimit_factor:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->ratelimit_factor = atoi($2); + free($2); + } + ; stub_name: VAR_NAME STRING_ARG { OUTYY(("P(name:%s)\n", $2)); @@ -1119,6 +1342,15 @@ stub_addr: VAR_STUB_ADDR STRING_ARG yyerror("out of memory"); } ; +stub_first: VAR_STUB_FIRST STRING_ARG + { + OUTYY(("P(stub-first:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0); + free($2); + } + ; stub_prime: VAR_STUB_PRIME STRING_ARG { OUTYY(("P(stub-prime:%s)\n", $2)); @@ -1153,6 +1385,15 @@ forward_addr: VAR_FORWARD_ADDR STRING_ARG yyerror("out of memory"); } ; +forward_first: VAR_FORWARD_FIRST STRING_ARG + { + OUTYY(("P(forward-first:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0); + free($2); + } + ; rcstart: VAR_REMOTE_CONTROL { OUTYY(("\nP(remote-control:)\n")); @@ -1162,7 +1403,7 @@ contents_rc: contents_rc content_rc | ; content_rc: rc_control_enable | rc_control_interface | rc_control_port | rc_server_key_file | rc_server_cert_file | rc_control_key_file | - rc_control_cert_file + rc_control_cert_file | rc_control_use_cert ; rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG { @@ -1190,6 +1431,16 @@ rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG yyerror("out of memory"); } ; +rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG + { + OUTYY(("P(control_use_cert:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->remote_control_use_cert = + (strcmp($2, "yes")==0); + free($2); + } + ; rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG { OUTYY(("P(rc_server_key_file:%s)\n", $2)); @@ -1218,6 +1469,122 @@ rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG cfg_parser->cfg->control_cert_file = $2; } ; +dtstart: VAR_DNSTAP + { + OUTYY(("\nP(dnstap:)\n")); + } + ; +contents_dt: contents_dt content_dt + | ; +content_dt: dt_dnstap_enable | dt_dnstap_socket_path | + dt_dnstap_send_identity | dt_dnstap_send_version | + dt_dnstap_identity | dt_dnstap_version | + dt_dnstap_log_resolver_query_messages | + dt_dnstap_log_resolver_response_messages | + dt_dnstap_log_client_query_messages | + dt_dnstap_log_client_response_messages | + dt_dnstap_log_forwarder_query_messages | + dt_dnstap_log_forwarder_response_messages + ; +dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG + { + OUTYY(("P(dt_dnstap_enable:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0); + } + ; +dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG + { + OUTYY(("P(dt_dnstap_socket_path:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_socket_path); + cfg_parser->cfg->dnstap_socket_path = $2; + } + ; +dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG + { + OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0); + } + ; +dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG + { + OUTYY(("P(dt_dnstap_send_version:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0); + } + ; +dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG + { + OUTYY(("P(dt_dnstap_identity:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_identity); + cfg_parser->cfg->dnstap_identity = $2; + } + ; +dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG + { + OUTYY(("P(dt_dnstap_version:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_version); + cfg_parser->cfg->dnstap_version = $2; + } + ; +dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG + { + OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_log_resolver_query_messages = + (strcmp($2, "yes")==0); + } + ; +dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG + { + OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_log_resolver_response_messages = + (strcmp($2, "yes")==0); + } + ; +dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG + { + OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_log_client_query_messages = + (strcmp($2, "yes")==0); + } + ; +dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG + { + OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_log_client_response_messages = + (strcmp($2, "yes")==0); + } + ; +dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG + { + OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_log_forwarder_query_messages = + (strcmp($2, "yes")==0); + } + ; +dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG + { + OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_log_forwarder_response_messages = + (strcmp($2, "yes")==0); + } + ; pythonstart: VAR_PYTHON { OUTYY(("\nP(python:)\n")); diff --git a/usr.sbin/unbound/util/data/msgencode.c b/usr.sbin/unbound/util/data/msgencode.c index a48a0a910b3..43464e9bbe0 100644 --- a/usr.sbin/unbound/util/data/msgencode.c +++ b/usr.sbin/unbound/util/data/msgencode.c @@ -21,16 +21,16 @@ * 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 THE REGENTS OR CONTRIBUTORS 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. + * "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 THE COPYRIGHT + * HOLDER OR CONTRIBUTORS 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. */ /** @@ -40,7 +40,6 @@ */ #include "config.h" -#include <ldns/wire2host.h> #include "util/data/msgencode.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" @@ -48,6 +47,7 @@ #include "util/log.h" #include "util/regional.h" #include "util/net_help.h" +#include "sldns/sbuffer.h" /** return code that means the function ran out of memory. negative so it does * not conflict with DNS rcodes. */ @@ -243,7 +243,7 @@ compress_tree_store(uint8_t* dname, int labs, size_t offset, /** compress a domain name */ static int -write_compressed_dname(ldns_buffer* pkt, uint8_t* dname, int labs, +write_compressed_dname(sldns_buffer* pkt, uint8_t* dname, int labs, struct compress_tree_node* p) { /* compress it */ @@ -253,37 +253,37 @@ write_compressed_dname(ldns_buffer* pkt, uint8_t* dname, int labs, if(labs == 1) { /* write root label */ - if(ldns_buffer_remaining(pkt) < 1) + if(sldns_buffer_remaining(pkt) < 1) return 0; - ldns_buffer_write_u8(pkt, 0); + sldns_buffer_write_u8(pkt, 0); return 1; } /* copy the first couple of labels */ while(labcopy--) { lablen = *dname++; - if(ldns_buffer_remaining(pkt) < (size_t)lablen+1) + if(sldns_buffer_remaining(pkt) < (size_t)lablen+1) return 0; - ldns_buffer_write_u8(pkt, lablen); - ldns_buffer_write(pkt, dname, lablen); + sldns_buffer_write_u8(pkt, lablen); + sldns_buffer_write(pkt, dname, lablen); dname += lablen; } /* insert compression ptr */ - if(ldns_buffer_remaining(pkt) < 2) + if(sldns_buffer_remaining(pkt) < 2) return 0; ptr = PTR_CREATE(p->offset); - ldns_buffer_write_u16(pkt, ptr); + sldns_buffer_write_u16(pkt, ptr); return 1; } /** compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC */ static int -compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt, +compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, struct regional* region, struct compress_tree_node** tree, size_t owner_pos, uint16_t* owner_ptr, int owner_labs) { struct compress_tree_node* p; - struct compress_tree_node** insertpt; + struct compress_tree_node** insertpt = NULL; if(!*owner_ptr) { /* compress first time dname */ if((p = compress_tree_lookup(tree, key->rk.dname, @@ -296,13 +296,13 @@ compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt, owner_labs, p)) return RETVAL_TRUNC; /* check if typeclass+4 ttl + rdatalen is available */ - if(ldns_buffer_remaining(pkt) < 4+4+2) + if(sldns_buffer_remaining(pkt) < 4+4+2) return RETVAL_TRUNC; } else { /* no compress */ - if(ldns_buffer_remaining(pkt) < key->rk.dname_len+4+4+2) + if(sldns_buffer_remaining(pkt) < key->rk.dname_len+4+4+2) return RETVAL_TRUNC; - ldns_buffer_write(pkt, key->rk.dname, + sldns_buffer_write(pkt, key->rk.dname, key->rk.dname_len); if(owner_pos <= PTR_MAX_OFFSET) *owner_ptr = htons(PTR_CREATE(owner_pos)); @@ -313,13 +313,13 @@ compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt, } else { /* always compress 2nd-further RRs in RRset */ if(owner_labs == 1) { - if(ldns_buffer_remaining(pkt) < 1+4+4+2) + if(sldns_buffer_remaining(pkt) < 1+4+4+2) return RETVAL_TRUNC; - ldns_buffer_write_u8(pkt, 0); + sldns_buffer_write_u8(pkt, 0); } else { - if(ldns_buffer_remaining(pkt) < 2+4+4+2) + if(sldns_buffer_remaining(pkt) < 2+4+4+2) return RETVAL_TRUNC; - ldns_buffer_write(pkt, owner_ptr, 2); + sldns_buffer_write(pkt, owner_ptr, 2); } } return RETVAL_OK; @@ -327,12 +327,12 @@ compress_owner(struct ub_packed_rrset_key* key, ldns_buffer* pkt, /** compress any domain name to the packet, return RETVAL_* */ static int -compress_any_dname(uint8_t* dname, ldns_buffer* pkt, int labs, +compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs, struct regional* region, struct compress_tree_node** tree) { struct compress_tree_node* p; struct compress_tree_node** insertpt = NULL; - size_t pos = ldns_buffer_position(pkt); + size_t pos = sldns_buffer_position(pkt); if((p = compress_tree_lookup(tree, dname, labs, &insertpt))) { if(!write_compressed_dname(pkt, dname, labs, p)) return RETVAL_TRUNC; @@ -346,27 +346,27 @@ compress_any_dname(uint8_t* dname, ldns_buffer* pkt, int labs, } /** return true if type needs domain name compression in rdata */ -static const ldns_rr_descriptor* +static const sldns_rr_descriptor* type_rdata_compressable(struct ub_packed_rrset_key* key) { uint16_t t = ntohs(key->rk.type); - if(ldns_rr_descript(t) && - ldns_rr_descript(t)->_compress == LDNS_RR_COMPRESS) - return ldns_rr_descript(t); + if(sldns_rr_descript(t) && + sldns_rr_descript(t)->_compress == LDNS_RR_COMPRESS) + return sldns_rr_descript(t); return 0; } /** compress domain names in rdata, return RETVAL_* */ static int -compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen, +compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen, struct regional* region, struct compress_tree_node** tree, - const ldns_rr_descriptor* desc) + const sldns_rr_descriptor* desc) { int labs, r, rdf = 0; - size_t dname_len, len, pos = ldns_buffer_position(pkt); + size_t dname_len, len, pos = sldns_buffer_position(pkt); uint8_t count = desc->_dname_count; - ldns_buffer_skip(pkt, 2); /* rdata len fill in later */ + sldns_buffer_skip(pkt, 2); /* rdata len fill in later */ /* space for rdatalen checked for already */ rdata += 2; todolen -= 2; @@ -390,9 +390,9 @@ compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen, } if(len) { /* copy over */ - if(ldns_buffer_remaining(pkt) < len) + if(sldns_buffer_remaining(pkt) < len) return RETVAL_TRUNC; - ldns_buffer_write(pkt, rdata, len); + sldns_buffer_write(pkt, rdata, len); todolen -= len; rdata += len; } @@ -400,19 +400,19 @@ compress_rdata(ldns_buffer* pkt, uint8_t* rdata, size_t todolen, } /* copy remainder */ if(todolen > 0) { - if(ldns_buffer_remaining(pkt) < todolen) + if(sldns_buffer_remaining(pkt) < todolen) return RETVAL_TRUNC; - ldns_buffer_write(pkt, rdata, todolen); + sldns_buffer_write(pkt, rdata, todolen); } /* set rdata len */ - ldns_buffer_write_u16_at(pkt, pos, ldns_buffer_position(pkt)-pos-2); + sldns_buffer_write_u16_at(pkt, pos, sldns_buffer_position(pkt)-pos-2); return RETVAL_OK; } /** Returns true if RR type should be included */ static int -rrset_belongs_in_reply(ldns_pkt_section s, uint16_t rrtype, uint16_t qtype, +rrset_belongs_in_reply(sldns_pkt_section s, uint16_t rrtype, uint16_t qtype, int dnssec) { if(dnssec) @@ -440,12 +440,12 @@ rrset_belongs_in_reply(ldns_pkt_section s, uint16_t rrtype, uint16_t qtype, /** store rrset in buffer in wireformat, return RETVAL_* */ static int -packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt, - uint16_t* num_rrs, uint32_t timenow, struct regional* region, +packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt, + uint16_t* num_rrs, time_t timenow, struct regional* region, int do_data, int do_sig, struct compress_tree_node** tree, - ldns_pkt_section s, uint16_t qtype, int dnssec) + sldns_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; uint16_t owner_ptr = 0; struct packed_rrset_data* data = (struct packed_rrset_data*) @@ -456,31 +456,33 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt, return RETVAL_OK; owner_labs = dname_count_labels(key->rk.dname); - owner_pos = ldns_buffer_position(pkt); + owner_pos = sldns_buffer_position(pkt); if(do_data) { - const ldns_rr_descriptor* c = type_rdata_compressable(key); + const sldns_rr_descriptor* c = type_rdata_compressable(key); for(i=0; i<data->count; i++) { + /* rrset roundrobin */ + j = (i + rr_offset) % data->count; if((r=compress_owner(key, pkt, region, tree, owner_pos, &owner_ptr, owner_labs)) != RETVAL_OK) return r; - ldns_buffer_write(pkt, &key->rk.type, 2); - ldns_buffer_write(pkt, &key->rk.rrset_class, 2); - if(data->rr_ttl[i] < timenow) - ldns_buffer_write_u32(pkt, 0); - else ldns_buffer_write_u32(pkt, - data->rr_ttl[i]-timenow); + sldns_buffer_write(pkt, &key->rk.type, 2); + sldns_buffer_write(pkt, &key->rk.rrset_class, 2); + if(data->rr_ttl[j] < timenow) + sldns_buffer_write_u32(pkt, 0); + else sldns_buffer_write_u32(pkt, + data->rr_ttl[j]-timenow); if(c) { - if((r=compress_rdata(pkt, data->rr_data[i], - data->rr_len[i], region, tree, c)) + if((r=compress_rdata(pkt, data->rr_data[j], + data->rr_len[j], region, tree, c)) != RETVAL_OK) return r; } else { - if(ldns_buffer_remaining(pkt) < data->rr_len[i]) + if(sldns_buffer_remaining(pkt) < data->rr_len[j]) return RETVAL_TRUNC; - ldns_buffer_write(pkt, data->rr_data[i], - data->rr_len[i]); + sldns_buffer_write(pkt, data->rr_data[j], + data->rr_len[j]); } } } @@ -489,28 +491,28 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt, size_t total = data->count+data->rrsig_count; for(i=data->count; i<total; i++) { if(owner_ptr && owner_labs != 1) { - if(ldns_buffer_remaining(pkt) < + if(sldns_buffer_remaining(pkt) < 2+4+4+data->rr_len[i]) return RETVAL_TRUNC; - ldns_buffer_write(pkt, &owner_ptr, 2); + sldns_buffer_write(pkt, &owner_ptr, 2); } else { if((r=compress_any_dname(key->rk.dname, pkt, owner_labs, region, tree)) != RETVAL_OK) return r; - if(ldns_buffer_remaining(pkt) < + if(sldns_buffer_remaining(pkt) < 4+4+data->rr_len[i]) return RETVAL_TRUNC; } - ldns_buffer_write_u16(pkt, LDNS_RR_TYPE_RRSIG); - ldns_buffer_write(pkt, &key->rk.rrset_class, 2); + sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_RRSIG); + sldns_buffer_write(pkt, &key->rk.rrset_class, 2); if(data->rr_ttl[i] < timenow) - ldns_buffer_write_u32(pkt, 0); - else ldns_buffer_write_u32(pkt, + sldns_buffer_write_u32(pkt, 0); + else sldns_buffer_write_u32(pkt, data->rr_ttl[i]-timenow); /* rrsig rdata cannot be compressed, perform 100+ byte * memcopy. */ - ldns_buffer_write(pkt, data->rr_data[i], + sldns_buffer_write(pkt, data->rr_data[i], data->rr_len[i]); } } @@ -526,9 +528,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, ldns_buffer* pkt, /** store msg section in wireformat buffer, return RETVAL_* */ static int insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, - ldns_buffer* pkt, size_t rrsets_before, uint32_t timenow, + sldns_buffer* pkt, size_t rrsets_before, time_t timenow, struct regional* region, struct compress_tree_node** tree, - ldns_pkt_section s, uint16_t qtype, int dnssec) + sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset) { int r; size_t i, setstart; @@ -537,36 +539,36 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, if(s == LDNS_SECTION_ANSWER && qtype == LDNS_RR_TYPE_ANY) dnssec = 1; /* include all types in ANY answer */ for(i=0; i<num_rrsets; i++) { - setstart = ldns_buffer_position(pkt); + setstart = sldns_buffer_position(pkt); if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], pkt, num_rrs, timenow, region, 1, 1, tree, - s, qtype, dnssec)) + s, qtype, dnssec, rr_offset)) != RETVAL_OK) { /* Bad, but if due to size must set TC bit */ /* trim off the rrset neatly. */ - ldns_buffer_set_position(pkt, setstart); + sldns_buffer_set_position(pkt, setstart); return r; } } } else { for(i=0; i<num_rrsets; i++) { - setstart = ldns_buffer_position(pkt); + setstart = sldns_buffer_position(pkt); if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], pkt, num_rrs, timenow, region, 1, 0, tree, - s, qtype, dnssec)) + s, qtype, dnssec, rr_offset)) != RETVAL_OK) { - ldns_buffer_set_position(pkt, setstart); + sldns_buffer_set_position(pkt, setstart); return r; } } if(dnssec) for(i=0; i<num_rrsets; i++) { - setstart = ldns_buffer_position(pkt); + setstart = sldns_buffer_position(pkt); if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], pkt, num_rrs, timenow, region, 0, 1, tree, - s, qtype, dnssec)) + s, qtype, dnssec, rr_offset)) != RETVAL_OK) { - ldns_buffer_set_position(pkt, setstart); + sldns_buffer_set_position(pkt, setstart); return r; } } @@ -577,44 +579,70 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, /** store query section in wireformat buffer, return RETVAL */ static int insert_query(struct query_info* qinfo, struct compress_tree_node** tree, - ldns_buffer* buffer, struct regional* region) + sldns_buffer* buffer, struct regional* region) { - if(ldns_buffer_remaining(buffer) < + if(sldns_buffer_remaining(buffer) < qinfo->qname_len+sizeof(uint16_t)*2) return RETVAL_TRUNC; /* buffer too small */ /* the query is the first name inserted into the tree */ if(!compress_tree_store(qinfo->qname, dname_count_labels(qinfo->qname), - ldns_buffer_position(buffer), region, NULL, tree)) + sldns_buffer_position(buffer), region, NULL, tree)) return RETVAL_OUTMEM; - if(ldns_buffer_current(buffer) == qinfo->qname) - ldns_buffer_skip(buffer, (ssize_t)qinfo->qname_len); - else ldns_buffer_write(buffer, qinfo->qname, qinfo->qname_len); - ldns_buffer_write_u16(buffer, qinfo->qtype); - ldns_buffer_write_u16(buffer, qinfo->qclass); + if(sldns_buffer_current(buffer) == qinfo->qname) + sldns_buffer_skip(buffer, (ssize_t)qinfo->qname_len); + else sldns_buffer_write(buffer, qinfo->qname, qinfo->qname_len); + sldns_buffer_write_u16(buffer, qinfo->qtype); + sldns_buffer_write_u16(buffer, qinfo->qclass); 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 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, sldns_buffer* buffer, time_t timenow, struct regional* region, uint16_t udpsize, int dnssec) { uint16_t ancount=0, nscount=0, arcount=0; struct compress_tree_node* tree = 0; int r; + size_t rr_offset; - ldns_buffer_clear(buffer); - if(udpsize < ldns_buffer_limit(buffer)) - ldns_buffer_set_limit(buffer, udpsize); - if(ldns_buffer_remaining(buffer) < LDNS_HEADER_SIZE) + sldns_buffer_clear(buffer); + if(udpsize < sldns_buffer_limit(buffer)) + sldns_buffer_set_limit(buffer, udpsize); + if(sldns_buffer_remaining(buffer) < LDNS_HEADER_SIZE) return 0; - ldns_buffer_write(buffer, &id, sizeof(uint16_t)); - ldns_buffer_write_u16(buffer, flags); - ldns_buffer_write_u16(buffer, rep->qdcount); + sldns_buffer_write(buffer, &id, sizeof(uint16_t)); + sldns_buffer_write_u16(buffer, flags); + sldns_buffer_write_u16(buffer, rep->qdcount); /* set an, ns, ar counts to zero in case of small packets */ - ldns_buffer_write(buffer, "\000\000\000\000\000\000", 6); + sldns_buffer_write(buffer, "\000\000\000\000\000\000", 6); /* insert query section */ if(rep->qdcount) { @@ -622,60 +650,67 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, RETVAL_OK) { if(r == RETVAL_TRUNC) { /* create truncated message */ - ldns_buffer_write_u16_at(buffer, 4, 0); - LDNS_TC_SET(ldns_buffer_begin(buffer)); - ldns_buffer_flip(buffer); + sldns_buffer_write_u16_at(buffer, 4, 0); + LDNS_TC_SET(sldns_buffer_begin(buffer)); + sldns_buffer_flip(buffer); return 1; } return 0; } } + /* roundrobin offset. using query id for random number. With ntohs + * for different roundrobins for sequential id client senders. */ + rr_offset = RRSET_ROUNDROBIN?ntohs(id):0; /* insert answer section */ if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer, 0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype, - dnssec)) != RETVAL_OK) { + dnssec, rr_offset)) != RETVAL_OK) { if(r == RETVAL_TRUNC) { /* create truncated message */ - ldns_buffer_write_u16_at(buffer, 6, ancount); - LDNS_TC_SET(ldns_buffer_begin(buffer)); - ldns_buffer_flip(buffer); + sldns_buffer_write_u16_at(buffer, 6, ancount); + LDNS_TC_SET(sldns_buffer_begin(buffer)); + sldns_buffer_flip(buffer); return 1; } return 0; } - ldns_buffer_write_u16_at(buffer, 6, ancount); - - /* insert auth section */ - if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer, - rep->an_numrrsets, timenow, region, &tree, - LDNS_SECTION_AUTHORITY, qinfo->qtype, dnssec)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* create truncated message */ - ldns_buffer_write_u16_at(buffer, 8, nscount); - LDNS_TC_SET(ldns_buffer_begin(buffer)); - ldns_buffer_flip(buffer); - return 1; + sldns_buffer_write_u16_at(buffer, 6, ancount); + + /* if response is positive answer, auth/add sections are not required */ + if( ! (MINIMAL_RESPONSES && positive_answer(rep, qinfo->qtype)) ) { + /* insert auth section */ + if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer, + rep->an_numrrsets, timenow, region, &tree, + LDNS_SECTION_AUTHORITY, qinfo->qtype, + dnssec, rr_offset)) != RETVAL_OK) { + if(r == RETVAL_TRUNC) { + /* create truncated message */ + sldns_buffer_write_u16_at(buffer, 8, nscount); + LDNS_TC_SET(sldns_buffer_begin(buffer)); + sldns_buffer_flip(buffer); + return 1; + } + return 0; } - return 0; - } - ldns_buffer_write_u16_at(buffer, 8, nscount); + sldns_buffer_write_u16_at(buffer, 8, nscount); - /* insert add section */ - if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer, - rep->an_numrrsets + rep->ns_numrrsets, timenow, region, - &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype, - dnssec)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* no need to set TC bit, this is the additional */ - ldns_buffer_write_u16_at(buffer, 10, arcount); - ldns_buffer_flip(buffer); - return 1; + /* insert add section */ + if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer, + rep->an_numrrsets + rep->ns_numrrsets, timenow, region, + &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype, + dnssec, rr_offset)) != RETVAL_OK) { + if(r == RETVAL_TRUNC) { + /* no need to set TC bit, this is the additional */ + sldns_buffer_write_u16_at(buffer, 10, arcount); + sldns_buffer_flip(buffer); + return 1; + } + return 0; } - return 0; + sldns_buffer_write_u16_at(buffer, 10, arcount); } - ldns_buffer_write_u16_at(buffer, 10, arcount); - ldns_buffer_flip(buffer); + sldns_buffer_flip(buffer); return 1; } @@ -689,31 +724,31 @@ calc_edns_field_size(struct edns_data* edns) } void -attach_edns_record(ldns_buffer* pkt, struct edns_data* edns) +attach_edns_record(sldns_buffer* pkt, struct edns_data* edns) { size_t len; if(!edns || !edns->edns_present) return; /* inc additional count */ - ldns_buffer_write_u16_at(pkt, 10, - ldns_buffer_read_u16_at(pkt, 10) + 1); - len = ldns_buffer_limit(pkt); - ldns_buffer_clear(pkt); - ldns_buffer_set_position(pkt, len); + sldns_buffer_write_u16_at(pkt, 10, + sldns_buffer_read_u16_at(pkt, 10) + 1); + len = sldns_buffer_limit(pkt); + sldns_buffer_clear(pkt); + sldns_buffer_set_position(pkt, len); /* write EDNS record */ - ldns_buffer_write_u8(pkt, 0); /* '.' label */ - ldns_buffer_write_u16(pkt, LDNS_RR_TYPE_OPT); /* type */ - ldns_buffer_write_u16(pkt, edns->udp_size); /* class */ - ldns_buffer_write_u8(pkt, edns->ext_rcode); /* ttl */ - ldns_buffer_write_u8(pkt, edns->edns_version); - ldns_buffer_write_u16(pkt, edns->bits); - ldns_buffer_write_u16(pkt, 0); /* rdatalen */ - ldns_buffer_flip(pkt); + sldns_buffer_write_u8(pkt, 0); /* '.' label */ + sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_OPT); /* type */ + sldns_buffer_write_u16(pkt, edns->udp_size); /* class */ + sldns_buffer_write_u8(pkt, edns->ext_rcode); /* ttl */ + sldns_buffer_write_u8(pkt, edns->edns_version); + sldns_buffer_write_u16(pkt, edns->bits); + sldns_buffer_write_u16(pkt, 0); /* rdatalen */ + sldns_buffer_flip(pkt); } int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, - uint16_t id, uint16_t qflags, ldns_buffer* pkt, uint32_t timenow, + uint16_t id, uint16_t qflags, sldns_buffer* pkt, time_t timenow, int cached, struct regional* region, uint16_t udpsize, struct edns_data* edns, int dnssec, int secure) { @@ -751,54 +786,54 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, } void -qinfo_query_encode(ldns_buffer* pkt, struct query_info* qinfo) +qinfo_query_encode(sldns_buffer* pkt, struct query_info* qinfo) { uint16_t flags = 0; /* QUERY, NOERROR */ - ldns_buffer_clear(pkt); - log_assert(ldns_buffer_remaining(pkt) >= 12+255+4/*max query*/); - ldns_buffer_skip(pkt, 2); /* id done later */ - ldns_buffer_write_u16(pkt, flags); - ldns_buffer_write_u16(pkt, 1); /* query count */ - ldns_buffer_write(pkt, "\000\000\000\000\000\000", 6); /* counts */ - ldns_buffer_write(pkt, qinfo->qname, qinfo->qname_len); - ldns_buffer_write_u16(pkt, qinfo->qtype); - ldns_buffer_write_u16(pkt, qinfo->qclass); - ldns_buffer_flip(pkt); + sldns_buffer_clear(pkt); + log_assert(sldns_buffer_remaining(pkt) >= 12+255+4/*max query*/); + sldns_buffer_skip(pkt, 2); /* id done later */ + sldns_buffer_write_u16(pkt, flags); + sldns_buffer_write_u16(pkt, 1); /* query count */ + sldns_buffer_write(pkt, "\000\000\000\000\000\000", 6); /* counts */ + sldns_buffer_write(pkt, qinfo->qname, qinfo->qname_len); + sldns_buffer_write_u16(pkt, qinfo->qtype); + sldns_buffer_write_u16(pkt, qinfo->qclass); + sldns_buffer_flip(pkt); } void -error_encode(ldns_buffer* buf, int r, struct query_info* qinfo, +error_encode(sldns_buffer* buf, int r, struct query_info* qinfo, uint16_t qid, uint16_t qflags, struct edns_data* edns) { uint16_t flags; - ldns_buffer_clear(buf); - ldns_buffer_write(buf, &qid, sizeof(uint16_t)); + sldns_buffer_clear(buf); + sldns_buffer_write(buf, &qid, sizeof(uint16_t)); flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/ flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */ - ldns_buffer_write_u16(buf, flags); + sldns_buffer_write_u16(buf, flags); if(qinfo) flags = 1; else flags = 0; - ldns_buffer_write_u16(buf, flags); + sldns_buffer_write_u16(buf, flags); flags = 0; - ldns_buffer_write(buf, &flags, sizeof(uint16_t)); - ldns_buffer_write(buf, &flags, sizeof(uint16_t)); - ldns_buffer_write(buf, &flags, sizeof(uint16_t)); + sldns_buffer_write(buf, &flags, sizeof(uint16_t)); + sldns_buffer_write(buf, &flags, sizeof(uint16_t)); + sldns_buffer_write(buf, &flags, sizeof(uint16_t)); if(qinfo) { - if(ldns_buffer_current(buf) == qinfo->qname) - ldns_buffer_skip(buf, (ssize_t)qinfo->qname_len); - else ldns_buffer_write(buf, qinfo->qname, qinfo->qname_len); - ldns_buffer_write_u16(buf, qinfo->qtype); - ldns_buffer_write_u16(buf, qinfo->qclass); + if(sldns_buffer_current(buf) == qinfo->qname) + sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len); + else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len); + sldns_buffer_write_u16(buf, qinfo->qtype); + sldns_buffer_write_u16(buf, qinfo->qclass); } - ldns_buffer_flip(buf); + sldns_buffer_flip(buf); if(edns) { struct edns_data es = *edns; es.edns_version = EDNS_ADVERTISED_VERSION; es.udp_size = EDNS_ADVERTISED_SIZE; es.ext_rcode = 0; es.bits &= EDNS_DO; - if(ldns_buffer_limit(buf) + calc_edns_field_size(&es) > + if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) > edns->udp_size) return; attach_edns_record(buf, &es); diff --git a/usr.sbin/unbound/util/iana_ports.inc b/usr.sbin/unbound/util/iana_ports.inc index 86264e11544..47496fc8d2f 100644 --- a/usr.sbin/unbound/util/iana_ports.inc +++ b/usr.sbin/unbound/util/iana_ports.inc @@ -33,7 +33,6 @@ 48, 49, 50, -51, 52, 53, 54, @@ -651,6 +650,7 @@ 780, 800, 801, +802, 810, 828, 829, @@ -660,6 +660,7 @@ 833, 847, 848, +853, 860, 861, 862, @@ -692,10 +693,8 @@ 1022, 1025, 1026, +1027, 1029, -1030, -1031, -1032, 1033, 1034, 1035, @@ -894,6 +893,7 @@ 1229, 1230, 1231, +1232, 1233, 1234, 1235, @@ -937,7 +937,6 @@ 1273, 1274, 1275, -1276, 1277, 1278, 1279, @@ -1068,7 +1067,6 @@ 1404, 1405, 1406, -1407, 1408, 1409, 1410, @@ -1303,6 +1301,7 @@ 1641, 1642, 1643, +1644, 1645, 1646, 1647, @@ -2017,7 +2016,6 @@ 2367, 2368, 2370, -2371, 2372, 2381, 2382, @@ -2046,7 +2044,6 @@ 2405, 2406, 2407, -2408, 2409, 2410, 2411, @@ -2064,6 +2061,7 @@ 2423, 2424, 2425, +2426, 2427, 2428, 2429, @@ -2201,6 +2199,7 @@ 2561, 2562, 2563, +2564, 2565, 2566, 2567, @@ -2487,7 +2486,6 @@ 2852, 2853, 2854, -2855, 2856, 2857, 2858, @@ -3064,6 +3062,7 @@ 3451, 3452, 3453, +3454, 3455, 3456, 3457, @@ -3443,7 +3442,6 @@ 3838, 3839, 3840, -3841, 3842, 3843, 3844, @@ -3793,11 +3791,11 @@ 4321, 4322, 4323, -4324, 4325, 4326, 4327, 4328, +4333, 4340, 4341, 4342, @@ -3820,6 +3818,7 @@ 4359, 4361, 4362, +4366, 4368, 4369, 4370, @@ -3842,9 +3841,12 @@ 4404, 4405, 4406, +4412, +4413, 4425, 4426, 4430, +4432, 4441, 4442, 4443, @@ -3867,6 +3869,7 @@ 4486, 4488, 4500, +4534, 4535, 4536, 4537, @@ -3954,12 +3957,17 @@ 4743, 4744, 4745, +4747, 4749, 4750, 4751, 4752, +4753, 4784, 4785, +4789, +4790, +4791, 4800, 4801, 4802, @@ -3997,6 +4005,7 @@ 4899, 4900, 4914, +4936, 4937, 4940, 4941, @@ -4007,6 +4016,7 @@ 4952, 4969, 4970, +4980, 4986, 4987, 4988, @@ -4049,6 +4059,7 @@ 5050, 5051, 5052, +5053, 5055, 5056, 5057, @@ -4067,6 +4078,7 @@ 5072, 5073, 5074, +5078, 5079, 5080, 5081, @@ -4086,6 +4098,7 @@ 5111, 5112, 5116, +5120, 5133, 5136, 5137, @@ -4150,6 +4163,7 @@ 5315, 5343, 5344, +5349, 5350, 5351, 5352, @@ -4164,6 +4178,7 @@ 5361, 5362, 5363, +5364, 5397, 5398, 5399, @@ -4215,6 +4230,7 @@ 5463, 5464, 5465, +5474, 5500, 5501, 5502, @@ -4228,6 +4244,7 @@ 5556, 5567, 5568, +5569, 5573, 5580, 5581, @@ -4252,6 +4269,7 @@ 5632, 5633, 5634, +5670, 5671, 5672, 5673, @@ -4265,6 +4283,8 @@ 5681, 5682, 5683, +5684, +5687, 5688, 5689, 5713, @@ -4341,11 +4361,14 @@ 6072, 6073, 6074, +6080, +6081, 6082, 6083, 6085, 6086, 6087, +6088, 6100, 6101, 6102, @@ -4359,6 +4382,7 @@ 6110, 6111, 6112, +6118, 6122, 6123, 6124, @@ -4378,6 +4402,8 @@ 6162, 6163, 6200, +6201, +6209, 6222, 6241, 6242, @@ -4393,6 +4419,7 @@ 6306, 6315, 6316, +6317, 6320, 6321, 6322, @@ -4403,17 +4430,20 @@ 6350, 6355, 6360, +6363, 6370, 6382, 6389, 6390, 6417, +6419, 6420, 6421, 6443, 6444, 6445, 6446, +6455, 6456, 6471, 6480, @@ -4436,6 +4466,7 @@ 6508, 6509, 6510, +6511, 6514, 6515, 6543, @@ -4461,6 +4492,11 @@ 6626, 6627, 6628, +6633, +6634, +6635, +6636, +6653, 6657, 6670, 6671, @@ -4480,6 +4516,7 @@ 6769, 6770, 6771, +6784, 6785, 6786, 6787, @@ -4532,9 +4569,11 @@ 7024, 7025, 7030, +7040, 7070, 7071, 7080, +7095, 7099, 7100, 7101, @@ -4552,9 +4591,11 @@ 7170, 7171, 7174, +7181, 7200, 7201, 7227, +7235, 7262, 7272, 7273, @@ -4578,6 +4619,7 @@ 7401, 7402, 7410, +7411, 7421, 7426, 7427, @@ -4605,6 +4647,7 @@ 7560, 7566, 7570, +7574, 7588, 7624, 7627, @@ -4626,6 +4669,7 @@ 7725, 7726, 7727, +7728, 7734, 7738, 7741, @@ -4636,6 +4680,7 @@ 7778, 7779, 7781, +7784, 7786, 7787, 7789, @@ -4645,9 +4690,11 @@ 7799, 7800, 7801, +7802, 7810, 7845, 7846, +7872, 7880, 7887, 7900, @@ -4657,6 +4704,7 @@ 7913, 7932, 7933, +7962, 7967, 7979, 7980, @@ -4687,6 +4735,7 @@ 8057, 8058, 8059, +8060, 8074, 8080, 8081, @@ -4735,6 +4784,7 @@ 8301, 8320, 8321, +8322, 8351, 8376, 8377, @@ -4742,6 +4792,7 @@ 8379, 8380, 8383, +8384, 8400, 8401, 8402, @@ -4751,28 +4802,32 @@ 8442, 8443, 8444, +8445, 8450, 8472, 8473, 8474, 8500, 8501, +8503, 8554, 8555, 8567, 8600, +8609, 8610, 8611, 8612, 8613, 8614, +8675, 8686, -8699, 8732, 8733, 8763, 8764, 8765, +8766, 8770, 8786, 8787, @@ -4797,6 +4852,8 @@ 8912, 8913, 8954, +8980, +8981, 8989, 8990, 8991, @@ -4804,6 +4861,7 @@ 9000, 9001, 9002, +9006, 9007, 9009, 9020, @@ -4858,6 +4916,7 @@ 9217, 9222, 9255, +9277, 9278, 9279, 9280, @@ -4921,7 +4980,7 @@ 9801, 9802, 9875, -9876, +9878, 9888, 9889, 9898, @@ -4935,6 +4994,7 @@ 9951, 9952, 9953, +9955, 9956, 9966, 9987, @@ -4955,6 +5015,7 @@ 10007, 10008, 10009, +10023, 10050, 10051, 10080, @@ -4979,8 +5040,10 @@ 10200, 10201, 10252, +10253, 10260, 10288, +10439, 10500, 10540, 10541, @@ -4991,10 +5054,13 @@ 10805, 10810, 10860, +10880, 10990, 11000, 11001, +11095, 11106, +11108, 11111, 11112, 11161, @@ -5011,9 +5077,12 @@ 11321, 11367, 11371, +11430, 11600, 11720, +11723, 11751, +11796, 11876, 11877, 11967, @@ -5026,6 +5095,7 @@ 12006, 12007, 12008, +12009, 12012, 12013, 12109, @@ -5057,9 +5127,11 @@ 13820, 13821, 13822, +13894, 13929, 14000, 14001, +14002, 14033, 14034, 14141, @@ -5100,8 +5172,11 @@ 17007, 17185, 17219, +17220, 17221, 17222, +17224, +17225, 17234, 17235, 17500, @@ -5126,6 +5201,7 @@ 18881, 18888, 19000, +19007, 19191, 19194, 19283, @@ -5137,6 +5213,7 @@ 19539, 19540, 19541, +19788, 19999, 20000, 20001, @@ -5172,6 +5249,7 @@ 22005, 22273, 22305, +22335, 22343, 22347, 22350, @@ -5200,13 +5278,16 @@ 24242, 24249, 24321, +24322, 24386, 24465, 24554, +24577, 24676, 24677, 24678, 24680, +24850, 24922, 25000, 25001, @@ -5223,6 +5304,8 @@ 25901, 25902, 25903, +25954, +25955, 26000, 26133, 26208, @@ -5239,11 +5322,16 @@ 27782, 27999, 28000, +28119, +28200, 28240, 29167, 30001, 30002, +30003, +30004, 30260, +30832, 30999, 31029, 31416, @@ -5272,6 +5360,7 @@ 32896, 33123, 33331, +33334, 33434, 33656, 34249, @@ -5281,11 +5370,15 @@ 34963, 34964, 34980, +35001, +35004, 35355, 36001, +36411, 36865, 37475, 37654, +38002, 38201, 38202, 38203, @@ -5296,23 +5389,27 @@ 40843, 40853, 41111, +41230, 41794, 41795, 42508, 42509, 42510, +43000, 43188, 43189, 43190, +43210, +43439, 43440, 43441, 44321, 44322, -44323, 44544, 44553, 44600, 44818, +44900, 45000, 45054, 45678, @@ -5320,10 +5417,12 @@ 45966, 46999, 47000, +47100, 47557, 47624, 47806, 47808, +47809, 48000, 48001, 48002, @@ -5332,3 +5431,4 @@ 48129, 48556, 48619, +48653, diff --git a/usr.sbin/unbound/util/net_help.c b/usr.sbin/unbound/util/net_help.c index b3d104067b9..eb03cd0ae6d 100644 --- a/usr.sbin/unbound/util/net_help.c +++ b/usr.sbin/unbound/util/net_help.c @@ -631,9 +631,9 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) SSL_CTX_free(ctx); return NULL; } - if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { + if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { log_err("error for cert file: %s", pem); - log_crypto_err("error in SSL_CTX use_certificate_file"); + log_crypto_err("error in SSL_CTX use_certificate_chain_file"); SSL_CTX_free(ctx); return NULL; } @@ -649,6 +649,23 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) SSL_CTX_free(ctx); return NULL; } +#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO + if(!SSL_CTX_set_ecdh_auto(ctx,1)) { + log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); + } +#elif defined(USE_ECDSA) + if(1) { + EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); + if (!ecdh) { + log_crypto_err("could not find p256, not enabling ECDHE"); + } else { + if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) { + log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE"); + } + EC_KEY_free (ecdh); + } + } +#endif if(verifypem && verifypem[0]) { if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { @@ -688,7 +705,7 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem) return NULL; } if(key && key[0]) { - if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { + if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { log_err("error in client certificate %s", pem); log_crypto_err("error in certificate file"); SSL_CTX_free(ctx); |