Commit 85b4aec7 authored by Marek Vavrusa's avatar Marek Vavrusa

Added configurable timeouts for TCP/UDP.

New config options:
* max-conn-idle  - TCP inactivity limit
* max-conn-hs    - Limit to make a first query
* max-conn-reply - How long to wait for a reply to SOA q

fixes #2024 @2h
parent b2c18206
......@@ -38,6 +38,9 @@ else.
[ @code{pidfile} @code{"}@kbd{string}@code{";} ]
[ @code{workers} @kbd{integer}@code{;} ]
[ @code{user} @kbd{string}[@code{.}@kbd{string}]@code{;} ]
[ @code{max-conn-idle} ( @kbd{integer} | @kbd{integer}(@code{s} | @code{m} | @code{h} | @code{d})@code{;} ) ]
[ @code{max-conn-hs} ( @kbd{integer} | @kbd{integer}(@code{s} | @code{m} | @code{h} | @code{d})@code{;} ) ]
[ @code{max-conn-reply} ( @kbd{integer} | @kbd{integer}(@code{s} | @code{m} | @code{h} | @code{d})@code{;} ) ]
@code{@}}
@end example
......@@ -52,6 +55,9 @@ else.
* pidfile::
* workers::
* user::
* max-conn-idle::
* max-conn-hs::
* max-conn-reply::
@end menu
@node identity
......@@ -150,6 +156,27 @@ system @{
@}
@end example
@node max-conn-idle
@subsubsection max-conn-idle
@vindex max-conn-idle
Maximum idle time between requests on a TCP connection.
This also limits receiving of a single query, each query must be received in this time limit.
@node max-conn-hs
@subsubsection max-conn-hs
@vindex max-conn-hs
Maximum time between newly accepted TCP connection and first query.
This is useful to disconnect inactive connections faster, than connection
that already made at least 1 meaningful query.
@node max-conn-reply
@subsubsection max-conn-reply
@vindex max-conn-reply
Maximum time to wait for a reply to an issued SOA query.
@node system Example
@subsection system Example
......
......@@ -41,6 +41,25 @@ system {
# User for running server
# May also specify user.group (e.g. knot.users)
user root;
# Maximum idle time between requests on a TCP connection
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 second, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# Default: 60s
max-conn-idle 60s;
# Maximum time between newly accepted TCP connection and first query
# This is useful to disconnect inactive connections faster
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 second, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# Default: 10s
max-conn-handshake 10s;
# Maximum time to wait for a reply to SOA query
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 second, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# Default: 10s
max-conn-reply 10s;
}
# Section 'keys' contains list of TSIG keys
......
......@@ -48,6 +48,25 @@ system {
# User for running server
# May also specify user.group (f.e. knot.users)
user root;
# Maximum idle time between requests on a TCP connection
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 second, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# Default: 60s
max-conn-idle 60s;
# Maximum time between newly accepted TCP connection and first query
# This is useful to disconnect inactive connections faster
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 second, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# Default: 10s
max-conn-handshake 10s;
# Maximum time to wait for a reply to SOA query
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 second, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# Default: 10s
max-conn-reply 10s;
}
# Section 'keys' contains list of TSIG keys
......
......@@ -92,6 +92,9 @@ workers { lval.t = yytext; return WORKERS; }
user { lval.t = yytext; return USER; }
pidfile { lval.t = yytext; return PIDFILE; }
ixfr-from-differences { lval.t = yytext; return BUILD_DIFFS; }
max-conn-idle { lval.t = yytext; return MAX_CONN_IDLE; }
max-conn-handshake { lval.t = yytext; return MAX_CONN_HS; }
max-conn-reply { lval.t = yytext; return MAX_CONN_REPLY; }
interfaces { lval.t = yytext; return INTERFACES; }
address { lval.t = yytext; return ADDRESS; }
......
......@@ -270,6 +270,9 @@ static int conf_mask(void* scanner, int nval, int prefixlen) {
%token <tok> NOTIFY_IN
%token <tok> NOTIFY_OUT
%token <tok> BUILD_DIFFS
%token <tok> MAX_CONN_IDLE
%token <tok> MAX_CONN_HS
%token <tok> MAX_CONN_REPLY
%token <tok> INTERFACES ADDRESS PORT
%token <tok> IPA
......@@ -406,6 +409,9 @@ system:
free($3.t);
}
| system MAX_CONN_IDLE INTERVAL ';' { new_config->max_conn_idle = $3.i; }
| system MAX_CONN_HS INTERVAL ';' { new_config->max_conn_hs = $3.i; }
| system MAX_CONN_REPLY INTERVAL ';' { new_config->max_conn_reply = $3.i; }
;
keys:
......
......@@ -27,6 +27,8 @@
#include "knot/conf/conf.h"
#include "knot/common.h"
/*
* Defaults.
*/
......@@ -134,6 +136,17 @@ static int conf_process(conf_t *conf)
return KNOT_ENOMEM;
}
}
/* Default TCP/UDP limits. */
if (conf->max_conn_idle < 1) {
conf->max_conn_idle = CONFIG_IDLE_WD;
}
if (conf->max_conn_hs < 1) {
conf->max_conn_hs = CONFIG_HANDSHAKE_WD;
}
if (conf->max_conn_reply < 1) {
conf->max_conn_reply = CONFIG_REPLY_WD;
}
// Postprocess zones
int ret = KNOT_EOK;
......
......@@ -45,6 +45,9 @@
#define CONFIG_NOTIFY_RETRIES 5 /*!< 5 retries (suggested in RFC1996) */
#define CONFIG_NOTIFY_TIMEOUT 60 /*!< 60s (suggested in RFC1996) */
#define CONFIG_DBSYNC_TIMEOUT (60*60) /*!< 1 hour. */
#define CONFIG_REPLY_WD 10 /*!< SOA/NOTIFY query timeout [s]. */
#define CONFIG_HANDSHAKE_WD 10 /*!< [secs] for connection to make a request.*/
#define CONFIG_IDLE_WD 60 /*!< [secs] of allowed inactivity between requests */
/*!
* \brief Configuration for the interface
......@@ -163,6 +166,9 @@ typedef struct conf_t {
int workers; /*!< Number of workers per interface. */
int uid; /*!< Specified user id. */
int gid; /*!< Specified group id. */
int max_conn_idle; /*!< TCP idle timeout. */
int max_conn_hs; /*!< TCP of inactivity before first query. */
int max_conn_reply; /*!< TCP/UDP query timeout. */
/*
* Log
......
......@@ -170,9 +170,11 @@ static int tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxlen
char r_addr[SOCKADDR_STRLEN];
sockaddr_tostr(&addr, r_addr, sizeof(r_addr));
int r_port = sockaddr_portnum(&addr);
rcu_read_lock();
log_server_warning("Couldn't receive query from '%s@%d'"
" within the time limit of %ds.\n",
r_addr, r_port, TCP_ACTIVITY_WD);
r_addr, r_port, conf()->max_conn_idle);
rcu_read_unlock();
}
return KNOT_ECONNREFUSED;
}
......@@ -324,7 +326,9 @@ static int tcp_accept(int fd)
/* Set recv() timeout. */
#ifdef SO_RCVTIMEO
struct timeval tv;
tv.tv_sec = TCP_ACTIVITY_WD;
rcu_read_lock();
tv.tv_sec = conf()->max_conn_idle;
rcu_read_unlock();
tv.tv_usec = 0;
if (setsockopt(incoming, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
log_server_warning("Couldn't set up TCP connection "
......@@ -556,6 +560,12 @@ int tcp_loop_worker(dthread_t *thread)
if (nfds < 0) {
continue;
}
/* Establish timeouts. */
rcu_read_lock();
int max_idle = conf()->max_conn_idle;
int max_hs = conf()->max_conn_hs;
rcu_read_unlock();
/* Process incoming events. */
dbg_net_verb("tcp: worker %p registered %d events\n",
......@@ -576,19 +586,19 @@ int tcp_loop_worker(dthread_t *thread)
w, client);
fdset_add(w->fdset, client, OS_EV_READ);
fdset_set_watchdog(w->fdset, client,
TCP_HANDSHAKE_WD);
max_hs);
dbg_net("tcp: watchdog for fd=%d set to %ds\n",
client, TCP_HANDSHAKE_WD);
client, max_hs);
} else {
/* Handle other events. */
int ret = tcp_handle(w, it.fd, qbuf,
TCP_BUFFER_SIZE);
if (ret == KNOT_EOK) {
fdset_set_watchdog(w->fdset, it.fd,
TCP_ACTIVITY_WD);
max_idle);
dbg_net("tcp: watchdog for fd=%d "
"set to %ds\n",
it.fd, TCP_ACTIVITY_WD);
it.fd, max_idle);
}
/*! \todo Refactor to allow erase on iterator.*/
if (ret == KNOT_ECONNREFUSED) {
......
......@@ -38,8 +38,6 @@
#include "knot/server/dthreads.h"
/* Constants */
#define TCP_HANDSHAKE_WD 10 /* [secs] for connection to make a request.*/
#define TCP_ACTIVITY_WD 60 /* [secs] of allowed inactivity between requests */
#define TCP_SWEEP_INTERVAL 2 /* [secs] granularity of connection sweeping */
/*!
......
......@@ -40,7 +40,6 @@
#include "common/prng.h"
/* Constants */
#define XFR_QUERY_WD 10 /*!< SOA/NOTIFY query timeout [s]. */
#define XFR_SWEEP_INTERVAL 2 /*! [seconds] between sweeps. */
#define XFR_BUFFER_SIZE 65535 /*! Do not change this - maximum value for UDP packet length. */
#define XFR_MSG_DLTTR 9 /*! Index of letter differentiating IXFR/AXFR in log msg. */
......@@ -1463,7 +1462,10 @@ static int xfr_process_request(xfrworker_t *w, uint8_t *buf, size_t buflen)
ret = KNOT_ENOMEM;
} else {
/* Add timeout. */
fdset_set_watchdog(w->fdset, task->session, XFR_QUERY_WD);
rcu_read_lock();
fdset_set_watchdog(w->fdset, task->session,
conf()->max_conn_reply);
rcu_read_unlock();
log_server_info("%s Query issued.\n", xfr.msgpref);
ret = KNOT_EOK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment