diff --git a/sys/include/net/gnrc/tcp/config.h b/sys/include/net/gnrc/tcp/config.h index a7aada558de8..a63ea3bb7a1a 100644 --- a/sys/include/net/gnrc/tcp/config.h +++ b/sys/include/net/gnrc/tcp/config.h @@ -185,6 +185,26 @@ extern "C" { #ifndef CONFIG_GNRC_TCP_EVENTLOOP_MSG_QUEUE_SIZE_EXP #define CONFIG_GNRC_TCP_EVENTLOOP_MSG_QUEUE_SIZE_EXP (3U) #endif + +/** + * @brief Enable experimental feature "dynamic msl". Disabled by default. + * @experimental This feature is experimental because it deviates from the TCP RFC. + * @note This features calculates the MSL based by multiplying the latest + * retransmission timeout value with + * CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_RTO_MUL. This leads to much + * faster return times on gnrc_tcp_close. + */ +#ifndef CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN +#define CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN 0 +#endif + +/** + * @brief Set RTO multiplication factor if experimental feature "dynamic msl" is enabled. + * @experimental This feature is experimental because it deviates from the TCP RFC. + */ +#ifndef CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_RTO_MUL +#define CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_RTO_MUL (4U) +#endif /** @} */ #ifdef __cplusplus diff --git a/sys/net/gnrc/transport_layer/tcp/Kconfig b/sys/net/gnrc/transport_layer/tcp/Kconfig index 15b899d7af81..923eb60dedb4 100644 --- a/sys/net/gnrc/transport_layer/tcp/Kconfig +++ b/sys/net/gnrc/transport_layer/tcp/Kconfig @@ -134,4 +134,23 @@ config GNRC_TCP_EVENTLOOP_MSG_QUEUE_SIZE_SIZE_EXP The number of elements in a message queue must be always a power of two. This value defines the exponent of 2^n. +config GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN + bool "Enable experimental feature \"dynamic MSL\"" + default n + help + Enables the experimental feature \"dynamic maximum segment lifetime\". + This feature calulates the MSL by multiplying the latest retransmission timeout + value with a factor GNRC_TCP_EXPERIMENTAL_DYN_MSL_RTO_MUL instead + of using the constant GNRC_TCP_MSL_MS. Using the shorter MSL leads to a faster + connection teardown and therfore for a faster return of gnrc_tcp_close. + +config GNRC_TCP_EXPERIMENTAL_DYN_MSL_RTO_MUL + int "Multiplication factor for experimental feature \"dynamic MSL\"" + default 4 + depends on GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN + help + Multiplication factor for the experimental feature \"dynamic maximum segment lifetime\". + This is the factor that is multiplied with the current retransmission timeout value + to determine the MSL value. + endif # KCONFIG_USEMODULE_GNRC_TCP diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c index b2f24a612dcf..6e9994e8fca3 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c @@ -112,8 +112,20 @@ static int _restart_timewait_timer(gnrc_tcp_tcb_t *tcb) { TCP_DEBUG_ENTER; _gnrc_tcp_eventloop_unsched(&tcb->event_timeout); - _gnrc_tcp_eventloop_sched(&tcb->event_timeout, 2 * CONFIG_GNRC_TCP_MSL_MS, - MSG_TYPE_TIMEWAIT, tcb); + + size_t val = CONFIG_GNRC_TCP_MSL_MS << 1; + + /* Experimental feature "dynamic msl", calculate timewait timer value + * based on the current retransmission timeout. + */ + if (IS_ACTIVE(CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN)) { + size_t dyn_msl = CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_RTO_MUL * tcb->rto; + if (dyn_msl < val) { + val = dyn_msl; + } + } + _gnrc_tcp_eventloop_sched(&tcb->event_timeout, val, + MSG_TYPE_TIMEWAIT, tcb); TCP_DEBUG_LEAVE; return 0; } diff --git a/tests/gnrc_tcp/Makefile b/tests/gnrc_tcp/Makefile index cd0555ad322a..d8cfb187c7e6 100644 --- a/tests/gnrc_tcp/Makefile +++ b/tests/gnrc_tcp/Makefile @@ -4,8 +4,10 @@ include ../Makefile.tests_common BOARD ?= native TAP ?= tap0 -# Shorten default TCP timeouts to speedup testing -MSL_MS ?= 1000 +# Enable experimental feature "Dynamic MSL" to speedup testing +ENABLE_DYNAMIC_MSL ?= 1 + +# Shorten default connection TCP timeout to speedup testing TIMEOUT_MS ?= 3000 # Set custom GNRC_TCP_NO_TIMEOUT constant for testing purposes @@ -29,8 +31,8 @@ USEMODULE += auto_init_gnrc_netif USEMODULE += gnrc_ipv6_default USEMODULE += gnrc_tcp USEMODULE += gnrc_pktbuf_cmd -USEMODULE += gnrc_netif_single # Only one interface used and it makes - # shell commands easier +USEMODULE += gnrc_netif_single # Only one interface used and it makes + # shell commands easier USEMODULE += shell USEMODULE += shell_commands USEMODULE += od @@ -45,17 +47,18 @@ ethos: include $(RIOTBASE)/Makefile.include -# Set CONFIG_GNRC_TCP_MSL via CFLAGS if not being set via Kconfig -ifndef CONFIG_GNRC_TCP_MSL_MS - CFLAGS += -DCONFIG_GNRC_TCP_MSL_MS=$(MSL_MS) -endif - # Set CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION via CFLAGS if not being set # via Kconfig ifndef CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS CFLAGS += -DCONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS=$(TIMEOUT_MS) endif +# Set CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN via CFLAGS if not being set +# via Kconfig +ifndef CONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN + CFLAGS += -DCONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN=$(ENABLE_DYNAMIC_MSL) +endif + # Set the shell echo configuration via CFLAGS if not being controlled via Kconfig ifndef CONFIG_KCONFIG_USEMODULE_SHELL CFLAGS += -DCONFIG_SHELL_NO_ECHO