diff --git a/doc/reference.rst b/doc/reference.rst index d7d45f056..0112f091e 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -38,6 +38,7 @@ else. [ max-conn-idle ( integer | integer(s | m | h | d); ) ] [ max-conn-handshake ( integer | integer(s | m | h | d); ) ] [ max-conn-reply ( integer | integer(s | m | h | d); ) ] + [ max-tcp-clients integer; ] [ transfers integer; ] [ rate-limit integer; ] [ rate-limit-size integer; ] @@ -230,6 +231,13 @@ max-conn-reply Maximum time to wait for a reply to an issued SOA query. +.. _max-tcp-clients: + +max-tcp-clients +^^^^^^^^^^^^^^^ + +Maximum number of TCP clients connected in parallel, set this below file descriptor limit to avoid resource exhaustion. + .. _transfers: transfers diff --git a/man/knot.conf.5.in b/man/knot.conf.5.in index 6dfd2fb50..7cbbbe422 100644 --- a/man/knot.conf.5.in +++ b/man/knot.conf.5.in @@ -83,6 +83,11 @@ system { # Default: 10s max-conn-reply 10s; + # Number of parallel TCP clients + # Set this below the descriptor limit to avoid resource exhaustion + # Default: 100 + max-tcp-clients 100; + # Number of parallel transfers # This number also includes pending SOA queries # Minimal value is number of CPUs diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l index f0b3cdd2e..cdc5f058d 100644 --- a/src/knot/conf/cf-lex.l +++ b/src/knot/conf/cf-lex.l @@ -127,6 +127,7 @@ serial-policy { lval.t = yytext; return SERIAL_POLICY; } 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; } +max-tcp-clients { lval.t = yytext; return MAX_TCP_CLIENTS; } rate-limit { lval.t = yytext; return RATE_LIMIT; } rate-limit-size { lval.t = yytext; return RATE_LIMIT_SIZE; } rate-limit-slip { lval.t = yytext; return RATE_LIMIT_SLIP; } diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y index f883cceec..dc7cc6d51 100644 --- a/src/knot/conf/cf-parse.y +++ b/src/knot/conf/cf-parse.y @@ -518,6 +518,7 @@ static void ident_auto(void *scanner, int tok, conf_t *conf, bool val) %token MAX_CONN_IDLE %token MAX_CONN_HS %token MAX_CONN_REPLY +%token MAX_TCP_CLIENTS %token RATE_LIMIT %token RATE_LIMIT_SIZE %token RATE_LIMIT_SLIP @@ -659,6 +660,9 @@ system: | system MAX_CONN_REPLY INTERVAL ';' { SET_INT(new_config->max_conn_reply, $3.i, "max-conn-reply"); } + | system MAX_TCP_CLIENTS NUM ';' { + SET_INT(new_config->max_tcp_clients, $3.i, "max-tcp-clients"); + } | system RATE_LIMIT NUM ';' { SET_INT(new_config->rrl, $3.i, "rate-limit"); } diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c index 238045bbc..8951a395d 100644 --- a/src/knot/conf/conf.c +++ b/src/knot/conf/conf.c @@ -211,6 +211,9 @@ static int conf_process(conf_t *conf) if (conf->max_conn_reply < 1) { conf->max_conn_reply = CONFIG_REPLY_WD; } + if (conf->max_tcp_clients < 1) { + conf->max_tcp_clients = CONFIG_MAXTCP; + } /* Default interface. */ conf_iface_t *ctl_if = conf->ctl.iface; diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h index d6b9d0b45..0928be59d 100644 --- a/src/knot/conf/conf.h +++ b/src/knot/conf/conf.h @@ -53,6 +53,7 @@ #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 */ +#define CONFIG_MAXTCP 100 /*!< Default limit on incoming TCP clients. */ #define CONFIG_RRL_SLIP 1 /*!< Default slip value. */ #define CONFIG_RRL_SIZE 393241 /*!< Htable default size. */ #define CONFIG_XFERS 10 @@ -201,6 +202,7 @@ typedef struct conf { 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. */ + int max_tcp_clients; /*!< TCP client limit. */ int rrl; /*!< Rate limit (in responses per second). */ size_t rrl_size; /*!< Rate limit htable size. */ int rrl_slip; /*!< Rate limit SLIP. */