xdp-tcp: allow configuring separate SYN table

This commit is contained in:
Libor Peltan 2021-10-08 11:52:46 +02:00 committed by Daniel Salzman
parent 7cfede5c23
commit a023cc05ce
7 changed files with 44 additions and 1 deletions

View file

@ -521,6 +521,7 @@ Various options related to XDP listening, especially TCP.
listen: STR[@INT] | ADDR[@INT] ...
tcp: BOOL
tcp-max-clients: INT
tcp-max-syn-clients: INT
tcp-inbuf-max-size: SIZE
tcp-idle-close-timeout: TIME
tcp-idle-reset-timeout: TIME
@ -599,6 +600,16 @@ A maximum number of TCP clients connected in parallel.
*Default:* 1000000 (one million)
.. _xdp_tcp-max-syn-clients:
tcp-max-syn-clients
-------------------
If set to non-zero, clients in SYN state are handled separately and
this is the limit of their number in parallel.
*Default:* 0
.. _xdp_tcp-inbuf-max-size:
tcp-inbuf-max-size

View file

@ -192,6 +192,9 @@ static void init_cache(
val = conf_get(conf, C_XDP, C_TCP_MAX_CLIENTS);
conf->cache.xdp_tcp_max_clients = conf_int(&val);
val = conf_get(conf, C_XDP, C_TCP_SYN_CLIENTS);
conf->cache.xdp_tcp_syn_clients = conf_int(&val);
val = conf_get(conf, C_XDP, C_TCP_INBUF_MAX_SIZE);
conf->cache.xdp_tcp_inbuf_max_size = conf_int(&val);

View file

@ -133,6 +133,7 @@ typedef struct {
size_t srv_bg_threads;
size_t srv_tcp_max_clients;
size_t xdp_tcp_max_clients;
size_t xdp_tcp_syn_clients;
size_t xdp_tcp_inbuf_max_size;
uint32_t xdp_tcp_idle_close;
uint32_t xdp_tcp_idle_reset;

View file

@ -243,6 +243,7 @@ static const yp_item_t desc_xdp[] = {
{ C_LISTEN, YP_TADDR, YP_VADDR = { 53 }, YP_FMULTI, { check_xdp_listen } },
{ C_TCP, YP_TBOOL, YP_VNONE },
{ C_TCP_MAX_CLIENTS, YP_TINT, YP_VINT = { 0, INT32_MAX, 1000000 } },
{ C_TCP_SYN_CLIENTS, YP_TINT, YP_VINT = { 0, INT32_MAX, 0 } },
{ C_TCP_INBUF_MAX_SIZE, YP_TINT, YP_VINT = { MEGA(1), SSIZE_MAX, MEGA(100), YP_SSIZE } },
{ C_TCP_IDLE_CLOSE, YP_TINT, YP_VINT = { 1, INT32_MAX, 10, YP_STIME } },
{ C_TCP_IDLE_RESET, YP_TINT, YP_VINT = { 1, INT32_MAX, 20, YP_STIME } },

View file

@ -130,6 +130,7 @@
#define C_TCP_INBUF_MAX_SIZE "\x12""tcp-inbuf-max-size"
#define C_TCP_IO_TIMEOUT "\x0E""tcp-io-timeout"
#define C_TCP_MAX_CLIENTS "\x0F""tcp-max-clients"
#define C_TCP_SYN_CLIENTS "\x13""tcp-max-syn-clients"
#define C_TCP_RESEND "\x12""tcp-resend-timeout"
#define C_TCP_REUSEPORT "\x0D""tcp-reuseport"
#define C_TCP_RMT_IO_TIMEOUT "\x15""tcp-remote-io-timeout"

View file

@ -36,9 +36,11 @@ typedef struct xdp_handle_ctx {
uint32_t msg_recv_count;
uint32_t msg_udp_count;
knot_tcp_table_t *tcp_table;
knot_tcp_table_t *syn_table;
bool tcp;
size_t tcp_max_conns;
size_t tcp_syn_conns;
size_t tcp_max_inbufs;
size_t tcp_max_obufs;
uint32_t tcp_idle_close; // In microseconds.
@ -67,6 +69,7 @@ void xdp_handle_reconfigure(xdp_handle_ctx_t *ctx)
conf_t *pconf = conf();
ctx->tcp = pconf->cache.xdp_tcp;
ctx->tcp_max_conns = pconf->cache.xdp_tcp_max_clients / pconf->cache.srv_xdp_threads;
ctx->tcp_syn_conns = pconf->cache.xdp_tcp_syn_clients / pconf->cache.srv_xdp_threads;
ctx->tcp_max_inbufs = pconf->cache.xdp_tcp_inbuf_max_size / pconf->cache.srv_xdp_threads;
ctx->tcp_max_obufs = pconf->cache.xdp_tcp_inbuf_max_size / pconf->cache.srv_xdp_threads; // FIXME another setting for outbuf!!
ctx->tcp_idle_close = pconf->cache.xdp_tcp_idle_close * 1000000;
@ -78,6 +81,7 @@ void xdp_handle_reconfigure(xdp_handle_ctx_t *ctx)
void xdp_handle_free(xdp_handle_ctx_t *ctx)
{
knot_tcp_table_free(ctx->tcp_table);
knot_tcp_table_free(ctx->syn_table);
free(ctx);
}
@ -98,6 +102,13 @@ xdp_handle_ctx_t *xdp_handle_init(knot_xdp_socket_t *xdp_sock)
xdp_handle_free(ctx);
return NULL;
}
if (ctx->tcp_syn_conns > 0) {
ctx->syn_table = knot_tcp_table_new(ctx->tcp_syn_conns, ctx->tcp_table);
if (ctx->syn_table == NULL) {
xdp_handle_free(ctx);
return NULL;
}
}
}
return ctx;
@ -185,7 +196,7 @@ static void handle_udp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
static void handle_tcp(xdp_handle_ctx_t *ctx, knot_layer_t *layer,
knotd_qdata_params_t *params)
{
int ret = knot_tcp_recv(ctx->relays, ctx->msg_recv, ctx->msg_recv_count, ctx->tcp_table, NULL);
int ret = knot_tcp_recv(ctx->relays, ctx->msg_recv, ctx->msg_recv_count, ctx->tcp_table, ctx->syn_table);
if (ret != KNOT_EOK) {
log_notice("TCP, failed to process some packets (%s)", knot_strerror(ret));
return;
@ -278,6 +289,20 @@ void xdp_handle_sweep(xdp_handle_ctx_t *ctx)
ret = knot_tcp_send(ctx->sock, sweep_relays, XDP_BATCHLEN, XDP_BATCHLEN);
}
knot_tcp_cleanup(ctx->tcp_table, sweep_relays, XDP_BATCHLEN);
if (ret != KNOT_EOK) {
break;
}
if (ctx->syn_table == NULL) {
continue;
}
ret = knot_tcp_sweep(ctx->syn_table, ctx->tcp_idle_close, ctx->tcp_idle_reset,
UINT32_MAX, ctx->tcp_syn_conns, SIZE_MAX, SIZE_MAX,
sweep_relays, XDP_BATCHLEN, &total_close, &total_reset);
if (ret == KNOT_EOK) {
ret = knot_tcp_send(ctx->sock, sweep_relays, XDP_BATCHLEN, XDP_BATCHLEN);
}
knot_tcp_cleanup(ctx->syn_table, sweep_relays, XDP_BATCHLEN);
} while (ret == KNOT_EOK && prev_reset < total_reset);
if (total_close > 0 || total_reset > 0) {

View file

@ -991,6 +991,7 @@ static const yp_item_t desc_server[] = {
static const yp_item_t desc_xdp[] = {
{ C_TCP, YP_TBOOL, YP_VNONE },
{ C_TCP_MAX_CLIENTS, YP_TINT, YP_VNONE },
{ C_TCP_SYN_CLIENTS, YP_TINT, YP_VNONE },
{ C_TCP_INBUF_MAX_SIZE, YP_TINT, YP_VNONE },
{ C_TCP_IDLE_CLOSE, YP_TINT, YP_VNONE },
{ C_TCP_IDLE_RESET, YP_TINT, YP_VNONE },