mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- delay-close: msec option that delays closing ports for which
the UDP reply has timed out. Keeps the port open, only accepts the correct reply. This correct reply is not used, but the port is open so that no port-denied ICMPs are generated. git-svn-id: file:///svn/unbound/trunk@3058 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
4adaadab61
commit
d8e5a83392
16 changed files with 1601 additions and 1490 deletions
|
|
@ -1156,7 +1156,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
|||
worker->daemon->env->infra_cache, worker->rndstate,
|
||||
cfg->use_caps_bits_for_id, worker->ports, worker->numports,
|
||||
cfg->unwanted_threshold, &worker_alloc_cleanup, worker,
|
||||
cfg->do_udp, worker->daemon->connect_sslctx);
|
||||
cfg->do_udp, worker->daemon->connect_sslctx, cfg->delay_close);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
- iana portlist updated.
|
||||
- iana portlist test updated so it does not touch the source
|
||||
if there are no changes.
|
||||
- delay-close: msec option that delays closing ports for which
|
||||
the UDP reply has timed out. Keeps the port open, only accepts
|
||||
the correct reply. This correct reply is not used, but the port
|
||||
is open so that no port-denied ICMPs are generated.
|
||||
|
||||
27 January 2014: Wouter
|
||||
- reuseport is attempted, then fallback to without on failure.
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@ server:
|
|||
# if very busy, 50% queries run to completion, 50% get timeout in msec
|
||||
# jostle-timeout: 200
|
||||
|
||||
# msec to wait before close of port on timeout UDP. 0 disables.
|
||||
# delay-close: 0
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
|
|
|||
|
|
@ -228,6 +228,15 @@ The qps for short queries can be about (numqueriesperthread / 2)
|
|||
/ (jostletimeout in whole seconds) qps per thread, about (1024/2)*5 = 2560
|
||||
qps by default.
|
||||
.TP
|
||||
.B delay\-close: \fI<msec>
|
||||
Extra delay for timeouted UDP ports before they are closed, in msec.
|
||||
Default is 0, and that disables it. This prevents very delayed answer
|
||||
packets from the upstream (recursive) servers from bouncing against
|
||||
closed ports and setting off all sort of close-port counters, with
|
||||
eg. 1500 msec. When timeouts happen you need extra sockets, it checks
|
||||
the ID and remote IP of packets, and unwanted packets are added to the
|
||||
unwanted packet counter.
|
||||
.TP
|
||||
.B so\-rcvbuf: \fI<number>
|
||||
If not 0, then set the SO_RCVBUF socket option to get more buffer
|
||||
space on UDP port 53 incoming queries. So that short spikes on busy
|
||||
|
|
|
|||
|
|
@ -229,7 +229,8 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb)
|
|||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
|
||||
ports, numports, cfg->unwanted_threshold,
|
||||
&libworker_alloc_cleanup, w, cfg->do_udp, w->sslctx);
|
||||
&libworker_alloc_cleanup, w, cfg->do_udp, w->sslctx,
|
||||
cfg->delay_close);
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,9 +381,11 @@ outnet_send_wait_udp(struct outside_network* outnet)
|
|||
if(!randomize_and_send_udp(outnet, pend, outnet->udp_buff,
|
||||
pend->timeout)) {
|
||||
/* callback error on pending */
|
||||
if(pend->cb) {
|
||||
fptr_ok(fptr_whitelist_pending_udp(pend->cb));
|
||||
(void)(*pend->cb)(outnet->unused_fds->cp, pend->cb_arg,
|
||||
NETEVENT_CLOSED, NULL);
|
||||
}
|
||||
pending_delete(outnet, pend);
|
||||
}
|
||||
}
|
||||
|
|
@ -460,8 +462,10 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
|||
verbose(VERB_ALGO, "outnet handle udp reply");
|
||||
/* delete from tree first in case callback creates a retry */
|
||||
(void)rbtree_delete(outnet->pending, p->node.key);
|
||||
if(p->cb) {
|
||||
fptr_ok(fptr_whitelist_pending_udp(p->cb));
|
||||
(void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_NOERROR, reply_info);
|
||||
}
|
||||
portcomm_loweruse(outnet, p->pc);
|
||||
pending_delete(NULL, p);
|
||||
outnet_send_wait_udp(outnet);
|
||||
|
|
@ -496,6 +500,17 @@ calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6,
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
pending_udp_timer_delay_cb(void* arg)
|
||||
{
|
||||
struct pending* p = (struct pending*)arg;
|
||||
struct outside_network* outnet = p->outnet;
|
||||
verbose(VERB_ALGO, "timeout udp with delay");
|
||||
portcomm_loweruse(outnet, p->pc);
|
||||
pending_delete(outnet, p);
|
||||
outnet_send_wait_udp(outnet);
|
||||
}
|
||||
|
||||
void
|
||||
pending_udp_timer_cb(void *arg)
|
||||
{
|
||||
|
|
@ -503,8 +518,16 @@ pending_udp_timer_cb(void *arg)
|
|||
struct outside_network* outnet = p->outnet;
|
||||
/* it timed out */
|
||||
verbose(VERB_ALGO, "timeout udp");
|
||||
if(p->cb) {
|
||||
fptr_ok(fptr_whitelist_pending_udp(p->cb));
|
||||
(void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_TIMEOUT, NULL);
|
||||
}
|
||||
if(outnet->delayclose) {
|
||||
p->cb = NULL;
|
||||
p->timer->callback = &pending_udp_timer_delay_cb;
|
||||
comm_timer_set(p->timer, &outnet->delay_tv);
|
||||
return;
|
||||
}
|
||||
portcomm_loweruse(outnet, p->pc);
|
||||
pending_delete(outnet, p);
|
||||
outnet_send_wait_udp(outnet);
|
||||
|
|
@ -561,7 +584,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
|||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx)
|
||||
void* sslctx, int delayclose)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
|
|
@ -583,6 +606,13 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
|||
outnet->unwanted_param = unwanted_param;
|
||||
outnet->use_caps_for_id = use_caps_for_id;
|
||||
outnet->do_udp = do_udp;
|
||||
#ifndef S_SPLINT_S
|
||||
if(delayclose) {
|
||||
outnet->delayclose = 1;
|
||||
outnet->delay_tv.tv_sec = delayclose/1000;
|
||||
outnet->delay_tv.tv_usec = (delayclose%1000)*1000;
|
||||
}
|
||||
#endif
|
||||
if(numavailports == 0) {
|
||||
log_err("no outgoing ports available");
|
||||
outside_network_delete(outnet);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@ struct outside_network {
|
|||
struct port_comm* unused_fds;
|
||||
/** if udp is done */
|
||||
int do_udp;
|
||||
/** if udp is delay-closed (delayed answers do not meet closed port)*/
|
||||
int delayclose;
|
||||
/** timeout for delayclose */
|
||||
struct timeval delay_tv;
|
||||
|
||||
/** array of outgoing IP4 interfaces */
|
||||
struct port_if* ip4_ifs;
|
||||
|
|
@ -377,6 +381,8 @@ struct serviced_query {
|
|||
* @param unwanted_param: user parameter to action.
|
||||
* @param do_udp: if udp is done.
|
||||
* @param sslctx: context to create outgoing connections with (if enabled).
|
||||
* @param delayclose: if not0, udp sockets are delayed before timeout closure.
|
||||
* msec to wait on timeouted udp sockets.
|
||||
* @return: the new structure (with no pending answers) or NULL on error.
|
||||
*/
|
||||
struct outside_network* outside_network_create(struct comm_base* base,
|
||||
|
|
@ -385,7 +391,7 @@ struct outside_network* outside_network_create(struct comm_base* base,
|
|||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx);
|
||||
void* sslctx, int delayclose);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
|
|
@ -516,6 +522,9 @@ int outnet_tcp_cb(struct comm_point* c, void* arg, int error,
|
|||
/** callback for udp timeout */
|
||||
void pending_udp_timer_cb(void *arg);
|
||||
|
||||
/** callback for udp delay for timeout */
|
||||
void pending_udp_timer_delay_cb(void *arg);
|
||||
|
||||
/** callback for outgoing TCP timer event */
|
||||
void outnet_tcptimer(void* arg);
|
||||
|
||||
|
|
|
|||
|
|
@ -900,7 +900,8 @@ outside_network_create(struct comm_base* base, size_t bufsize,
|
|||
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
|
||||
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
|
||||
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
|
||||
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx))
|
||||
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
|
||||
int ATTR_UNUSED(delayclose))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct outside_network* outnet = calloc(1,
|
||||
|
|
@ -1229,6 +1230,11 @@ void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
|
|||
log_assert(0);
|
||||
}
|
||||
|
||||
void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void outnet_tcptimer(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ config_create(void)
|
|||
cfg->prefetch_key = 0;
|
||||
cfg->infra_cache_slabs = 4;
|
||||
cfg->infra_cache_numhosts = 10000;
|
||||
cfg->delay_close = 0;
|
||||
if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int))))
|
||||
goto error_exit;
|
||||
init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
|
||||
|
|
@ -378,6 +379,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl)
|
||||
else S_POW2("infra-cache-slabs:", infra_cache_slabs)
|
||||
else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts)
|
||||
else S_NUMBER_OR_ZERO("delay-close:", delay_close)
|
||||
else S_STR("chroot:", chrootdir)
|
||||
else S_STR("username:", username)
|
||||
else S_STR("directory:", directory)
|
||||
|
|
@ -622,6 +624,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_DEC(opt, "infra-host-ttl", host_ttl)
|
||||
else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
|
||||
else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts)
|
||||
else O_UNS(opt, "delay-close", delay_close)
|
||||
else O_YNO(opt, "do-ip4", do_ip4)
|
||||
else O_YNO(opt, "do-ip6", do_ip6)
|
||||
else O_YNO(opt, "do-udp", do_udp)
|
||||
|
|
|
|||
|
|
@ -119,6 +119,8 @@ struct config_file {
|
|||
size_t infra_cache_slabs;
|
||||
/** max number of hosts in the infra cache */
|
||||
size_t infra_cache_numhosts;
|
||||
/** delay close of udp-timeouted ports, if 0 no delayclose. in msec */
|
||||
int delay_close;
|
||||
|
||||
/** the target fetch policy for the iterator */
|
||||
char* target_fetch_policy;
|
||||
|
|
|
|||
2104
util/configlexer.c
2104
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -248,6 +248,7 @@ infra-cache-numhosts{COLON} { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) }
|
|||
infra-cache-lame-size{COLON} { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) }
|
||||
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) }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -174,7 +174,8 @@ extern int yydebug;
|
|||
VAR_STUB_FIRST = 383,
|
||||
VAR_MINIMAL_RESPONSES = 384,
|
||||
VAR_RRSET_ROUNDROBIN = 385,
|
||||
VAR_MAX_UDP_SIZE = 386
|
||||
VAR_MAX_UDP_SIZE = 386,
|
||||
VAR_DELAY_CLOSE = 387
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
|
|
@ -307,6 +308,7 @@ extern int yydebug;
|
|||
#define VAR_MINIMAL_RESPONSES 384
|
||||
#define VAR_RRSET_ROUNDROBIN 385
|
||||
#define VAR_MAX_UDP_SIZE 386
|
||||
#define VAR_DELAY_CLOSE 387
|
||||
|
||||
|
||||
|
||||
|
|
@ -320,7 +322,7 @@ typedef union YYSTYPE
|
|||
|
||||
|
||||
/* Line 2049 of yacc.c */
|
||||
#line 324 "util/configparser.h"
|
||||
#line 326 "util/configparser.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%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_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
|
||||
%token VAR_MAX_UDP_SIZE
|
||||
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
|
@ -163,7 +163,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_log_queries | server_tcp_upstream | server_ssl_upstream |
|
||||
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_so_reuseport | server_delay_close
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
|
@ -669,6 +669,15 @@ 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_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_rrset_cache_size:%s)\n", $2));
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ fptr_whitelist_comm_timer(void (*fptr)(void*))
|
|||
{
|
||||
if(fptr == &pending_udp_timer_cb) return 1;
|
||||
else if(fptr == &outnet_tcptimer) return 1;
|
||||
else if(fptr == &pending_udp_timer_delay_cb) return 1;
|
||||
else if(fptr == &worker_stat_timer_cb) return 1;
|
||||
else if(fptr == &worker_probe_timer_cb) return 1;
|
||||
#ifdef UB_ON_WINDOWS
|
||||
|
|
|
|||
Loading…
Reference in a new issue